We are pleased to release ggplot2 3.5.0. This release is a large one, so we have split the updates into multiple posts. This posts outlines changes to axes; see the main release post to learn about other changes.
Axes, alongside
legends, are visual representations of scales and allow observers to read values off of a plot. The innards of axes, like other guides, underwent a major overhaul with the guide system rewrite. Axes specifically are guides for positions and classically display labelled tick marks. In Cartesian coordinates, these are the x- and y-positions, but in non-Cartesian systems may reflect a theta, radius, longitude or latitude. In ggplot2, an axis is usually represented by the
guide_axis()
function. We outline the following changes to axes:
Minor ticks
A much requested expansion of axis capabilities is the ability to draw minor ticks. To draw minor ticks, you can use the minor.ticks
argument of
guide_axis()
.
library(ggplot2)
p <- ggplot(mpg, aes(displ, hwy)) +
geom_point() +
guides(
x = guide_axis(minor.ticks = TRUE),
y = guide_axis(minor.ticks = TRUE)
)
p
The minor ticks are unlabelled ticks and follow the minor_breaks
provided to the scale. Their length is determined by the axis.minor.ticks.length
and their positional children. The rest of their appearance is inherited from the major ticks, as can be seen in the plot below where the minor ticks on the y-axis are also blue. To tweak their style separately from the major ticks, the axis.minor.ticks.{x.bottom/x.top/y.left/y.right}
setting can be used. Please note that there is no axis.minor.ticks
setting without the position suffixes, as they inherit from the major ticks.
p + scale_x_continuous(minor_breaks = scales::breaks_width(0.2)) +
theme(
axis.ticks.length = unit(5, "pt"),
axis.minor.ticks.length = rel(0.5),
axis.minor.ticks.x.bottom = element_line(colour = 'red'),
axis.ticks.y = element_line(colour = "blue")
)
Capping
Axes can now also be ‘capped’ at the upper and lower end. We hesitate to call this improvement ‘new’, as it has been a part of base R plotting since time immemorial. When axes are capped, the axis line will not be drawn up to the panel edge, but up to the first and last breaks. Unsurprisingly, this only affects plots where the axis line is not blank.
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
guides(
x = guide_axis(cap = "both"), # Cap both ends
y = guide_axis(cap = "upper") # Cap the upper end
) +
theme(axis.line = element_line())
Logarithmic axes
A new axis for displaying logarithmic (and related) scales has been added:
guide_axis_logticks()
. This axis draws three types of tick marks at log10-spaced positions. The ticks positions are placed in the original, untransformed data-space, so the axis plays well with scale- and coord-transformations. To accommodate a series of logarithmic-like transformations, such as
scales::transform_pseudo_log()
or
scales::transform_asinh()
, scales that include 0 in their limits have the ticks mirrored around 0.
r <- seq(0.001, 0.999, length.out = 100)
df <- data.frame(
x = qcauchy(r),
y = qlnorm(r)
)
p <- ggplot(df, aes(x, y)) +
geom_line() +
coord_trans(y = "reverse") +
scale_y_continuous(
transform = "log10",
breaks = c(0.1, 1, 10),
guide = guide_axis_logticks(long = 2, mid = 1, short = 0.5)
) +
scale_x_continuous(
transform = "asinh",
breaks = c(-100, -10, -1, 0, 1, 10, 100),
guide = "axis_logticks"
)
p
The log-ticks axis supersedes the earlier
annotation_logticks()
function. Because it is implemented as an axis, it has minimal fuss with the placement of labels and is immune to the clipping options in the coord. To mirror
annotation_logticks()
more closely, you can set a negative tick length in the theme.
Stacked axes
The last new axis is technically not an axis, but a way to combine axes.
guide_axis_stack()
can take multiple other axes and combine them by placing them next to one another. On its own, the usefulness of stacking axes is pretty limited. However, when extensions start defining custom position guides, it is an easy way to mix-and-match axes from different extensions. The first axis is placed next to the panel and subsequent axes are placed further away from the panel. Axes, like legends, have acquired a theme
argument that can be used to customise the display of individual axes. Currently, there is not a compelling case to use
guide_axis_stack()
, but it is an important building block for when axis extensions arrive.
Display in facets
More of an indirect improvement to axes, is the ability of facets to tweak the appearance of inner axes when scales are fixed. This facilitates requirements in some journals that every panel should have labelled axes.
facet_wrap()
and
facet_grid()
would previously only display axes in between panels when scales = "free"
was set. This is still the case, but there are more options available for
facet_grid()
and fixed scales. Using the axes = "all"
option, all axes are displayed, including those in between panels. When using axes = "all_x"
or axes = "all_y"
, you can narrow down which axes are displayed.
p <- ggplot(mpg, aes(displ, hwy)) +
geom_point()
p + facet_grid(year ~ drv, axes = "all_y")
In addition, you can choose to selectively suppress labels and only show ticks marks by using the axis.labels
argument.
p + facet_grid(year ~ drv, axes = "all", axis.labels = "all_y")
That wraps up the visible changes to axes for this post. To read about general changes, see the main post. The changes to legends are covered in a separate post and for the new polar coordinate system (and their axes) will be in a future post.