ggfun: Utilities and Extensions for ggplot2

Guangchuang Yu

2026-07-02

ggfun collects small but useful extensions for ggplot2. The package focuses on tools that make it easier to style plots, add custom geometric layers, work with legends, and inspect or modify existing plot objects.

This vignette groups the functions by the type of task they solve.

Theme Elements

Rounded rectangles

element_roundrect() works like element_rect(), but draws rounded rectangle backgrounds. It can be used in theme elements such as facet strips, legends, panel backgrounds, and plot backgrounds.

p <- ggplot(mpg, aes(displ, cty)) +
  geom_point(alpha = 0.7) +
  facet_grid(cols = vars(cyl))

p + theme(
  strip.background = element_roundrect(
    fill = "grey35",
    color = NA,
    r = 0.15
  ),
  strip.text = element_text(color = "white")
)

ggplot(mtcars, aes(mpg, disp, color = factor(cyl), size = wt)) +
  geom_point(alpha = 0.8) +
  theme(
    legend.background = element_roundrect(
      fill = "grey97",
      color = "grey55",
      linetype = 2,
      r = 0.08
    )
  )

Alternating grid bands

element_blinds() and theme_blinds() draw alternating bands on major grid lines. This is useful when categorical axes need more visual separation.

df_blinds <- data.frame(
  group = rep(LETTERS[1:6], each = 3),
  sample = rep(c("A", "B", "C"), 6),
  value = c(2, 4, 3, 5, 3, 4, 4, 6, 5, 6, 5, 7, 3, 4, 6, 5, 7, 6)
)

ggplot(df_blinds, aes(sample, group)) +
  geom_point(aes(size = value, color = value)) +
  scale_color_viridis_c() +
  theme_blinds(axis = "y", colour = c("grey95", "white")) +
  theme(panel.grid.major.x = element_blank())

Minimal plot backgrounds

Several small theme helpers remove common plot decorations.

ggplot(mtcars, aes(mpg, disp)) +
  geom_point(aes(color = factor(cyl)), size = 2) +
  theme_noxaxis()

ggplot(mtcars, aes(mpg, disp)) +
  geom_point(aes(color = factor(cyl)), size = 2) +
  theme_transparent()

Geometric Layers

Histograms based on hist()

geom_hist() uses hist() to compute break midpoints and counts. This makes it useful when the goal is to reproduce base R histogram calculations inside a ggplot2 layer.

set.seed(42)
df_hist <- data.frame(
  value = c(rnorm(120), rnorm(120, mean = 2)),
  group = rep(c("A", "B"), each = 120)
)

ggplot(df_hist, aes(value, fill = group)) +
  geom_hist(breaks = 16, position = "identity", alpha = 0.55, color = "white")

X-splines

geom_xspline() draws an X-spline through control points. Positive shape values produce smoother curves, while negative values pull the curve toward the control points.

set.seed(123)
df_line <- data.frame(
  x = rep(1:10, 2),
  y = c(cumsum(rnorm(10)), cumsum(rnorm(10, sd = 0.7)) + 2),
  series = rep(c("A", "B"), each = 10)
)

ggplot(df_line, aes(x, y, color = series, group = series)) +
  geom_point(size = 2) +
  geom_xspline(linewidth = 1, shape = 1)

Continuous-color segments

geom_segment_c() draws line segments whose colors transition from col0 to col1.

df_segments <- data.frame(
  x = c(0, 1, 2, 3),
  xend = c(1, 2, 3, 3),
  y = c(0, 1, 0.5, 0),
  yend = c(1, 0.5, 1.5, 1.5),
  start = c(0.1, 0.3, 0.5, 0.7),
  end = c(0.4, 0.6, 0.9, 1.0)
)

ggplot(df_segments) +
  geom_segment_c(
    aes(x = x, y = y, xend = xend, yend = yend, col0 = start, col1 = end),
    linewidth = 2,
    lineend = "round"
  ) +
  scale_color_viridis_c(name = "value") +
  coord_equal()

Shape-like point layers

geom_scatter_rect(), geom_triangle(), and geom_cake() are convenient when a plot needs custom glyph-like markers.

df_rect <- data.frame(
  x = rep(1:5, 2),
  y = rep(1:2, each = 5),
  value = c(1, 3, 2, 4, 5, 2, 4, 3, 5, 6)
)

ggplot(df_rect, aes(x, y)) +
  geom_scatter_rect(aes(fill = value), width = 0.85, height = 0.5, color = "white") +
  scale_y_continuous(breaks = 1:2, labels = c("control", "treated")) +
  scale_fill_viridis_c()

df_glyph <- data.frame(
  x = 1:4,
  y = c(1, 2, 1.4, 2.4),
  angle = c(0, 45, 90, 135),
  cake_size = c(0.18, 0.2, 0.16, 0.22)
)

ggplot(df_glyph, aes(x, y)) +
  geom_triangle(aes(angle = angle), fill = "tomato", size = 16, alpha = 0.8) +
  geom_cake(aes(y = y + 0.45, size = cake_size), colour.cake = "pink") +
  coord_equal(xlim = c(0.5, 4.5), ylim = c(0.5, 3.2)) +
  theme_noaxis()

Facets and Plot Data

Updating facet labels

facet_set() can relabel existing facets or add a simple facet strip to a plot.

p_facet <- ggplot(mtcars, aes(disp, drat)) +
  geom_point() +
  facet_grid(cols = vars(am), rows = vars(cyl))

p_facet + facet_set(label = c(`0` = "Automatic", `1` = "Manual", `6` = "Six cylinders"))

ggplot(mtcars, aes(mpg, disp)) +
  geom_point() +
  facet_set("Motor Trend cars")

Extracting mapped data

get_aes_var() returns the variable used by a mapping, and get_plot_data() extracts variables from the data associated with a plot or layer.

p_data <- ggplot(mtcars, aes(mpg, disp, color = factor(cyl))) +
  geom_point()

get_aes_var(p_data$mapping, "x")
#> [1] "mpg"
head(get_plot_data(p_data, var = c("x", "y")))
#>                    mpg disp
#> Mazda RX4         21.0  160
#> Mazda RX4 Wag     21.0  160
#> Datsun 710        22.8  108
#> Hornet 4 Drive    21.4  258
#> Hornet Sportabout 18.7  360
#> Valiant           18.1  225

xrange(), yrange(), and ggrange() summarize the visible data range of a plot.

xrange(p_data)
#> [1]  9.225 35.075
yrange(p_data)
#> [1]  51.055 492.045
ggrange(p_data, var = "x", region = "plot", type = "range")
#> [1] 10.4 33.9

Legends and Fonts

get_legend() extracts the legend grob from a plot.

p_legend <- ggplot(mtcars, aes(mpg, disp, color = factor(cyl))) +
  geom_point(size = 2)

legend <- get_legend(p_legend)
class(legend)
#> [1] "gtable" "gTree"  "grob"   "gDesc"

gglegend() adds a manual legend by drawing an invisible helper layer.

p_base <- ggplot(mtcars, aes(mpg, disp)) +
  geom_point()

legend_data <- data.frame(
  colour = c("firebrick", "steelblue"),
  label = c("Group A", "Group B")
)

gglegend(aes(colour = label, label = label), legend_data, geom_text, p_base)

set_font() edits text grobs after a plot has been converted to a gtable. It draws the result and returns the edited grob invisibly.

df_text <- data.frame(
  x = 1:5,
  y = c(2, 3, 2.5, 4, 3.5),
  label = LETTERS[1:5]
)

p_text <- ggplot(df_text, aes(x, y, label = label)) +
  geom_text(size = 5) +
  labs(title = "Edited text grobs")

set_font(p_text, family = "serif", fontface = "italic", color = "firebrick")

Summary

The functions in ggfun are intentionally small and composable. They are most useful when a plot is almost complete but needs a custom theme element, a specialized layer, a modified facet strip, or access to the data and grobs that ggplot2 builds internally.