chirunconf / chirunconf19

Discussion of potential projects for Chicago R Unconference, March 9-10, 2019
16 stars 2 forks source link

Incremental graphs in ggplot2 #24

Open weiyangtham opened 5 years ago

weiyangtham commented 5 years ago

I am a fan of showing graphs layer by layer in slideshows. I find that my workflow ends up being something like

  1. Make the final version of the graph that I want
  2. Deconstruct the graph into the desired increments

This ends up involving a lot of copying and pasting. It's not the worst thing since ggplot syntax fits well with the layering idea, but I have found it to be enough work that I don't always do it. I've thought it would be nice to have some functions that can take a plot and show you just the parts you want. Roughly,

p = ggplot(mtcars, aes(mpg, wt)) + geom_point()
show_x_axis(p) # only shows x-axis
show_one_point(p) # only show one point so you can explain it
maurolepore commented 5 years ago

Sounds cool! Have you thought about how to implement it? My first (and only idea) would be to edit the final call to the ggplot with the rlang package by @lionel- et al.

wlandau commented 5 years ago

Yeah, this sounds awesome! Such a natural consequence of ggplot2's layering paradigm.

In fact, ggplot2 objects already have a layers element.

library(ggplot2)
pl <- ggplot(mtcars) +
  geom_line(aes(x = wt, y = mpg)) +
  ggtitle("mpg vs wt") +
  geom_point(aes(x = wt, y = mpg, color = as.factor(cyl))) +
  ggtitle("mpg vs wt with line")

pl


pl$layers
#> [[1]]
#> mapping: x = ~wt, y = ~mpg 
#> geom_line: na.rm = FALSE
#> stat_identity: na.rm = FALSE
#> position_identity 
#> 
#> [[2]]
#> mapping: x = ~wt, y = ~mpg, colour = ~as.factor(cyl) 
#> geom_point: na.rm = FALSE
#> stat_identity: na.rm = FALSE
#> position_identity

# Remove a layer.
pl$layers <- pl$layers[-1]

pl

Created on 2019-03-07 by the reprex package (v0.2.1)

But that's not what we want because both frames have "with line" in the title. Hence, @maurolepore's idea of computing on the language. A couple more ideas:

  1. Walk the abstract syntax tree (AST), discover + signs, and make a new increment for each one.
  2. Define increments manually, which would still require walking the AST to discover calls to increment().
pl <- ggplot(mtcars) +
  geom_line(aes(x = wt, y = mpg)) +
  ggtitle("mpg vs wt") +
  increment() +
  geom_point(aes(x = wt, y = mpg, color = as.factor(cyl))) +
  ggtitle("mpg vs wt with line") +
  increment()