knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-" )
ggfittext is a ggplot2 extension for fitting text into boxes.
yeats <- data.frame( xmin = c(0, 4, 6, 4, 4, 5, 5.5, 5, 5, 5.25, 5.25), xmax = c(4, 8, 8, 6, 5, 6, 6, 5.5, 5.25, 5.5, 5.5), ymin = c(0, 4, 0, 0, 2, 3, 2, 2, 2.5, 2.75, 2.5), ymax = c(8, 8, 4, 2, 4, 4, 3, 2.5, 3, 3, 2.75), label = c("<span style='color:red'>T</span><span style='color:orange'>u</span><span style='color:yellow'>r</span><span style='color:green'>n</span><span style='color:blue'>i</span><span style='color:purple'>n</span><span style='color:violet'>g</span>", "**and**", "*turning*", "<span style='color:blue'>in</span>", "the<sup>*</sup>", "widening", "gyre", "the", "falcon", "cannot", "hear"), angle = c(0, 315, 270, 225, 180, 135, 90, 45, 0, 315, 270) ) library(ggfittext) library(ggplot2) library(patchwork) p1 <- ggplot(yeats, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, label = label, angle = angle)) + geom_rect(fill = "grey", colour = "black") + geom_fit_text(grow = TRUE, min.size = 0, rich = TRUE) polar_d <- data.frame( word = c("The" , "falcon" , "cannot" , "hear" , "the" , "falconer") , xmin = c( 0.0 , 0.2 , 0.35 , 0.6 , 0.65 , 0.8) , xmax = c( 0.2 , 0.35 , 0.6 , 0.65 , 0.8 , 1) , ymin = rep(0, 6), ymax = c( 0.95 , 0.85 , 0.75 , 0.65 , 0.45 , 0.35) ) p2 <- ggplot(polar_d, aes(label = word, xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax)) + geom_rect(aes(xmin = 0, xmax = 1, ymin = 0, ymax = 1)) + geom_rect(fill = "lightblue", colour = "black") + coord_polar() + geom_fit_text( grow = TRUE, padding.x = grid::unit(1, "mm"), padding.y = grid::unit(1, "mm"), place = "top", min.size = 0 ) p1 + p2
Install the release version of ggfittext from CRAN:
install.packages("ggfittext")
If you want the development version, install it from GitHub:
devtools::install_github("wilkox/ggfittext")
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:
ggplot(animals, aes(x = type, y = flies, label = animal)) + geom_tile(fill = "white", colour = "black") + geom_fit_text()
As with geom_text()
, the position of the text is set by the x
and y
aesthetics. 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 reflow
:
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:
ggplot(altitudes, aes(x = craft, y = altitude, label = altitude)) + geom_col() + geom_bar_text()
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()
With the rich = TRUE
argument, geom_fit_text()
and geom_bar_text()
both
support a limited subset of Markdown and HTML markup for text (rendered with
gridtext).
ggplot(animals_rich, aes(x = type, y = flies, label = animal)) + geom_tile(fill = "white", colour = "black") + geom_fit_text(reflow = TRUE, grow = TRUE, rich = TRUE)
Rich text cannot be drawn in polar coordinates. Please note that this feature is liable to change, and is subject to upstream changes to gridtext.
If you want to manually set the limits of the box (instead of having them
inferred from x
and y
), you can use xmin
& xmax
and/or ymin
& ymax
:
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 width
and/or
height
arguments, which should be grid::unit()
objects. The horizontal
and/or vertical centre of the box will be defined by x
and/or y
.
Text can be drawn in polar coordinates with geom_fit_text()
simply by adding
coord_polar()
to the plot. This feature is experimental and any bug reports
are very welcome.
p <- ggplot(gold, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = linenumber, label = line)) + coord_polar() + geom_rect() + scale_fill_gradient(low = "#fee391", high = "#238443") p + geom_fit_text(min.size = 0, grow = TRUE)
When text is drawn in polar coordinates, the flip = TRUE
argument can be used
to flip upside-down text the 'right way up' to ease readability:
p + geom_fit_text(min.size = 0, grow = TRUE, flip = TRUE)
All arguments to geom_fit_text()
can also be used with geom_bar_text()
.
contrast
can be used to automatically invert the colour of the text so
it contrasts against a background fill
:ggplot(animals, aes(x = type, y = flies, fill = mass, label = animal)) + geom_tile() + geom_fit_text(reflow = TRUE, grow = TRUE, contrast = TRUE)
padding.x
and padding.y
can 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 grid::unit()
objects.min.size
sets the minimum font size in points, by default 4 pt. Text
smaller than this will be hidden (see also outside
).outside
is FALSE
by default for geom_fit_text()
. If TRUE
, text
that is placed at "top", "bottom", "left" or "right" and must be shrunk
smaller than min.size
to 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.hjust
and vjust
set the horizontal and vertical justification of
the text, scaled between 0 (left/bottom) and 1 (right/top). These are both
0.5 by default.formatter
allows 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.fullheight
is 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
).ggplot(data.frame(label = "fullheight = TRUE", xmin = 0.25, xmax = 0.75, ymin = 0.25, ymax = 0.75), aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, label = label)) + geom_rect() + geom_fit_text(grow = TRUE, fullheight = TRUE, family = "mono") + theme(axis.text = element_blank(), axis.ticks = element_blank(), panel.background = element_blank(), plot.title = element_text(hjust = 0.5))
ggplot(data.frame(label = "fullheight = FALSE", xmin = 0.25, xmax = 0.75, ymin = 0.25, ymax = 0.75), aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, label = label)) + geom_rect() + geom_fit_text(grow = TRUE, fullheight = FALSE, family = "mono") + theme(axis.text = element_blank(), axis.ticks = element_blank(), panel.background = element_blank(), plot.title = element_text(hjust = 0.5))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.