Search code examples
rggplot2

ggplot legend override.aes for points containing no data


I'm trying to create swimmer plot with ggplot by following online resources because Power BI service does not support swimplot package but supports ggplot 3.3.3. The plot looks good, but the legend does not work as expected. An error occurs when using guides(color = guide_legend(override.aes =...)). I'm guessing it is because one of the columns (DaysCR) contains no data. Is it possible to show "CR" in the legend for DaysCR even if no data? Then maybe the override.aes would work.

The data looks like:

Subject DaysTRT DaysDISC DaysDTH DaysCR
XXX 10 11
YYY 16 17 20
library(tidyverse)

dat_swim <- 
dataset |>
    mutate(Subject = fct_reorder(factor(Subject), DaysTRT))

dataCR <- dataset[, c("Subject", "DaysCR")]

cols <- c("TRT" = "blue",
          "CR" = "green",
          "Death"="black", 
          "Discontinuation" = "red")

shape_override <- c(21,24,24,NA)
line_override <- c(NA,NA,NA,1)
fill_override <- c("green","black","red","blue")

ggplot(data = dat_swim, aes(y=Subject, group="Subject")) +

  geom_segment(aes(x = 0, xend=DaysTRT, y=Subject, color="TRT")) +
  geom_point(aes(x=DaysDISC, y=Subject, color="Discontinuation", fill="Discontinuation"), shape=24) +
  geom_point(aes(x=DaysDTH, y=Subject, color="Death", fill="Death"), shape=24) +
  geom_point(data = na.omit(dataCR), aes(x=DaysCR, y=Subject, color="CR", fill="CR"), shape=21) +

  scale_color_manual(values=cols, name="Legend") + scale_fill_manual(values=cols) + guides(fill=FALSE) + 

#issue with this line
   guides(color = guide_legend(
           override.aes = list(
             shape = shape_override,
             linetype = line_override,
             fill = fill_override)))

Thank you


Solution

  • You can set the limits= for the color scale to include all categories. Additionally I simplified your code a bit by using the same scale for color and fill. Doing so does not require to remove the fill scale and to override the fill aes.

    library(ggplot2)
    
    ggplot(data = dat_swim, aes(y = Subject, group = "Subject")) +
      geom_segment(aes(x = 0, xend = DaysTRT, y = Subject, color = "TRT")) +
      geom_point(
        aes(
          x = DaysDISC, y = Subject,
          color = "Discontinuation", fill = "Discontinuation"
        ),
        shape = 24
      ) +
      geom_point(
        aes(
          x = DaysDTH, y = Subject,
          color = "Death", fill = "Death"
        ),
        shape = 24
      ) +
      geom_point(
        data = na.omit(dataCR),
        aes(
          x = DaysCR, y = Subject,
          color = "CR", fill = "CR"
        ), shape = 21
      ) +
      scale_color_manual(
        values = cols, name = "Legend",
        limits = sort(names(cols)),
        aesthetics = c("color", "fill")
      ) +
      guides(color = guide_legend(
        override.aes = list(
          shape = shape_override,
          linetype = line_override
        )
      ))
    #> Warning: Removed 1 row containing missing values or values outside the scale range
    #> (`geom_point()`).
    

    DATA

    dataset <- data.frame(
      Subject = c("XXX", "YYY"),
      DaysTRT = c(10L, 16L),
      DaysDISC = c(11L, 17L),
      DaysDTH = c(NA, 20L),
      DaysCR = c(NA, NA)
    )