2

I've created a ggplot2 graph using the basic code below:

my_df %>% 
 ggplot(aes(conv_norm, vot_norm, color = language:poa)) + 
 geom_smooth(method = "glm", se=FALSE) + 
 theme(
 ...
 )

[I've left out the formatting commands from the theme() layer]

And I got a graph that looks like this: enter image description here

Now, my question is: how can I add extra space only in between two legend items? I've looked online and have found ways to increase the spacing between all items in the legend, but I only want extra spacing between the English items and the Spanish items. Is there a way to add a 1-in distance between these language groups?

asked Apr 10, 2021 at 3:55
1

2 Answers 2

2

Well, I don't know of an elegant, simple solution to do what you are asking to do... but by working with how legends are drawn and adjusting some of the elements, we can come up with a really "hacky" solution. ;)

Here's a sample dataset that kind of simulates what you shared, along with the plot:

set.seed(12345)
my_df <- data.frame(
 lang = rep(c(paste('English',1:3), paste('Spanish',1:3)),2),
 x = c(rep(0,6), rep(1,6)),
 y = rnorm(12, 10,2))
library(ggplot2)
p <- ggplot(my_df, aes(x,y, color=lang)) + geom_line()
p

enter image description here

The approach here is going to be to combine all the following individual steps:

  • Add a "blank" legend entry. We do this by refactoring and specifying the levels of the column mydf$lang to include a blank entry in the correct position. This will be the final order of the items in the legend.

  • Use scale_color_manual() to set the colors of the legend items manually. I make sure to use "NA" for the blank entry.

  • Within scale_color_manual() I use the drop=FALSE setting. This includes all levels for a factor, even if there is no data on the plot to show. This makes our blank entry show on the legend.

  • Use the legend.background theme element to draw transparent boxes for the legend key items. This is so that you don't have a white or gray box for that blank entry.

Putting it all together you get this:

my_df$lang <- factor(my_df$lang, levels=c(paste('English',1:3), '', paste('Spanish',1:3)))
ggplot(my_df, aes(x,y, color=lang)) +
 geom_line() +
 scale_color_manual(
 values=c(rainbow(6)[1:3], 'NA', rainbow(6)[4:6]),
 drop=FALSE) +
 theme( legend.key = element_rect(fill='NA') )

enter image description here

Alternatively, you could use guides(color=guide_legend(override.aes... to set the colors, but you need the drop=FALSE part within scale_color_manual() get the blank level to draw in the legend anyway.

answered Apr 11, 2021 at 12:51
Sign up to request clarification or add additional context in comments.

Comments

2

Another option would be to create two separate legends. Either by using two different aesthetics, or you can use color twice, e.g with ggnewscale - thanks to user chemdork123 for the fake data +1.

library(tidyverse)
library(ggnewscale)
set.seed(12345)
my_df <- data.frame(
 lang = rep(c(paste('English',1:3), paste('Spanish',1:3)),2),
 x = c(rep(0,6), rep(1,6)),
 y = rnorm(12, 10,2))
ggplot(mapping = aes(x,y)) +
 geom_line(data = filter(my_df, grepl("English", lang)), aes(color=lang)) +
 scale_color_brewer(NULL, palette = "Dark2") +
 new_scale_colour() +
 geom_line(data = filter(my_df, grepl("Spanish", lang)), aes(color=lang)) +
 scale_color_brewer(palette = "Set1") +
 guides(color = guide_legend(order = 1))

Created on 2021年04月11日 by the reprex package (v1.0.0)

answered Apr 11, 2021 at 17:04

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.