Home > database >  How do I change the symbol for just one legend entry using ggplot2?
How do I change the symbol for just one legend entry using ggplot2?

Time:09-15

I am trying to change the orange dot in the legend to be a diamond with a line through it. I have been unable to change only the one symbol; my attempts have either changed all of the symbols to diamonds, or the legend lists the shapes and colors separately.

plot

Here's reproducible data:

data <- structure(list(Period = c(1, 2, 5, 4, 3), 
                   y1 = c(0.0540540540540541, 0.0256410256410256, 0.454545454545455, 0.451612903225806, 0.333333333333333), 
                   y2 = c(0.157894736842105, 0.163265306122449, 0.277027027027027, 0.289473684210526, 0.318181818181818), 
                   y3 = c(0.0917, 0.1872, 0.1155, 0.0949, 0.2272)), row.names = c(NA, -5L), 
              class = c("tbl_df", "tbl", "data.frame"))

and

CIinfo <- structure(list(Period = c(1, 2, 3, 4, 5), 
                     PointEstimate = c(0.09170907, 0.18715355, 0.22718774, 0.09494454, 0.11549015), 
                     LowerCI = c(0.02999935,0.09032183, 0.1859676, 0.06469029, 0.08147854), 
                     UpperCI = c(0.1534188, 0.2839853, 0.2684079, 0.1251988, 0.1495018)), 
                row.names = c(NA, 5L), class = "data.frame")

To generate the plot:


library(ggplot2)
library(ggtext) #text box for plot title

scatter <- ggplot(data)   
  geom_point(aes(x=Period, y=y1, colour="prevalence"), size=4)   #colour is for legend label
  
  geom_segment(data = CIinfo, aes(x=Period, y=LowerCI, xend=Period, yend=UpperCI, #bars for 95% CI
                                  colour="estimated probability and 95%CI"), 
               size=2, lineend = "round", alpha=0.7, show.legend = FALSE)   #alpha is transparency
  
  geom_point(aes(x=Period, y=y2, colour="median prevalence"), size=3)  

  geom_point(aes(x=Period, y=y3, colour="estimated probability and 95%CI"), size=4, shape=18)  
  
  theme_minimal()  
  scale_color_manual(values = c("#d2d2d2","#365C8DFF","#EB6529FF"), 
                     breaks = c("prevalence","median prevalence","estimated probability and 95%CI"),  #set order of legend
                     labels = ~ stringr::str_wrap(.x, width = 28))   #width of legend
  
  labs(x = "Time Period", 
       title ="Estimated Probability and Prevalence Rates")  
  
  theme(plot.title = element_textbox(hjust = 0.5, #center title
                                     margin = margin(b = 15)), #pad under the title
        plot.title.position = "plot",
        axis.title.x = element_text(margin = margin(t = 10, r = 0, b = 0, l = 0)), #pad x axis label
        axis.title.y = element_blank(), # remove y-axis label
        axis.text = element_text(face="bold"), #bold axis labels
        panel.grid.minor.x = element_blank(), # remove vertical minor gridlines
        legend.title = element_blank(), # remove legend label
        legend.spacing.y = unit(8, "pt") # space legend entries
  )   
  
  guides(colour = guide_legend(byrow = TRUE))   # space legend entries
  
  scale_y_continuous(labels = scales::percent, limits = c(0, .5))  # y-axis as %

scatter

  


CodePudding user response:

Does something like this help? I'm using a random example, but hopefully it points you in the right direction:

library(tidyverse)

draw_key_custom <- function(data, params, size) {
  if (data$colour == "orange") {
    data$size <- .5
    draw_key_pointrange(data, params, size)
  } else {
    data$size <- 2
    draw_key_point(data, params, size)
  }
}

mtcars |>
  ggplot(aes(hp, mpg, color = as.factor(cyl))) 
  geom_point(key_glyph = "custom") 
  guides(color = guide_legend(
    override.aes = list(shape = c(16,16,18),
                        color= c("black", "black", "orange")))
    )

P.S. I borrowed some code from this question: R rotate vline in ggplot legend with scale_linetype_manual

  • Related