To reproduce:
library(tidyverse)
# use this for geom_text annotation
diamonds_annotations <- diamonds |>
group_by(cut) |>
summarise(SD_Price = paste0("sd = ", round(sd(price)), 2),
Cor_Price = paste0("cor = ", round(cor(price, carat), 2)))
diamonds |>
ggplot(aes(x = carat, y = price))
geom_point()
facet_wrap(. ~ cut)
I would like to annotate the facets with the standard deviation sd()
of price and also with the correlation cor()
of price with carat. Tried:
diamonds |>
ggplot(aes(x = carat, y = price))
geom_point()
facet_wrap(. ~ cut)
geom_text(data = diamonds_annotations, mapping = aes(x = -Inf, y = -Inf, label = SD_Price))
geom_text(data = diamonds_annotations, mapping = aes(x = -Inf, y = -Inf, label = Cor_Price))
Here it looks like the text is cut off along the bottom. Tried several variations of playing with vjust and hjust e.g:
diamonds |>
ggplot(aes(x = carat, y = price))
geom_point()
facet_wrap(. ~ cut)
geom_text(data = diamonds_annotations, mapping = aes(x = -Inf, y = -Inf, label = SD_Price), vjust = -8, hjust = -3, size = 3)
geom_text(data = diamonds_annotations, mapping = aes(x = -Inf, y = -Inf, label = Cor_Price), vjust = -6, hjust = -2, size = 3)
Here I can see the text cut off but still 'there' over on the right hand side.
This feels too fiddly and I wondered if I was doing something 'wrong'. Is there a way to consistently position the text in a corner, e.g. in this plot the bottom right hand side tends to be open space... is there a way to align right and bottom?
Same question e.g. right and top?
CodePudding user response:
This is tricky, but possible. First, create the plot without annotations:
p <- diamonds |>
ggplot(aes(x = carat, y = price))
geom_point()
facet_wrap(. ~ cut)
Now get the x and y ranges from the plot object:
x_range <- layer_scales(p)$x$range$range
y_range <- layer_scales(p)$y$range$range
Now we can use this information to add text at a fixed position within each facet:
p geom_text(data = diamonds_annotations,
x = x_range[2] - 0.1 * (diff(x_range)),
y = y_range[1] 0.1 * (diff(y_range)),
aes(label = paste(SD_Price, Cor_Price, sep = "\n")),
hjust = 1)
Similarly, for a fixed position in the top right, we can do:
p geom_text(data = diamonds_annotations,
x = x_range[2] - 0.1 * (diff(x_range)),
y = y_range[2] - 0.1 * (diff(y_range)),
aes(label = paste(SD_Price, Cor_Price, sep = "\n")),
hjust = 1)