Home > Enterprise >  ggplot2 legend showing but variables in plot don't have colour
ggplot2 legend showing but variables in plot don't have colour

Time:08-30

I have been working on some code to plot a graph with multiple variables with a secondary Y axis and legend. I achieved this far with the examples below:

ggplot2 line chart gives "geom_path: Each group consist of only one observation. Do you need to adjust the group aesthetic?"

Adjusting the second y axis in ggplot2

Y limits for ggplot with sec.axis

However, I am currently sitting with two versions of the same graph. One has no colour in the plot itself but includes a legend with the correct colours for each variable and a second graph that has colour in the plot but no legend shows. Please the the plots and code below.

I am aware it is something to do with the geom_point() code line as I saw in the answer from this previous question: Reasons that ggplot2 legend does not appear

colour= XYZ should be inside the aes(),not outside

geom_point(aes(data, colour=XYZ)) #------>legend

geom_point(aes(data),colour=XYZ) #------>no legend

Please find a chunk of the dataset below:

h1enraw <-structure(list(run = c(1738, 1739, 1740, 1741, 1742, 1743),
                          temp = c(19, 19, 19, 19, 21, 22),
                          avgbase = c(1386, 1386, 1389, 1389, 1352, 1336),
                          no2c = c(6.98, 6.96, 6.94, 6.99, 7.01, 7.01),
                          no3c = c(18.52, 17.6, 18.77, 19.81, 18.22, 18.60)), 
                     row.names = c(NA, 6L), class = "data.frame")

In line with the quoted code above I understand why one of my graph versions has a legend and the other one does not. I just do not understand how this impacts the variables within the graph to have colour or not. I would really appreciate it if someone could point me to the right direction.

Graph with no colour but showing the legend

# Choose number for dividing second Y axis
scaleRight <- 40
ymax <-43

h1no2<-ggplot(h1enraw, aes(x=run))  
  geom_path(aes(y=temp, group=1,colour="cornflowerblue"), size=0.9)  
  geom_point(aes(y=no2c, group=1,colour="red"))  
  geom_point(aes(y=no3c, group=1,colour="darkgreen"))  
  geom_line(aes(y=avgbase/scaleRight, group=1,colour="chocolate1"), size=0.9)  
  scale_y_continuous(breaks=seq(0,40,2), expand = expansion(mult = c(0,.05)),
                     sec.axis = sec_axis(~.*scaleRight, name = "Average Baseline (Transmitance Units)"))  
  coord_cartesian(ylim = c(0, ymax))  
  theme_classic()  
  labs( y="Temperature (°C) / Concentration (ppm)", x="Run", title = "H1 - High Temperature Cycle")  
  theme(text = element_text(size=9),
        axis.text.x = element_text(angle=90, vjust=0.6),
        axis.text=element_text(size=12),
        axis.title=element_text(size=14,face="bold"),
        panel.border = element_rect(colour = "chocolate1", fill=NA, size=0.5),
        legend.position = "bottom", legend.title=element_text(size=10), legend.text = element_text(size=8),
        axis.title.y = element_text(size=10),
        plot.title = element_text(size=14, face="bold"))  
  theme(legend.title=element_blank())   
  scale_fill_manual(breaks=c("temp","no2c","no3c","avgbase"),
                    labels=c("Temperature", "NO2", "NO3", "Avg Baseline"),
                    values = c("temp"="cornflowerblue", "no2c"="red",
                               "no3c"="darkgreen", "avgbase"="chocolate1"))   
  scale_color_manual(labels = c("Temperature", expression(NO[2]), expression(NO[3]), "Avg Baseline"),
                     values = c("temp"="cornflowerblue", "no2c"="red",
                                "no3c"="darkgreen", "avgbase"="chocolate1"),
                     breaks=c("temp","no2c","no3c","avgbase"))

Plot with legend but variables in plot do not have colour

Graph with colour but no legend

# Choose number for dividing second Y axis
scaleRight <- 40
ymax <-43

h2no2<-ggplot(h2enraw, aes(x=run))  
  geom_path(aes(y=temp, group=1), colour="cornflowerblue", size=0.9)  
  geom_point(aes(y=no2c, group=1 ),colour="red")  
  geom_point(aes(y=no3c, group=1 ),colour="darkgreen")  
  geom_line(aes(y=avgbase/scaleRight, group=1 ),colour="chocolate1", size=0.9)  
  scale_y_continuous(breaks=seq(0,40,2), expand = expansion(mult = c(0,.05)),
                     sec.axis = sec_axis(~.*scaleRight, name = "Average Baseline (Transmitance Units)"))  
  coord_cartesian(ylim = c(0, ymax))  
  theme_classic()  
  labs( y="Temperature (°C) / Concentration (ppm)", x="Run", title = "H2 - High Temperature Cycle")  
  theme(text = element_text(size=9),
        axis.text.x = element_text(angle=90, vjust=0.6),
        axis.text=element_text(size=12),
        axis.title=element_text(size=14,face="bold"),
        panel.border = element_rect(colour = "chocolate1", fill=NA, size=0.5),
        legend.position = "bottom", legend.title=element_text(size=10), legend.text = element_text(size=8),
        axis.title.y = element_text(size=10),
        plot.title = element_text(size=14, face="bold"))  
  scale_fill_manual(name="Legend",
                    breaks=c("temp","no2c","no3c","avgbase"),
                    labels=c("Temperature", "NO2", "NO3", "Avg Baseline"))

Plot with colour and no legend

Thank you so much

CodePudding user response:

Option 1

This should work for you.

I calculated a scaled version of avgbase, then I transformed your data into long-format. Because this generally helps when you want to group variables within a plot.

In ggplot(), I filter in every geom_ the specific data points I want to plot (i.e., in geom_line() I filter for temp and avgbase_scaled because I want them plotted as lines).

library(tidyverse)

h1enraw <-structure(list(run = c(1738, 1739, 1740, 1741, 1742, 1743),
                         temp = c(19, 19, 19, 19, 21, 22),
                         avgbase = c(1386, 1386, 1389, 1389, 1352, 1336),
                         no2c = c(6.98, 6.96, 6.94, 6.99, 7.01, 7.01),
                         no3c = c(18.52, 17.6, 18.77, 19.81, 18.22, 18.60)), 
                    row.names = c(NA, 6L), class = "data.frame")

scaleRight <- 40
ymax <- 43

h1enraw %>%
  mutate(avgbase_scaled = avgbase/scaleRight, .keep = "unused") %>%
  pivot_longer(c(-run), names_to = "value_type", values_to = "value") %>%
  ggplot(aes(x = run, color = value_type))  
  geom_line(data = . %>% filter(value_type %in% c("avgbase_scaled",
                                                  "temp")),
            aes(y = value), size=0.9) 
  geom_point(data = . %>% filter(value_type %in% c("no2c",
                                                  "no3c")),
            aes(y = value), size=1) 
  scale_y_continuous(breaks=seq(0,40,2), expand = expansion(mult = c(0,.05)),
                     sec.axis = sec_axis(~.*scaleRight, name = "Average Baseline (Transmitance Units)")) 
  coord_cartesian(ylim = c(0, ymax))  
  theme_classic()  
  labs( y="Temperature (°C) / Concentration (ppm)", x="Run", 
        title = "H1 - High Temperature Cycle")  
  theme(text = element_text(size=9),
        axis.text.x = element_text(angle=90, vjust=0.6),
        axis.text=element_text(size=12),
        axis.title=element_text(size=14,face="bold"),
        panel.border = element_rect(colour = "chocolate1", fill=NA, size=0.5),
        legend.position = "bottom", 
        legend.title=element_blank(), 
        legend.text = element_text(size=8),
        axis.title.y = element_text(size=10),
        plot.title = element_text(size=14, face="bold")) 
  scale_color_manual(labels = c("Temperature", expression(NO[2]), expression(NO[3]), "Avg Baseline"),
                     values = c("temp"="cornflowerblue", "no2c"="red",
                                "no3c"="darkgreen", "avgbase_scaled"="chocolate1"),
                     breaks=c("temp","no2c","no3c","avgbase_scaled"))

Created on 2022-08-30 with reprex v2.0.2

Option 2

Here an option without data transformation: You have to use the color parameter within aes() and assign the correct colnames:

scaleRight <- 40
ymax <-43

ggplot(h1enraw, aes(x=run))  
  geom_path(aes(y=temp, color="temp"), size=0.9)  
  geom_point(aes(y=no2c, color="no2c"))  
  geom_point(aes(y=no3c, color="no3c")) 
  geom_line(aes(y=avgbase/scaleRight, color="avgbase"), size=0.9)  
  scale_y_continuous(breaks=seq(0,40,2), expand = expansion(mult = c(0,.05)),
                     sec.axis = sec_axis(~.*scaleRight, name = "Average Baseline (Transmitance Units)"))  
  coord_cartesian(ylim = c(0, ymax))  
  theme_classic()  
  labs( y="Temperature (°C) / Concentration (ppm)", x="Run", 
        title = "H1 - High Temperature Cycle")  
  theme(text = element_text(size=9),
        axis.text.x = element_text(angle=90, vjust=0.6),
        axis.text = element_text(size=12),
        axis.title = element_text(size=14,face="bold"),
        legend.position = "bottom", 
        legend.title = element_blank(), 
        legend.text = element_text(size=8),
        axis.title.y = element_text(size=10),
        plot.title = element_text(size=14, face="bold")) 
  scale_color_manual(labels=c("Temperature", "NO2", "NO3", "Avg Baseline"),
                     values = c("temp"="cornflowerblue", "no2c"="red",
                                "no3c"="darkgreen", "avgbase"="chocolate1"))

Created on 2022-08-30 with reprex v2.0.2

  • Related