ggplot2: place text at right location
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
A common task in plotting is adding texts as labels or annotations to specific locations. ggplot()
has functions geom_text()
, geom_label()
and annotate()
for this purpose. In this post we discuss how ggplot2
controls positioning of text.
First we need to specify (x, y)
coordinate in the plot where the text is placed. By default, the center of the text is at (x, y)
, which is sometimes not what we want, as shown in the example below.
library(ggplot2) df <- data.frame(x = 1:3, y = 1:3, z = c("aa\nnew line", "bb\nnew line 1\nand new line 2", "cc")) g <- ggplot(df, aes(x = x, y = y)) + geom_col() + geom_point(color = "red") + coord_cartesian(xlim = c(0.3, 3.5), ylim = c(0.5, 3.5)) g + geom_text(aes(label = z)) + labs(subtitle = "(x, y) set the position of text but often is not we want")
As the text has its own shape and size, we need to determine which part of the text to be superimposed at (x, y)
. This positioning is controlled by parameters hjust
and vjust
. Imaging the text is surrounded by a rectangle and a local coordinate originates at the bottom left corner of the rectangle, (hjust, vjust)
then is a local position in the local coordinate. By default, hjust = 0.5
and vjust = 0.5
, that is, the center of the rectangle is at (x, y)
. We can change them to match to (x, y)
by borders or corners, as shown in the examples below. The positioning of text is still not ideal as it is too close to (x, y)
.
library(grid) library(gridExtra) g1 <- g + geom_text(aes(label = z), hjust = 0) + labs(subtitle = "hjust = 0 place left side of the text to (x, y)") g2 <- g + geom_text(aes(label = z), vjust = 1) + labs(subtitle = "vjust = 1 place top of the text to (x, y)") g3 <- g + geom_text(aes(label = z), hjust = 1, vjust = 0) + labs(subtitle = "hjust = 1 and vjust = 0 place tottom\nright cornor of the text to (x, y)") grid.arrange(g1, g2, g3, nrow = 1)
The parameters nudge_x
and nudge_y
shift whole text along x
and y
axis. With them we can add a space between text and (x, y)
.
g1 <- g + geom_text(aes(label = z), hjust = 0, nudge_x = 0.1) + labs(subtitle = "nudge_x = 0.1 moves text to the right by 0.1") g2 <- g + geom_text(aes(label = z), vjust = 1, nudge_y = -0.1) + labs(subtitle = "nudge_y = -0.1 moves text down by 0.1") g3 <- g + geom_text(aes(label = z), hjust = 1, vjust = 0, nudge_x = -0.1, nudge_y = 0.1) + labs(subtitle = "nudge_x = -0.1 nudge_y = 0.1 to northwest") grid.arrange(g1, g2, g3, nrow = 1)
For multi-line text, we also want to adjust the line space. The line space is set by parameter lineheight
.
g1 <- g + geom_text(aes(label = z), hjust = 1, vjust = 0, nudge_x = -0.1, lineheight = 0) + labs(subtitle = "lineheight = 0") g2 <- g + geom_text(aes(label = z), hjust = 1, vjust = 0, nudge_x = -0.1, lineheight = 0.9) + labs(subtitle = "lineheight = 0.9") g3 <- g + geom_text(aes(label = z), hjust = 1, vjust = 0, nudge_x = -0.1, lineheight = 2) + labs(subtitle = "lineheight = 2") grid.arrange(g1, g2, g3, nrow = 1)
As a final note, some people use hjust
and vjust
that are < 0
or > 1
to shift text from (x, y)
. This works well to move up and down a single line text but not good to move left and right or multi-line text, as hjust
and vjust
are relative to dimension of the rectangle around the text. Some bad examples are shown below. So it is better to use nudge_x
and nudge_y
to shift whole text.
g1 <- g + geom_text(aes(label = z), vjust = 1.3) + labs(subtitle = "vjust = 1.3, more line more space") g2 <- g + geom_text(aes(label = z), hjust = -0.2) + labs(subtitle = "hjust = -0.1, longer lines more space") grid.arrange(g1, g2, nrow = 1)
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.