Home > OS >  geom_text() place text in a corner
geom_text() place text in a corner

Time:03-02

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)

This gives me a plot: enter image description here

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)) 

enter image description here

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)

enter image description here

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)

enter image description here

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)

enter image description here

  • Related