library(ggplot2)
# ── Base data: three economic series, re-indexed to 0–100 ──────────────────
rescale01 <- function(x) (x - min(x)) / (max(x) - min(x)) * 100
econ <- subset(economics_long,
variable %in% c("uempmed", "pce", "psavert"))
econ$variable <- factor(econ$variable,
levels = c("uempmed", "pce", "psavert"),
labels = c("Unemployment", "Consumption", "Savings"))
# Index each series to [0, 100]
econ$value_idx <- ave(econ$value01, econ$variable,
FUN = function(x) rescale01(x))
# Base plot object (reused throughout)
p <- ggplot(econ, aes(x = date, y = value_idx, color = variable)) +
geom_line(linewidth = 0.8) +
labs(x = "Year", y = "Index (0 – 100)",
color = "Series",
caption = "Source: ggplot2::economics_long")1 Setup
In this document, we explore various themes and styles available in ggplot2 and related packages. All examples use a line chart with three series drawn from the built-in economics_long dataset (unemployment rate, personal consumption expenditure, and personal savings rate — rescaled to a common 0–100 index for comparability).
2 Built-in ggplot2 Themes
Below are examples of every built-in theme shipped with ggplot2.
2.1 Theme Gray (default)
p + theme_gray() +
labs(title = "Theme Gray")2.2 Theme Dark-on-light (BW)
p + theme_bw() +
labs(title = "Theme BW")2.3 Theme Linedraw
p + theme_linedraw() +
labs(title = "Theme Linedraw")2.4 Theme Light
p + theme_light() +
labs(title = "Theme Light")2.5 Theme Dark
p + theme_dark() +
labs(title = "Theme Dark")2.6 Theme Minimal
p + theme_minimal() +
labs(title = "Theme Minimal")2.7 Theme Classic
p + theme_classic() +
labs(title = "Theme Classic")2.8 Theme Void
p + theme_void() +
labs(title = "Theme Void")2.9 Theme Test
p + theme_test() +
labs(title = "Theme Test")3 Themes in ggthemes
Additional themes and matching color scales from the ggthemes package (v 5.2.0, released 2025-11-30).
3.1 Theme Base
Mimics base R graphics aesthetics. New to the gallery — added in ggthemes 4.x.
library(ggthemes)
p + theme_base() +
labs(title = "Theme Base")3.2 Theme Economist
p + theme_economist() +
scale_color_economist() +
labs(title = "Theme Economist")3.3 Theme Economist – White
p + theme_economist_white() +
scale_color_economist() +
labs(title = "Theme Economist – White")3.4 Theme Excel (Classic)
p + theme_excel() +
scale_color_excel() +
labs(title = "Theme Excel (Classic)")3.5 Theme Excel – New
p + theme_excel_new() +
scale_color_excel_new() +
labs(title = "Theme Excel – New")3.6 Theme LibreOffice Calc
p + theme_calc() +
scale_color_calc() +
labs(title = "Theme Calc")3.7 Theme Highcharts
p + theme_hc() +
scale_color_hc() +
labs(title = "Theme Highcharts")3.8 Theme Google Docs
p + theme_gdocs() +
scale_color_gdocs() +
labs(title = "Theme Google Docs")3.9 Theme Clean
p + theme_clean() +
scale_color_canva() +
labs(title = "Theme Clean")3.10 Theme 538
p + theme_fivethirtyeight() +
labs(title = "Theme 538")3.11 Theme igray
p + theme_igray() +
labs(title = "Theme igray")3.12 Theme Few
p + theme_few() +
scale_color_few() +
labs(title = "Theme Few")3.13 Theme Solarized
# Light
p + theme_solarized() +
scale_color_solarized() +
labs(title = "Theme Solarized – Light")# Light 2
p + theme_solarized_2() +
scale_color_solarized() +
labs(title = "Theme Solarized 2")# Dark
p + theme_solarized(light = FALSE) +
scale_color_solarized() +
labs(title = "Theme Solarized – Dark")3.14 Theme Tufte
p + theme_tufte() +
labs(title = "Theme Tufte")3.15 Theme Stata
p + theme_stata() +
scale_color_stata() +
labs(title = "Theme Stata")3.16 Theme Wall Street Journal (WSJ)
p + theme_wsj() +
labs(title = "Theme Wall Street Journal")3.17 Theme Pander
p + theme_pander() +
scale_color_pander() +
labs(title = "Theme Pander")3.18 Notable Color Scales in ggthemes
The following demos use theme_minimal() as a neutral backdrop so the color scales are the focus.
3.18.1 Colorblind-safe Palette
scale_color_colorblind() (alias: scale_colour_colourblind()) provides an 8-color palette that is safe for the most common forms of color-vision deficiency. Renamed in ggthemes 5.2.0 to the British spelling.
p + theme_minimal() +
scale_color_colorblind() +
labs(title = "Colorblind-safe Palette (ggthemes)")3.18.2 Paul Tol Qualitative Palette
scale_color_ptol() implements Paul Tol’s colorblind-safe qualitative palette, popular in scientific publishing.
p + theme_minimal() +
scale_color_ptol() +
labs(title = "Paul Tol Qualitative Palette (ggthemes)")3.18.3 Tableau Color Scales
scale_color_tableau() offers Tableau’s discrete palettes. The default is the classic “Tableau 10”.
p + theme_minimal() +
scale_color_tableau() +
labs(title = "Tableau 10 Palette (ggthemes)")4 Themes in tidyquant
library(tidyquant)
# Tidyquant – standard
p + theme_tq() +
scale_color_tq() +
labs(title = "Theme Tidyquant")# Tidyquant – dark
p + theme_tq_dark() +
scale_color_tq() +
labs(title = "Theme Tidyquant Dark")# Tidyquant – green
p + theme_tq_green() +
scale_color_tq() +
labs(title = "Theme Tidyquant Green")5 Themes in hrbrthemes
hrbrthemes (v 0.8.x, Bob Rudis) is a typography-focused package offering publication-ready themes. It ships with a bundled copy of Roboto Condensed so no font installation is required for the core themes.
library(hrbrthemes)
# Suppress font warnings if Roboto Condensed is unavailable on this system
update_geom_font_defaults()5.1 Theme ipsum
Clean, minimal, and opinionated — one of the most widely used non-ggplot2 themes in academic and data journalism contexts.
p + theme_ipsum() +
labs(title = "Theme ipsum (hrbrthemes)")5.2 Theme ipsum_rc (Roboto Condensed)
p + theme_ipsum_rc() +
labs(title = "Theme ipsum_rc (hrbrthemes)")5.3 Theme ft_rc (Financial Times – Dark)
Inspired by the Financial Times’s dark-background online charts.
p + theme_ft_rc() +
labs(title = "Theme ft_rc – FT Dark (hrbrthemes)")5.4 Theme modern_rc (Modern Dark)
p + theme_modern_rc() +
labs(title = "Theme modern_rc – Modern Dark (hrbrthemes)")6 Custom Theme
custom_theme <- theme(
plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.title = element_text(size = 12, face = "bold"),
axis.text = element_text(size = 10),
panel.background = element_rect(fill = "white"),
panel.grid.major = element_line(color = "grey80", linewidth = 0.5),
panel.grid.minor = element_line(color = "grey90", linewidth = 0.25),
legend.position = "bottom"
)
p + custom_theme +
labs(title = "Custom Theme")7 Academic Journal Style
Academic journals (e.g., Journal of Finance, Review of Financial Studies) typically require figures that are black-and-white compatible, use grayscale or high-contrast linetype differentiation, have no chart junk, and are sized for a single or double column layout. The example below builds a self-contained theme_journal that satisfies these conventions, and uses linetypes instead of color so the figure survives grayscale printing.
# ── Journal theme definition ───────────────────────────────────────────────
theme_journal <- function(base_size = 10, base_family = "serif") {
theme_classic(base_size = base_size, base_family = base_family) %+replace%
theme(
# Title & caption
plot.title = element_text(size = base_size, face = "bold",
hjust = 0, margin = margin(b = 4)),
plot.caption = element_text(size = base_size - 2, hjust = 0,
color = "grey40",
margin = margin(t = 6)),
# Axes
axis.title = element_text(size = base_size),
axis.text = element_text(size = base_size - 1, color = "black"),
axis.line = element_line(color = "black", linewidth = 0.4),
axis.ticks = element_line(color = "black", linewidth = 0.4),
# No background, no minor grid; faint major grid only
panel.grid.major = element_line(color = "grey88", linewidth = 0.3),
panel.grid.minor = element_blank(),
# Legend: compact, inside or below
legend.title = element_text(size = base_size - 1, face = "bold"),
legend.text = element_text(size = base_size - 1),
legend.key.width = unit(1.5, "cm"), # room to see the linetype
legend.position = "bottom",
legend.background = element_blank(),
# Margins
plot.margin = margin(6, 8, 6, 6)
)
}
# ── Plot: grayscale + linetype (no reliance on color) ─────────────────────
p_journal <- ggplot(econ,
aes(x = date, y = value_idx,
color = variable,
linetype = variable)) +
geom_line(linewidth = 0.6) +
scale_color_grey(start = 0, end = 0.6) + # black → mid-grey
scale_linetype_manual(values = c("solid", "dashed", "dotdash")) +
labs(
title = "U.S. Economic Indicators, 1967–2015",
subtitle = NULL,
x = "Year",
y = "Index (0 – 100)",
color = NULL,
linetype = NULL,
caption = "Note: Each series re-indexed to [0, 100]. Source: ggplot2::economics_long."
) +
theme_journal()
p_journalKey design choices that match journal submission guidelines:
- Serif font (
"serif") matches the body typeface of most economics journals. scale_color_grey()+scale_linetype_manual()— the figure is fully legible in both color and grayscale print, satisfying most journals’ figure requirements.fig.width = 5, fig.height = 3.5targets a single-column figure width (~127 mm) common in two-column journal layouts.fig.dpi = 300meets the minimum resolution for most journals (300 dpi for line art).- No fill, no background shading, no minor gridlines — eliminates chart junk per Tufte’s principles.
To export the figure as a standalone file for submission:
ggsave("fig1.png", plot = p_journal,
width = 5, height = 3.5, units = "in", device = "png")
ggsave("fig1.tiff", plot = p_journal,
width = 5, height = 3.5, units = "in",
dpi = 600, compression = "lzw") # 600 dpi TIFF for some journals