Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I show legend of multiple layers (geom_point and geom_bar)?

I have two data sets that I want to combine into one plot, one as a barplot (2 groups) and one as a point-line plot (1 group). I’ve managed to combine the plots and show the legend for the barplot, but whenever I try to show the legend for the points/line it doesn’t work.

Here is an excerpt of my data sets (translated):

bargroup <- data.frame('Year' = as.numeric(rep(2001:2004, each = 2)),
                     'Group' = as.factor(rep(c('State', 'Country'), 4)),
                     'Share' = as.numeric(c(0.42, 0.41, 0.4, 0.4, 0.42, 0.4, 0.42, 0.38)))

plgroup <- data.frame('Year' = as.numeric(2001:2004),
                             'Group' = as.factor(rep('State', 4)),
                             'Value' = as.numeric(c(4.95, 5.31, 5.29, 4.96)))

Here’s my current code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

ggplot() +
geom_bar(data = bargroup, aes(x = Year, y = Share, fill = Group, group = Group),
           stat = 'identity', position = position_dodge2(preserve = 'single')) +
  geom_point(data = plgroup, aes(y = Value*0.1, x = Year), size = 4, color = '#875DA3') +
  geom_line(data = plgroup, aes(y = Value*0.1, x = Year), size = 1, color = '#875DA3') +
  labs(x = 'Year') +
  scale_y_continuous(name = 'Share groups', labels = scales::percent,
                     sec.axis = sec_axis(~.*10, name = 'Cost')) +
  scale_fill_manual(labels = c('Share State', 'Share Country'), 
                    values = c('#659B7A', '#8CD7F0')) +
  scale_color_manual(labels = c('Total Cost'), 
                values = c('#875DA3')) +
  theme_minimal() +
  theme(legend.title = element_blank(),
        legend.position = 'bottom',
        plot.title = element_blank(),
        panel.grid.minor = element_blank(),
        axis.title.x = element_text(size = 18),
        axis.title.y = element_text(size = 18),
        axis.text = element_text(size = 16),
        legend.text = element_text(size = 18)) +
  guides(fill = guide_legend(nrow = 2, byrow = T))
dev.off()

This is the graph I get:

Graph 1

As you can see, the point/line group is not displayed in the legend. I then tried removing the argument scale_color_manual() and adjusting the geom_point() and geom_line() arguments like so:

  geom_point(data = plgroup, aes(y = Value*0.1, x = Year, color = Group), 
             size = 4, color = '#875DA3', show.legend = T)
  geom_line(data = plgroup, aes(y = Value*0.1, x = Year, color = Group),
            size = 1, color = '#875DA3', show.legend = T)

The graph I got from this was:

Graph 2

I got that same graph when I combined the two data sets using the melt() function.

I also tried just making 3 groups out of it and not showing the point/line group. That showed all 3 groups but unfortunately the point/line group was now – obviously – labeled with a square instead of its point/line symbol (in the legend).

Does anyone have any idea how I can adjust my code to show the point/line group as a single bullet point next to or below the other two groups? Preferably also with the option to pick the label name (‘Total Cost’).

Thank you so much in advance!

>Solution :

Rule of thumb: everything within aes() will produce a legend. So put size out of aes() AND color into aes():

ggplot() +
  geom_bar(data = bargroup, aes(x = Year, y = Share, fill = Group, group = Group),
           stat = 'identity', position = position_dodge2(preserve = 'single')) +
  geom_point(data = plgroup, aes(y = Value*0.1, x = Year, color = '#875DA3'),size = 4) +
  geom_line(data = plgroup, aes(y = Value*0.1, x = Year, color = '#875DA3'),size = 1) +
  labs(x = 'Year') +
  scale_y_continuous(name = 'Share groups', labels = scales::percent,
                     sec.axis = sec_axis(~.*10, name = 'Cost')) +
  scale_fill_manual(labels = c('Share State', 'Share Country'), 
                    values = c('#659B7A', '#8CD7F0')) +
  scale_color_manual(labels = c('Total Cost'), 
                     values = c('#875DA3')) +
  theme_minimal() +
  theme(legend.title = element_blank(),
        legend.position = 'bottom',
        plot.title = element_blank(),
        panel.grid.minor = element_blank(),
        axis.title.x = element_text(size = 18),
        axis.title.y = element_text(size = 18),
        axis.text = element_text(size = 16),
        legend.text = element_text(size = 18)) +
  guides(fill = guide_legend(nrow = 2, byrow = T))

enter image description here

Changing the order of legend:

guides(fill = guide_legend(nrow = 2, byrow = T, order=1))

enter image description here

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading