简体   繁体   中英

Is it possible to draw a legend for the different lengths of lines (birds-on-wire plot) drawn using geom_linerange

I am making a birds-on-wire plot using geom_linerange and geom_linerangeh to show subjects' treatment over time (wire) and the occurrence of some events (birds) during the treatment period. I am using the height of "birds" (ie length of vertical lines) to represent a certain characteristic of the "birds" (events). There are only 4 possible different lengths (see variable evt_type2 ) below. See mock data, code, and plot below.

library(tidyverse)
library(ggstance)
###Mock data###
#Treatment data
data_foo1 <- data.frame(subjectn = c(1, 1, 2, 3, 3, 3, 4, 5),
                        trt_start = c(1, 25, 1, 1, 50, 101, 1, 1),
                        trt_end = c(80, 60, 100, 25, 100, 200, 120, 90),
                        trt_type = as.factor(c(1, 2, 1, 3, 4, 5, 2, 4)),
                        stringsAsFactors =  F)

#Some kind of events data
data_foo2 <- data.frame(subjectn = c(1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5),
                        evt_start = c(70, 20, 90, 92, 24, 50, 70, 120, 170, 69, 80, 90),
                        evt_type1 = as.factor(c(0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0)),
                        evt_type2 = c(0.2, 0.8, 0.2, 0.4, 0.4, 0.2, 0.2, 0.6, 0.4, 0.4, 0.6, 0.2))

###Plot###
data_foo2 %>% 
  ggplot() + 
  geom_linerange(aes(x = evt_start, y = subjectn, ymin = subjectn, ymax = subjectn + evt_type2, linetype = evt_type1), size=0.8,  alpha = 0.5) +
  geom_linerangeh(data = data_foo1, aes(x = trt_start, y = subjectn, xmin = trt_start, xmax = trt_end, color = trt_type), size = 1.2, alpha = 0.7) +
  scale_y_continuous(breaks = c(1, 2, 3, 4, 5), labels = c("A001", "A002", "A003", "A004", "A005")) +
  xlab("Time") + theme_bw()

See the resulting plot here

在此处查看结果图

My question is, is it possible to add a legend for the 4 different vertical line lengths? THANK YOU!

As mentioned in the comment, showing lengths of lines in the legend is generally not easily possible. One option would be to create a fake legend - another plot, which you then add to your main plot.

But I struggle to find the visualisation very compelling. Line lengths are difficult to discern, expecially when you have different line types and a line can cut off weirdly (see subject A003). It would also not be clear in the legend how to map the respective line length to the legnth in the plot.

Thus, I recommend using a different aesthetic for visualising dimension event 2. One way would be to draw rectangles instead of lines and use the fill. You can make this categorical (as in my example) or continuous, and the legend easily maps to your data - visually, in my opinion, you can better discern the four different event types.

library(tidyverse)
library(ggstance)

ggplot() +
  geom_linerangeh(
    data = data_foo1,
    aes(
      y = subjectn,
      xmin = trt_start,
      xmax = trt_end,
      color = trt_type
    ),
    size = 1.2, alpha = 0.7
  ) +
  geom_rect(
    data = data_foo2, aes(
      xmin = evt_start - 2,
      xmax = evt_start + 2,
      ymin = subjectn,
      ymax = subjectn + 0.5,
      linetype = evt_type1,
      fill = as.character(evt_type2)
    ),
    size = 0.2, color = "black", alpha = 0.5
  ) +
  scale_fill_brewer() +
  scale_y_continuous(breaks = 1:5, labels = paste0("A00", 1:5)) +
  theme_bw()

Or, you can keep the lines, and add a second color aesthetic with ggnewscale .

ggplot() +
  geom_linerangeh(
    data = data_foo1,
    aes(
      y = subjectn,
      xmin = trt_start,
      xmax = trt_end,
      color = trt_type
    ),
    size = 1.2, alpha = 0.7
  ) +
  scale_y_continuous(breaks = 1:5, labels = paste0("A00", 1:5)) +
  ggnewscale::new_scale_color()+
  geom_linerange(data = data_foo2, 
                 aes(x = evt_start, 
                     y = subjectn, 
                     ymin = subjectn, 
                     ymax = subjectn + 0.5, 
                     color = as.character(evt_type2),
                     linetype = evt_type1),
                 size=0.8) +
  scale_color_brewer() +
  theme_bw()

Created on 2020-04-26 by the reprex package (v0.3.0)

The colors come out quite "light", and if you want them "darker", you can use the shades packages, eg, by wrapping your scale_color function into one of the brightness modifying functions, eg shades::brightness(scale_color_brewer(), shades::delta(-0.2))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM