Is there a more efficient way to fix the legend title in this ggplot2 plot?

Hello.

Below is a reproducible example similar to what I'm doing with another data set. Notice at the very end I use guide_legend() twice to fix the legend title since I'm using both fill and color scales. Is there a more efficient way to do that?

Thanks in advance!

# load some sample data
data(iris)

# fit a silly model with interaction
m <- lm(Sepal.Length ~ Sepal.Width * Species, data = iris)

# Create data for effect plot to visualize interaction
library(ggeffects) 
eff_out <- ggpredict(m, terms = c("Sepal.Width", "Species"))

# create effect plot using eff_out
ggplot(eff_out, aes(x = x, y = predicted, color = group)) +
  geom_line() +
  geom_ribbon(aes(ymin = conf.low, ymax = conf.high, fill = group), 
              alpha = 1/5) +
  scale_x_continuous("Sepal Width") +
  scale_y_continuous("Sepal Length") +
  guides(fill = guide_legend(title="Species"), 
         color = guide_legend(title="Species")) 

try

gg <- 
ggplot(eff_out, aes(x = x, y = predicted, color = group)) +
  geom_line() +
  geom_ribbon(aes(ymin = conf.low, ymax = conf.high, fill = group), 
              alpha = 1/5) +
  scale_x_continuous("Sepal Width") +
  scale_y_continuous("Sepal Length") +
  guides(fill = guide_legend(title="Species"), 
         color = guide_legend(title="Species")) 

gg + labs(col = "The New Legend Title")

Thank you, but I was hoping to use less code, not more. :grinning: It seems like there should be a way to update the legend title without having to do it twice. For example, if I just do the following...

 guides(fill = guide_legend(title="Species")) 

...that results in two legends.

Likewise, the following results in two legends being created:

ggplot(eff_out, aes(x = x, y = predicted, color = group)) +
  geom_line() +
  geom_ribbon(aes(ymin = conf.low, ymax = conf.high, fill = group), 
              alpha = 1/5) +
  scale_x_continuous("Sepal Width") +
  scale_y_continuous("Sepal Length") +
  scale_color_discrete("Species")

To prevent that, the only thing I have figured out to do is to update both scales:

ggplot(eff_out, aes(x = x, y = predicted, color = group)) +
  geom_line() +
  geom_ribbon(aes(ymin = conf.low, ymax = conf.high, fill = group), 
              alpha = 1/5) +
  scale_x_continuous("Sepal Width") +
  scale_y_continuous("Sepal Length") +
  scale_color_discrete("Species") +
  scale_fill_discrete("Species")

Or using guide_legend() twice.

You could rename the column in the data frame produced by ggpredict. I've also switched to the labs function for axis titles.

library(tidyverse)
library(ggeffects) 

# fit a silly model with interaction
m <- lm(Sepal.Length ~ Sepal.Width * Species, data = iris)

eff_out <- ggpredict(m, terms = c("Sepal.Width", "Species")) %>% 
  rename(Species=group)

# create effect plot using eff_out
ggplot(eff_out, aes(x = x, y = predicted, color = Species)) +
  geom_line() +
  geom_ribbon(aes(ymin = conf.low, ymax = conf.high, fill = Species), 
              alpha = 1/5) +
  labs(x="Sepal Width", y="Sepal Length")

Created on 2020-02-18 by the reprex package (v0.3.0)

3 Likes

(facepalm) What an obvious solution. Thank you! That's perfect.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.