Sometimes you want to draw some text in a ggplot2 plot so that it fits inside a defined area. You can do this by manually fiddling with the font size, but this is tedious and un-reproducible. ggfittext provides a geom called
geom_fit_text() that automatically resizes text to fit inside a box. It works like this:
geom_text(), the position of the text is set by the
geom_fit_text() tries to infer the width and height of the box in which the text is allowed to fit, and shrinks down any text that is too big.
Another way to make the text fit in the box is by reflowing it; that is, wrapping it over multiple lines. With the
reflow = TRUE argument,
geom_fit_text() will reflow the text before (if still necessary) shrinking it:
ggplot(animals, aes(x = type, y = flies, label = animal)) + geom_tile(fill = "white", colour = "black") + geom_fit_text(reflow = TRUE)
If you want the text to be as large as possible, the argument
grow = TRUE will increase the text size to the maximum that will fit in the box. This works well in conjunction with
ggplot(animals, aes(x = type, y = flies, label = animal)) + geom_tile(fill = "white", colour = "black") + geom_fit_text(reflow = TRUE, grow = TRUE)
By default, text is placed in the centre of the box. However, you can place it in a corner or on a side of the box with the
place argument, which takes values like “top”, “topright”, “bottomleft” and so on:
ggplot(animals, aes(x = type, y = flies, label = animal)) + geom_tile(fill = "white", colour = "black") + geom_fit_text(place = "topleft", reflow = TRUE)
ggfittext also provides a geom
geom_bar_text() for labelling bars in bar plots:
geom_bar_text() works with stacked bar plots:
ggplot(beverages, aes(x = beverage, y = proportion, label = ingredient, fill = ingredient)) + geom_col(position = "stack") + geom_bar_text(position = "stack", reflow = TRUE)
And it works with dodged bar plots, and with flipped bar plots:
ggplot(beverages, aes(x = beverage, y = proportion, label = ingredient, fill = ingredient)) + geom_col(position = "dodge") + geom_bar_text(position = "dodge", grow = TRUE, reflow = TRUE, place = "left") + coord_flip()
If you want to manually set the limits of the box (instead of having them inferred from
y), you can use
ggplot(presidential, aes(ymin = start, ymax = end, x = party, label = name)) + geom_fit_text(grow = TRUE) + geom_errorbar(alpha = 0.5)
Alternatively, you can set the width and/or height with the
height arguments, which should be
grid::unit() objects. The horizontal and/or vertical centre of the box will be defined by
ggplot(gold, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = linenumber, label = line)) + coord_polar() + geom_rect() + geom_fit_text(min.size = 0, grow = TRUE) + scale_fill_gradient(low = "#fee391", high = "#238443")
contrastcan be used to automatically invert the colour of the text so it contrasts against a background
ggplot(animals, aes(x = type, y = flies, fill = mass, label = animal)) + geom_tile() + geom_fit_text(reflow = TRUE, grow = TRUE, contrast = TRUE)
padding.ycan be used to set the padding between the text and the edge of the box. By default this is 1 mm. These values must be given as
min.sizesets the minimum font size in points, by default 4 pt. Text smaller than this will be hidden (see also
FALSEby default for
TRUE, text that is placed at “top”, “bottom”, “left” or “right” and must be shrunk smaller than
min.sizeto fit in the box will be flipped to the outside of the box (if it fits there). This is mostly useful for drawing text inside bars in a bar plot.
vjustset the horizontal and vertical justification of the text, scaled between 0 (left/bottom) and 1 (right/top). These are both 0.5 by default.
formatterallows you to provide a function that will be applied to the text before it is drawn. This is mostly useful in contexts where variables may be interpolated, such as when using gganimate.
fullheightis automatically set depending on place, but can be overridden with this option. This is used to determine the bounding box around the text. If
FALSE, the bounding box includes the x-height of the text and ascenders, but not any descenders. If TRUE, it extends from the top of the ascenders to the bottom of the descenders. This is mostly useful in situations where you want to ensure the baseline of text is consistent between labels (
fullheight = FALSE), or when you want to avoid descenders spilling out of the bounding box (
fullheight = TRUE).