Home > OS >  ggplot2 scale_color_identity() how to change linestyle and design of the legend?
ggplot2 scale_color_identity() how to change linestyle and design of the legend?

Time:05-01

I coded the following ggplot. The problem is that the design of the legend is flawed: The elements of the legend are interconnected with what appears to be dashed lines. How can this be removed? And furthermore, navy should be a dashed line, but it is shown as a solid one. Is there a possibility to change that? This is my code:

plot1 <- ggplot()  
  geom_line(aes(x = datacom$Datum , y = datacom$`CDU/CSU`, colour = "black"),size=0.8)  
  geom_line(aes(x = datacom$Datum , y = datacom$SPD, colour = "red"),size=0.8)  
  geom_line(aes(x = datacom$Datum , y = datacom$GRÜNE, col = "green"),size=0.8)  
  geom_line(aes(x = datacom$Datum , y = datacom$FDP, col = "gold1"),size=0.8)  
  geom_line(aes(x = datacom$Datum , y = datacom$`Linke/PDS`, col = "darkred"),size=0.8)  
  geom_line(aes(x = datacom$Datum[154:168] , y = datacom$Piraten[154:168], col = "tan1"),size=0.8)  
  geom_line(aes(x = datacom$Datum[169:272] , y = datacom$AfD[169:272], col = "blue"),size=0.8)  
  geom_line(aes(x = datacom$Datum , y = datacom$Sonstige, col = "grey"),size=0.8)  
  geom_vline(aes(xintercept = datacom$Datum[263], color = "navy"), linetype="longdash",size = 0.5) 
  geom_vline(xintercept = datacom$Datum[215], color = "navy", size = 0.5,linetype="longdash") 
  geom_vline(xintercept = datacom$Datum[167], color = "navy", size = 0.5,linetype="longdash") 
  geom_vline(xintercept = datacom$Datum[127], color = "navy", size = 0.5,linetype="longdash") 
  geom_vline(xintercept = datacom$Datum[79], color = "navy", size = 0.5,linetype="longdash") 
  geom_vline(xintercept = datacom$Datum[44], color = "navy", size = 0.5,linetype="longdash") 
  scale_color_identity(name = NULL, labels = c(black = "CDU/CSU", red = "SPD",green="Die Grünen",gold1="FDP",darkred = "Die Linke/PDS",tan1="Piraten",blue="AfD",grey="Sonstige",navy="Bundestagswahlen"), guide = "legend")  
   theme_bw()  
  theme(legend.position = "bottom")  
  theme(axis.text.x = element_text(angle = 90))  
  labs(title="Forsa-Sonntagsfrage Bundestagswahl in %") ylab("Prozent") xlab("Jahre")

plot1

Thanks in advance

The Graphic:

CodePudding user response:

Your code has a lot of unnecessary repetition and you are not taking advantage of the syntax of ggplot.

The reason for the vertical dashed lines in the legend is that one of your geom_vline calls includes a color mapping, so its draw key is being added to the legend. You can change its key_glyph to draw_key_path to fix this. Note that you only need a single geom_vline call, since you can have multiple x intercepts.

ggplot(datacom, aes(x = Datum))  
  geom_line(aes(y = `CDU/CSU`, colour = "black"), size = 0.8)  
  geom_line(aes(y = SPD, colour = "red"), size = 0.8)  
  geom_line(aes(y = GRÜNE, col = "green"), size = 0.8)  
  geom_line(aes(y = FDP, col = "gold1"), size = 0.8)  
  geom_line(aes(y = `Linke/PDS`, col = "darkred"),size = 0.8)  
  geom_line(aes(y = Piraten, col = "tan1"), 
            data = datacom[154:168,], size = 0.8)  
  geom_line(aes(y = AfD, col = "blue"),
            data = datacom[169:272,], size = 0.8)  
  geom_line(aes(y = Sonstige, col = "grey"), size = 0.8)  
  geom_vline(data = datacom[c(263, 215, 167, 127, 79, 44),],
             aes(xintercept = Datum, color = "navy"), linetype = "longdash", 
             size = 0.5, key_glyph = draw_key_path) 
  scale_color_identity(name = NULL, 
                       labels = c(black = "CDU/CSU", red = "SPD",
                                  green = "Die Grünen", gold1 = "FDP",
                                  darkred = "Die Linke/PDS",
                                  tan1 = "Piraten", blue = "AfD",
                                  grey = "Sonstige",
                                  navy = "Bundestagswahlen"),
                       guide = "legend")  
  theme_bw()  
  theme(legend.position = "bottom",
        axis.text.x     = element_text(angle = 90))  
  labs(title = "Forsa-Sonntagsfrage Bundestagswahl in %",
       y     = "Prozent",
       x     = "Jahre")

enter image description here

An even better way to make your plot would be to pivot the data into long format. This would mean only a single geom_line call:

library(tidyverse)

datacom %>%
  mutate(Piraten = c(rep(NA, 153), Piraten[154:168], 
                     rep(NA, nrow(datacom) - 168)),
         AfD     = c(rep(NA, 168), AfD[169:272], 
                     rep(NA, nrow(datacom) - 272))) %>%
  pivot_longer(-Datum, names_to = "Series") %>%
  ggplot(aes(x = Datum, y = value, color = Series))  
  geom_line(size = 0.8, na.rm = TRUE)  
  geom_vline(data = datacom[c(263, 215, 167, 127, 79, 44),],
             aes(xintercept = Datum, color = "Bundestagswahlen"), 
             linetype = "longdash", size = 0.5, key_glyph = draw_key_path)  
  scale_color_manual(name = NULL, 
                     values = c("CDU/CSU" = "black", SPD = "red",
                                "GRÜNE" = "green", FDP = "gold1",
                                "Linke/PDS" = "darkred",
                                Piraten = "tan1", AfD = "blue",
                                Sonstige = "grey",
                                "Bundestagswahlen" = "navy"))  
  theme_bw()  
  theme(legend.position = "bottom",
        axis.text.x     = element_text(angle = 90))  
  labs(title = "Forsa-Sonntagsfrage Bundestagswahl in %",
       y     = "Prozent",
       x     = "Jahre")

enter image description here


Data used to create plot

Obviously, I had to create some data to get your code to run, since you didn't supply any. Here is my code for creating the data

var <- seq(5, 15, length = 280)

datacom <- data.frame(Datum       = seq(as.POSIXct("1999-01-01"), 
                                        as.POSIXct("2022-04-01"), by = "month"),
                      `CDU/CSU`   = 40   cumsum(rnorm(280)),
                      SPD         = 40   cumsum(rnorm(280)),
                      GRÜNE       = rpois(280, var),
                      FDP         = rpois(280, var),
                      `Linke/PDS` = rpois(280, var),
                      Piraten     = rpois(280, var),
                      AfD         = rpois(280, var),
                      Sonstige    = rpois(280, var), check.names = FALSE)
  • Related