I am trying to add legends next to axis titles. I followed this stackoverflow answer to get the plot.
How to add legend on two y axes?. I would like
This source has an simple and easy answer. It describes the logic used by ggplot to create a legend based on assigned aes mapping, then provides a step by step solution without all this extra code. Perfect for ggplot with a second y axis, that is, plots that combine multiple geom_ or stat_summary objects into one beautifully slick graph :)
http://zevross.com/blog/2014/08/04/beautiful-plotting-in-r-a-ggplot2-cheatsheet-3/#manually-adding-legend-items-guides-override.aes
In order to make this a bit shorter I cut down your theme
definitions.
I make use of the fact that you can extract single grobs from your ggplot elements. In this case we extract 3 legends.
For the desired result we need to create 4 plots:
We make use of the function get_legend()
which is part of the package cowplot
. It lets you extract the legend of a plot.
After we extracted both legends for the left side we use arrangeGrob
to combine them and name that combined legend llegend
.
After we extracted the red legend, we us grid.arrange
to plot all three objects (llegend
, p
and rlegend
).
Concerning the orientation of the legend keys you should notice that we print the legends on top of the corresponding plots. That way we can use editGrob
to rotate the (combined) legends after extracting them and the legend keys have the correct orientation.
This is all the code:
library(ggplot2)
library(gridExtra)
library(grid)
library(cowplot)
# actual plot without legends
p <- ggplot(mapping = aes(x = plate_num, y = value, group = variable)) +
geom_line(data = subset(df1, variable %in% c('Before Treatment', 'After Treatment')), aes(color = variable), size = 1, show.legend = F) +
geom_point(data = subset(df1, variable %in% c('Before Treatment', 'After Treatment')), aes(color = variable), size = 2, show.legend = F) +
geom_line(data = subset(df1, variable %in% c('norm_ratio')), aes(color = 'Test'), col = 'red', size = 1) +
geom_point(data = subset(df1, variable %in% c('norm_ratio')), aes(color = 'Test'), col = 'red', size = 2) +
facet_wrap(~ grp) +
scale_y_continuous(sec.axis = sec_axis(trans = ~ . * (max2 / max1),
name = 'Ratio of Main Effect of Before and After Treatment\n')) +
scale_color_manual(values = c('green', 'blue'), guide = 'legend') +
theme_bw() +
theme(axis.text.x = element_text(size=11, face="bold", angle = 0, vjust = 1),
axis.title.x = element_text(size=11, face="bold"),
axis.text.y = element_text(size=11, face="bold", color = 'black'),
axis.text.y.right = element_text(size=11, face="bold", color = 'red'),
axis.title.y.right = element_text(size=11, face="bold", color = 'red', margin=margin(0,0,0,0)),
axis.title.y = element_text(size=11, face="bold", margin=margin(0,-30,0,0)),
panel.grid.minor = element_blank(),
strip.text.x = element_text(size=15, face="bold", color = "black", angle = 0),
plot.margin = unit(c(1,1,1,1), "cm")) +
ylab('Main Effect of TDP43\n\n\n') +
xlab('\nPlate Number')
# Create legend on the left
l1 <- ggplot(mapping = aes(x = plate_num, y = value, group = variable)) +
geom_line(data = subset(df1, variable %in% c('Before Treatment')), aes(color = variable), size = 1, show.legend = TRUE) +
geom_point(data = subset(df1, variable %in% c('Before Treatment')), aes(color = variable), size = 2, show.legend = TRUE) +
scale_color_manual(values = 'green', guide = 'legend') +
theme(legend.direction = 'horizontal',
legend.text = element_text(angle = 0, colour = c('green', 'blue')),
legend.position = 'top',
legend.title = element_blank(),
legend.margin = margin(0, 0, 0, 0, 'cm'),
legend.box.margin = unit(c(0, 0 , -2.5 ,0), 'cm'))
l2 <- ggplot(mapping = aes(x = plate_num, y = value, group = variable)) +
geom_line(data = subset(df1, variable %in% c('After Treatment')), aes(color = variable), size = 1, show.legend = TRUE) +
geom_point(data = subset(df1, variable %in% c('After Treatment')), aes(color = variable), size = 2, show.legend = TRUE) +
scale_color_manual(values = 'blue', guide = 'legend') +
theme(legend.direction = 'horizontal',
legend.text = element_text(angle = 0, colour = c('blue')),
legend.position = 'top',
legend.title = element_blank(),
legend.margin = margin(0, 0, 0, 0, 'cm'),
legend.box.margin = unit(c(0, 0 , -2.5 ,0), 'cm'))
legend1 <- get_legend(l1)
legend2 <- get_legend(l2)
# Combine green and blue legend
llegend <- editGrob(arrangeGrob(grobs = list(legend1, legend2),
nrow = 1, ncol = 2), vp = viewport(angle = 90))
# Plot with legend on the right
l3 <- ggplot(mapping = aes(x = plate_num, y = value, group = variable)) +
geom_line(data = subset(df1, variable %in% c('norm_ratio')), aes(color = variable), size = 1) +
geom_point(data = subset(df1, variable %in% c('norm_ratio')), aes(color = variable), size = 2) +
scale_color_manual(values = 'red', guide = 'legend') +
theme(legend.direction = 'horizontal',
legend.text = element_text(angle = 0, colour = 'red'),
legend.position = 'top',
legend.title = element_blank(),
legend.margin = margin(0, 0, 0, 0, 'cm'),
legend.box.margin = unit(c(0, 0, -3, 0), 'cm'))
# extract legend
rlegend <- editGrob(get_legend(l3), vp = viewport(angle = 270))
grid.arrange(grobs = list(llegend, p, rlegend), ncol = 3,
widths = unit(c(3, 16, 3), "cm"))