Last active
January 19, 2024 15:00
-
-
Save jimjam-slam/1d988451ae15882c889f49cf20b99a64 to your computer and use it in GitHub Desktop.
How to add SVG attributes to a ggplot to assist in building interactives for the web #rstatstips
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
# gridSVG::grid.garnish can be used to add SVG attributes to elements of a plot! | |
# we don't even need to do it one at a time: with the option `group = FALSE`, we | |
# can give it a vector of values for an attribute and garnish an entire geom at | |
# once. the only rub is that sometimes ggplot2 shuffles your data around when | |
# plotting it. we need to check how the data was reordered, and arrange our | |
# original data to match, before we send it to grid.garnish. | |
library(tidyverse) | |
library(magrittr) | |
library(grid) | |
library(gridExtra) | |
library(gridSVG) | |
select = dplyr::select | |
filter = dplyr::filter | |
# step 1: create the plot. i've left out the analysis code here, but i have | |
# a data frame, `mts_data`, with the columns `year`, `count` and `anomaly`. | |
hb_theme = theme( | |
panel.grid.major.x = element_blank(), | |
panel.grid.minor.x = element_blank(), | |
panel.grid.minor.y = element_blank(), | |
panel.grid.major.y = element_line(colour = "#666666"), | |
axis.title.x = element_text(colour = 'white', margin = margin(t = 9)), | |
axis.text = element_text(colour = "#666666"), | |
plot.subtitle = element_text(colour = '#666666'), | |
plot.title = element_text(colour = '#999999')) | |
mts_barplot = ggplot(mts_data) + | |
geom_col( | |
aes(x = year, y = anomaly), | |
fill = 'white', colour = NA, show.legend = FALSE) + | |
theme_minimal(base_family = 'Oswald', base_size = 14) + | |
hb_theme + | |
labs( | |
x = 'YEAR', | |
y = NULL, | |
title = 'AUSTRALIAN AVERAGE NIGHTS OVER 20 °C EACH YEAR', | |
subtitle = 'RELATIVE TO THE 1940–2013 AVERAGE (101.65 PER YEAR)') | |
# step 2: sort the data frame by the order in which ggplot2 plots them. | |
# occasionally ggplot2 reorders data during plotting (eg. here it plots ngative bars first, | |
# then positive ones). since this is the order the grid elements appear, any data we pass | |
# to grid.garnish needs to match it! | |
# nb: this data frame uses the names of the aesthetics for columns, not the names of the source | |
# columns | |
plotted_data = | |
ggplot_build(mts_barplot)$data %>% | |
# nb: if you have multiple geoms, you might need to group them first! | |
mutate(plot_order = 1:nrow(.)) %>% | |
select(plot_order, x, y) | |
mts_data %<>% | |
inner_join(plotted_data, by = c("year" = "x", "anomaly" = "y") %>% | |
arrange(plot_order) | |
# step 3: send the plot to the graphics device, add your extra SVG info to it, and export | |
barplot_grob = mts_barplot %>% ggplotGrob() %>% grid.force() | |
dev.new(width = 8, height = 4.5, units = 'in') | |
grid.draw(barplot_grob) | |
# grid.garnish needs a handle | |
grid.garnish('geom_rect', | |
'class' = paste0('chart_bar_', if_else(mts_data$anomaly > 0, 'pos', 'neg')), | |
'data-year' = mts_data$year, | |
'data-count' = mts_data$count, | |
'data-anomaly' = mts_data$anomaly, | |
group = FALSE, grep = TRUE, redraw = TRUE) | |
grid.export('garnish_barchart.svg', strict = FALSE) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment