The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Numbered markers on other plots

Scatter plots and maps are the most obvious choicies where numbered markers can be used. However, geom_focus() needs only an x and a y position, so it isn’t limited to scatter plots. Positions can be continuous, discrete or dates, and can come from your data or from a stat. This article adds numbered markers to line charts, bar charts and distributions.

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.5.3
library(ggindex)

Events on a line chart

To mark events on a time series, put them in their own data frame and pass it to geom_focus() with data. Here each event gets the unemployment value of its date, so the marker sits on the line.

events <- data.frame(
  date = as.Date(c("2001-03-01", "2007-12-01", "2008-09-15")),
  event = c(
    "Dot-com recession begins",
    "Great Recession begins",
    "Lehman Brothers collapses"
  )
)
events$unemploy <- approx(economics$date, economics$unemploy, events$date)$y

ggplot(economics, aes(date, unemploy)) +
  geom_line() +
  geom_focus(aes(info = event), data = events) +
  scale_info_discrete("Events") +
  labs(x = NULL, y = "Unemployed (thousands)") +
  theme_minimal()

Bar charts

On a discrete axis, markers sit at the centre of each category. Nudge them past the end of the bar with position_nudge(). Here the bars are horizontal, so the markers move along x.

classes <- as.data.frame(table(class = mpg$class), responseName = "n")

ggplot(classes, aes(n, class)) +
  geom_col(fill = "grey80") +
  geom_focus(
    aes(info = class, focus = n > 40),
    position = position_nudge(x = 3)
  ) +
  scale_info_discrete("Most common") +
  labs(x = "Models", y = NULL) +
  theme_minimal()

Points in a distribution

Number single observations on top of a box plot, such as outliers you want to name. Observations that share an info value share a number: both new beetles are 2.

ggplot(mpg, aes(class, hwy)) +
  geom_boxplot(outliers = FALSE) +
  geom_focus(aes(info = model, focus = hwy > 40)) +
  scale_info_discrete("Outliers") +
  labs(x = NULL, y = "Highway miles per gallon") +
  theme_minimal()

Summary statistics on a distribution

To mark the mean, median and mode on a density curve, compute them first and look up the height of the curve at each one with approx(). Putting the value in info makes the legend double as a table of the statistics.

waiting <- faithful$waiting
dens <- density(waiting)
centres <- data.frame(
  stat = c("Mean", "Median", "Mode"),
  x = c(mean(waiting), median(waiting), dens$x[which.max(dens$y)])
)
centres$y <- approx(dens$x, dens$y, centres$x)$y
centres$info <- sprintf("%s: %.1f min", centres$stat, centres$x)

ggplot(faithful, aes(waiting)) +
  geom_density(fill = "grey90") +
  geom_segment(
    aes(x = x, xend = x, y = 0, yend = y),
    data = centres,
    colour = "grey50",
    linetype = "dashed"
  ) +
  geom_focus(aes(x, y, info = info), data = centres) +
  scale_info_discrete(NULL) +
  labs(x = "Minutes to next eruption", y = "Density") +
  theme_minimal()

On a cumulative distribution, quantiles are points on the curve: the median is where it crosses 0.5. Label the markers with the percentage and explain it in the legend.

quartiles <- data.frame(p = c(0.25, 0.5, 0.75))
quartiles$waiting <- quantile(waiting, quartiles$p, type = 1)
quartiles$label <- quartiles$p * 100
quartiles$info <- sprintf(
  "%g%% erupt within %g min",
  quartiles$label,
  quartiles$waiting
)

ggplot(faithful, aes(waiting)) +
  stat_ecdf(geom = "step") +
  geom_focus(aes(y = p, label = label, info = info), data = quartiles) +
  scale_info_discrete("Quartiles") +
  labs(x = "Minutes to next eruption", y = "Cumulative probability") +
  theme_minimal()

type = 1 makes quantile() return observed values, so the markers sit on the steps of the empirical curve.

Positions from a stat

geom_focus() takes a stat like other geoms, so markers can show computed values. With stat = "summary" each marker sits at the class mean and shows it as the label.

ggplot(mpg, aes(class, hwy)) +
  geom_jitter(width = 0.2, height = 0, colour = "grey70") +
  geom_focus(
    aes(label = after_stat(round(y))),
    stat = "summary",
    fun = mean
  ) +
  labs(x = NULL, y = "Highway miles per gallon") +
  theme_minimal()

Other coordinate systems

Markers are placed by the plot’s coordinate system, so they follow it. The bar chart above in polar coordinates:

ggplot(classes, aes(class, n)) +
  geom_col(fill = "grey80") +
  geom_focus(aes(info = class, focus = n > 40)) +
  scale_info_discrete("Most common") +
  coord_radial() +
  labs(x = NULL, y = NULL) +
  theme_minimal()

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.