Beryl
Beryl

Reputation: 39

Legend only shows one layer

enter image description here

I am facing a problem with R, ggplot2. I used facet to indicate feature "gear" of my data, then for the y-axis feature, I'd like to use 2 types of legends. But my codes only shows the legend for one type(layer 1) data. * I want data2 to use colourful round dots, data1 use black * (shape=4). Please help. Thank you.

data1 <- subset(mtcars, carb==4)
data2 <- subset(mtcars, !carb==4)
ggplot(mapping = aes(x = mpg, y = wt, color= carb)) + 
  geom_point(data=data2, mapping = aes(x = mpg, y = wt, color= carb), size=0.2) + 
  facet_wrap(~ gear, nrow = 1) +
  labs(y='wt value', x= "mpg type") + 
  geom_point(data=data1, color = "black", shape=4, size=0.7, mapping=aes(x = mpg, y = wt, color= carb)) +
  facet_wrap(~ gear, nrow = 1) 

Upvotes: 2

Views: 757

Answers (2)

tjebo
tjebo

Reputation: 23747

Legends are only created for variables that appear in aes. So you need to add shape to it. There are many different ways how to change your color for a variable that fulfils one condition, and the probably easiest is what you have done, to plot different subsets. If you decide so, best practice is not to use aes within the main call, because it can mess up your plot quite a bit.

I have used a conditional statement for your shape and format the shape with scale_shape. I personally find the added difference in color unnecessary for the plot, and I would probably not have done so, but because you have asked for it - here we go.

I also transformed carb to characters - you can also transform it to a factor. Because it is a categorical variable, it makes sense to also show it as such.

edit as per comment

As usual, there are plenty of ways of achieving things. Below two different ways of changing/ removing the titles of the legends and only showing the shape and value for 4. Comments in the code.

Option 1: remove shape from the subset without '4', change legend title e.g. using labs.

library(ggplot2)

ggplot() + 
  geom_point(data = subset(mtcars, carb !=4), aes(x = mpg, y = wt, color = as.character(carb)), shape = 1) +
  geom_point(data = subset(mtcars, carb ==4), aes(x = mpg, y = wt, shape = carb  == 4), color = 'black')+
  scale_shape_manual(values = c(`TRUE` = 4, `FALSE` = 1)) +
  labs(shape = NULL, color = 'Model prediction') +
  guides(color = guide_legend(order = 1), shape = guide_legend(order = 2)) +
## I had to change the legend order, because the shape legend would draw on top otherwise. See link below! 
  facet_wrap(~ gear, nrow = 1)

Now - the legends are a bit separated, and believe me, it's quite tricky to bring them closer together.

Therefore:

option 2 Factorise your categorical data, subset your data, use drop = FALSE in the scale_color function, and change the legend aesthetic with override.aes. Sounds like a hack, but still easier and safer than trying to reduce the distance between two legends.

mtcars2 <- mtcars
mtcars2$carb2 <- factor(mtcars$carb, levels = c(1:3,6,8,4))

ggplot() + 
  geom_point(data = subset(mtcars2, carb != 4), aes(x = mpg, y = wt, color= carb2), shape = 1) +
  geom_point(data = subset(mtcars, carb == 4), aes(x = mpg, y = wt), shape = 4, color = 'black') +
  facet_wrap(~ gear, nrow = 1) +
  scale_color_discrete(drop = FALSE) +
  labs(color = 'Model prediction') +
  guides(color = guide_legend(override.aes = list(shape = c(rep(1, 5), 4),
                                                  color = c(RColorBrewer::brewer.pal(5, 'Dark2'), 'black'))))

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

Some links to learn from

Legend order is weird

change shapes in legend

Upvotes: 1

MarBlo
MarBlo

Reputation: 4524

There needs some little changes to be made. You can not use 2 facets like this. Have look to the following code. You can make carb a factor in data2 which will give you the colored points and legend. If that is what you are looking for, you will find the differences in the above mentioned points. PS: I have enlarged the point size a bit.

library(ggplot2)
data <- mtcars 
data1 <- subset(data, carb==4)
data2 <- subset(data, !carb==4)
ggplot(mapping = aes(x = mpg, y = wt, color= carb)) + 
  geom_point(data=data2, mapping = aes(x = mpg, y = wt, color= factor(carb)), size=4) + 
  geom_point(data=data1, mapping=aes(x = mpg, y = wt), shape =4, size=8, color= 'black') +
  facet_wrap(~ gear, nrow = 1) +
  theme_bw() +
  labs(y='wt value', x= "mpg type") 

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


library(ggplot2)
data <- mtcars 
data1 <- subset(data, carb==4)
data2 <- subset(data, !carb==4)
ggplot(mapping = aes(x = mpg, y = wt, color= carb)) + 
  geom_point(data=data2, mapping = aes(x = mpg, y = wt, color= factor(carb)), size=4) + 
  geom_point(data=data1, mapping=aes(x = mpg, y = wt, shape = factor(carb)),  size=8, color= 'black') +
  scale_shape_manual(values = c(4))+
  facet_wrap(~ gear, nrow = 1) +
  labs(shape = '')+
  #scale_color_discrete(guide = FALSE)+
  theme_bw() +
  labs(y='wt value', x= "mpg type") 

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

I brought the shape back into the aesthetics of data1 but then switched off the title of this by labs(shape = '') . By adding scale_shape_manual(values = c(4)) the shape is defined. Because I was not sure, if you want the first legend or not I have put #scale_color_discrete(guide = FALSE) into the code, but commented it. You may remove the commenting and will get rid of the first legend completely.

Upvotes: 2

Related Questions