Last active
August 18, 2016 09:03
-
-
Save tchakravarty/d4ead37873dbf356df1ce2954e3d3f8d to your computer and use it in GitHub Desktop.
Dual Y-Axis ggplot2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(ggplot2) | |
library(grid) | |
library(tidyr) | |
library(gtable) | |
library(dplyr) | |
gg_foo3_colors = c("#F8766D", "#00BFC4") | |
df_foo = read.csv(text = ",Russia,World | |
1996,0,423 | |
1997,4,220 | |
1998,1,221 | |
1999,0,298 | |
2000,0,322 | |
2001,8,530 | |
2002,6,466 | |
2003,17,459 | |
2004,25,562 | |
2005,27,664 | |
2006,33,760 | |
2007,53,893 | |
2008,87,1038 | |
2009,32,761 | |
2010,62,949 | |
2011,101,1109 | |
2012,96,1130 | |
2013,110,1317 | |
2014,111,1535 | |
2015,88,1738") %>% | |
gather(key = Country, value = Value, -X) %>% | |
rename(Year = X) | |
#========================================================== | |
# create the individual plots | |
#========================================================== | |
#================================================ | |
# Russia | |
#================================================ | |
gg_russia = df_foo %>% | |
filter(Country == "Russia") %>% | |
ggplot(aes(x = Year, y = Value)) + | |
geom_line(color = gg_foo3_colors[[1]], size = 1.5) + | |
labs(x = NULL, y = NULL) + | |
# ggtitle("Russia") + | |
scale_x_continuous(breaks = c(1996, seq(2000, 2015, 5))) + | |
scale_y_continuous(expand = c(0, 0), limits = c(-0.9, 200.9)) + | |
theme_bw() + | |
theme( | |
# panel related theme elements | |
panel.border = element_blank(), | |
panel.background = element_blank(), | |
panel.grid.minor = element_blank(), | |
panel.grid.major = element_line(color = "gray50", size = 0.5), | |
panel.grid.major.x = element_blank(), | |
# axis text | |
axis.text.y = element_text(color = gg_foo3_colors[[1]], size = 12), | |
axis.text.x = element_text(size = 12), | |
# axis ticks | |
axis.ticks.x = element_line(), | |
axis.ticks.y = element_line(), | |
# axis ticks | |
axis.ticks = element_line(colour = "gray50"), | |
axis.ticks.length = unit(x = 0.25, units = "cm"), | |
axis.ticks.y = element_blank(), | |
# title | |
plot.title = element_text(hjust = 0.85, vjust = 2.12, color = gg_foo3_colors[[1]], size = 12) | |
) | |
# plot it | |
# gg_russia | |
#================================================ | |
# Rest of the world | |
#================================================ | |
gg_world = df_foo %>% | |
filter(Country == "World") %>% | |
ggplot(aes(x = Year, y = Value)) + | |
geom_line(color = gg_foo3_colors[[2]], size = 1.5) + | |
labs(x = NULL, y = NULL) + | |
# ggtitle("Rest of the World") + | |
scale_x_continuous(breaks = c(1996, seq(2000, 2015, 5))) + | |
scale_y_continuous(expand = c(0, 0), limits = c(-0.9, 2000.9)) + | |
theme_bw() + | |
theme( | |
# panel related theme elements | |
panel.border = element_blank(), | |
panel.background = element_blank(), | |
panel.grid.minor = element_blank(), | |
panel.grid.major = element_line(color = "gray50", size = 0.5), | |
panel.grid.major.x = element_blank(), | |
# axis text | |
axis.text.y = element_text(color = gg_foo3_colors[[2]], size = 12), | |
axis.text.x = element_text(size = 12), | |
# axis ticks | |
axis.ticks.x = element_line(), | |
axis.ticks.y = element_line(), | |
# axis ticks | |
axis.ticks = element_line(colour = "gray50"), | |
axis.ticks.length = unit(x = 0.25, units = "cm"), | |
axis.ticks.y = element_blank(), | |
# title | |
plot.title = element_text(hjust = -0.0135, vjust = 2.12, color = gg_foo3_colors[[2]], size = 12) | |
) | |
# plot it | |
# gg_world | |
#========================================================== | |
# combine the two plots | |
#========================================================== | |
# first override the titles | |
gg_russia = gg_russia | |
gg_world = gg_world | |
# then convert them to grobs | |
grob_russia = ggplotGrob(gg_russia) | |
grob_world = ggplotGrob(gg_world) | |
# 1. get the locations of the plot panels in the first plot | |
grob_panel_all = c(subset(ggplotGrob(gg_russia)$layout, name == "panel", se = t:r)) | |
grob_russia = gtable_add_grob( | |
x = grob_russia, | |
grobs = grob_world$grobs[[which(grob_world$layout$name == "panel")]], | |
t = grob_panel_all$t, | |
l = grob_panel_all$l, | |
b = grob_panel_all$b, | |
r = grob_panel_all$l | |
) | |
# source the function that switches the grob orientation | |
source("https://raw.githubusercontent.com/wilkelab/cowplot/master/R/switch_axis.R") | |
# 2. get the y-axis from gg_world | |
yaxis = grob_world$grobs[[which(grob_world$layout$name == "axis-l")]] | |
# 3. reverse the ticks (tick marks, axis line and the tick labels) of the second y-axis | |
ticks.y = yaxis$children[[2]] | |
ticks.y$widths = rev(ticks.y$widths) | |
ticks.y$grobs = rev(ticks.y$grobs) | |
# 4. change the tick marks | |
# NOTE: not clear what has happened here | |
tml = plot_theme(gg_russia)$axis.ticks.length | |
ticks.y$grobs[[1]]$x = ticks.y$grobs[[1]]$x - unit(1, "npc") + tml | |
# 5. swap margins and fix justifications for the tick mark labels | |
ticks.y$grobs[[2]] = hinvert_title_grob(ticks.y$grobs[[2]]) | |
# 6. put ticks back into the y-axis | |
yaxis$children[[2]] = ticks.y | |
# 7. put the transformed y-axis on the right side of grob_russia | |
grob_russia = gtable_add_cols( | |
grob_russia, | |
grob_world$widths[grob_world$layout[which(grob_world$layout$name == "axis-l"), ]$l], | |
grob_panel_all$r | |
) | |
# add the other y-axis to the plot | |
grob_russia = gtable_add_grob( | |
grob_russia, | |
yaxis, | |
grob_panel_all$t, | |
grob_panel_all$r + 1, | |
grob_panel_all$b, | |
grob_panel_all$r + 1, | |
clip = "off", | |
name = "axis-r" | |
) | |
# 8. create the labels for the top of the plot | |
left = textGrob( | |
"Russia", | |
x = 0, | |
y = 0.9, | |
just = c("left", "top"), | |
gp = gpar(fontsize = 12, col = gg_foo3_colors[[1]]) | |
) | |
right = textGrob( | |
"Rest of the World", | |
x = 1, | |
y = 0.9, | |
just = c("right", "top"), | |
gp = gpar(fontsize = 12, col = gg_foo3_colors[[2]]) | |
) | |
# put them together | |
labs = gTree("Labs", children = gList(left, right)) | |
# 9. new row in the plot for the labels | |
height = unit(3, "grobheight", left) | |
gg_russia = gtable_add_rows(grob_russia, height, 2) | |
# put the label in the new row | |
grob_russia = gtable_add_grob(grob_russia, labs, t = 3, l = 3, r = 5) | |
grob_russia$layout[which(grob_russia$layout$name == "panel"), ]$clip = "off" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment