1

I'm creating a graph of air temperatures in two locations, denoted on the plot by solid lines (location 1) and dashed lines (location 2). I've added geom_label annotations to display the min and max temperatures as text, and I would really like for the boxes surrounding the text to correspond to the linetypes already on the plot (i.e. solid boxes for location 1 labels; dashed boxes for location 2 labels).

Code-wise, I currently have

ggplot() +
  geom_line(data = sum_BHBM3, aes(x = MM, y = minATMP), col = "dodgerblue2") +
  geom_line(data = sum_44013, aes(x = MM, y = meanATMP), col = "black") +
  geom_line(data = sum_44013, aes(x = MM, y = maxATMP), col = "firebrick3") +
  geom_line(data = sum_BUZM3, aes(x = MM, y = minATMP), col = "dodgerblue2", linetype = "22") +
  geom_line(data = sum_BUZM3, aes(x = MM, y = meanATMP), col = "black", linetype = "22") +
  geom_line(data = sum_NWPR1, aes(x = MM, y = maxATMP), col = "firebrick3", linetype = "22") +
  annotate("label", label = "10-yr min: -21.9°C", col = "dodgerblue2", x = 3.75, y = -21) +
  annotate("label", label = "10-yr max: 30.1°C", col = "firebrick3", x = 7.9, y = 25) +
  annotate("label", label = "10-yr min: -16.5°C", col = "dodgerblue2", x = 2, y = -5) +
  annotate("label", label = "10-yr max: 35.5°C", col = "firebrick3", x = 4.4, y = 34.5)

...

I've tried adding linetype = "22" to the annotate lines to create a dashed outline, as in

annotate("label", label = "10-yr min: -16.5°C", col = "dodgerblue2", x = 2, y = -5, linetype = "22")

but it generates the "unknown parameters" warning message and thus appears to be invalid. I've also been unable to find any resources online covering this situation.

Is there a way to set the linetype of the box surrounding a label geom, specifically to a dashed line?

  • You might submit this as a feature request to the [ggplot2 issues list](https://github.com/tidyverse/ggplot2/issues) ... there's no reason I can think of that this *shouldn't* be possible ... – Ben Bolker Jul 25 '23 at 23:28

2 Answers2

2

You could plot rounded rectangles then text labels. Use strwidth to measure the strings - this allows the boxes to fit around them nicely:

library(tidyverse)

mtcars %>%
  slice_head(n = 8) %>%
  rownames_to_column() %>%
  mutate(strwidth = strwidth(rowname)/20) %>%
  mutate(xmin = wt - strwidth, 
         xmax = wt + strwidth, 
         ymin = mpg - 0.4,
         ymax = mpg + 0.4) %>%
  mutate(cyl = factor(cyl)) %>%
  ggplot(aes(wt, mpg, label = rowname)) +
  statebins:::geom_rrect(aes(xmin = xmin, xmax = xmax, ymin = ymin, 
                             ymax = ymax, linetype = cyl), 
                         fill = "white", color = "black",
           radius = unit(0.4, "lines"), size = 1) +
  geom_text()

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
1

It doesn't look that way (without hacking ggplot2 or finding an alternative geom that someone has defined). The internal code here shows that the only rectangle-formatting information passed downward is the colo(u)r, fill, and line width.

  rect.gp = gpar(
          col = if (isTRUE(all.equal(label.size, 0))) NA else row$colour,
          fill = alpha(row$fill, row$alpha),
          lwd = label.size * .pt
        )

The closest I can get right now is a hacky tile + text combo (combining these two into a function would make sense but is a little tricky)

ggplot(data.frame(x = 1:10, y = 1:10), aes(x, y)) + geom_point() + 
      annotate("tile", x = 5, y = 5, width = 1, height = 0.5, 
                  lwd = 1, lty = 3, fill = "white", col = "red") +
      annotate("text", label = "hello", x = 5, y = 5)
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453