How to rotate text to match slope of line

Suppose I would like to add text at the point (2, 2) so that it aligns with the line y = x.

If I use the angle parameter for geom_richtext() from the ggtext package, I can see what happens if I set it to 45^\circ:

library(tidyverse)
library(ggtext)

tibble(x = 1:3, y = 1:3) %>% 
  ggplot(aes(x, y)) +
  geom_line() +
  geom_richtext(
    x = 2, y = 2,
    label = 'slope',
    angle = 45
  )


Created on 2021-03-24 by the reprex package (v0.3.0)

Not great, but even worse if I change the y-axis scale:


tibble(x = 1:3, y = 1:3) %>% 
  ggplot(aes(x, y)) +
  geom_line() +
  geom_richtext(
    x = 2, y = 2,
    label = 'slope',
    angle = 45
  ) +
  coord_cartesian(
    ylim = c(0, 4)
  )

So here's my question:

How can I represent the slope of a given line segment so that it's always aligned, no matter how the axis scale limits are chosen?

It seems that both the aspect ratio of the plot (set by the size of the plot pane in RStudio) and the corresponding ratio of the axis ranges are required:

library(tidyverse)
library(ggtext)

tibble(x = 1:3, y = 1:3) %>% 
  ggplot(aes(x, y)) +
  geom_line() +
  geom_richtext(
    x = 2, y = 2,
    label = 'slope',
    angle = 
      atan(
        # slope
        1 *
          # aspect ratio of plot:
          unit(0, 'npc') %>% grid::convertY('native', valueOnly = T) /
          unit(1, 'npc') %>% grid::convertX('native', valueOnly = T) /
          # ratio of y-range to x-range of plot:
          ( 2 / 2 )
      ) * 180 / pi
  )


tibble(x = 1:3, y = 1:3) %>% 
  ggplot(aes(x, y)) +
  geom_line() +
  geom_richtext(
    x = 2, y = 2,
    label = 'slope',
    angle = 
      atan(
        # slope
        1 *
          # aspect ratio of plot:
          unit(0, 'npc') %>% grid::convertY('native', valueOnly = T) /
          unit(1, 'npc') %>% grid::convertX('native', valueOnly = T) /
          # ratio of y-range to x-range of plot:
          ( 4 / 2 )
      ) * 180 / pi
  )  +
  coord_cartesian(
    ylim = c(0, 4)
  )

Created on 2021-03-24 by the reprex package (v0.3.0)

3 Likes

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.