class: center, middle, inverse, title-slide .title[ # Interactive graphics ] .subtitle[ ## SISBID 2024
https://github.com/dicook/SISBID
] .author[ ### Di Cook (
dicook@monash.edu
)
Heike Hofmann (
hhhofmann4@unl.edu
)
Susan Vanderplas (
susan.vanderplas@unl.edu
) ] .date[ ### 08/14-16/2024 ] --- <style type="text/css"> /* custom.css */ .left-code { color: #777; width: 48%; height: 92%; float: left; } .right-plot { width: 50%; float: right; padding-left: 1%; } </style> # Choices of packages for interactive graphics - `crosstalk`: that's what shiny is based on - we will look into shiny later - `plotly`: has come a long way in the last years, started as part of Carson Sievert's PhD thesis research. The beauty is that it builds directly onto ggplot2 - `leaflet`: (RStudio) allows to make interactive maps. Has been picking up users and has developed a stable user base. - `ggvis`: both static and interactive graphics, work on it has stalled ... (Wickham) - `animint2`: interactive, linked graphics with ggplot2 syntax (Toby Hocking) - `rCharts`, `rbokeh`, `gridSVG`, `epivizr`, `cranvas` previous approaches to packages with interactive graphics - see also https://r-graph-gallery.com/interactive-charts.html for additional packages (more specific) --- <img src="index_files/figure-html/unnamed-chunk-6-1.png" style="display: block; margin: auto;" /> --- # plotly .left-code[ The `plotly` package in R builds on the `ggplot2` package, adding interactive elements to these plots. It translates plots to javascript. ``` r library(plotly) plot_ly(data = penguins, x = ~fl, y = ~bl, color = ~species, size = 3, width=420, height=300) ```
] .right-plot[ Or using `ggplot2` ``` r gg <- ggplot(data=penguins, aes(x = fl, y = bl, colour = species)) + geom_point(alpha=0.5) + geom_smooth(method = "lm", se=F) ggplotly(gg, width=390, height=300) ```
] --- # Scatterplot(ly) matrix .pull-left[ ``` r library(GGally) p <- ggpairs(penguins, columns = 2:5, ggplot2::aes(colour = species)) ``` ] .pull-right[ ``` r ggplotly(p, width=450, height=450) ```
] --- # Maps .pull-left[ ``` r data(canada.cities, package = "maps") viz <- ggplot(canada.cities, aes(long, lat)) + borders(regions = "canada") + coord_equal() + geom_point(aes(text = name, size = log2(pop)), colour = "red", alpha = 1/4) + theme_map() ``` Not all `ggplot2` geoms are supported in plotly, but when they are, they just work out of the box ] .pull-right[ ``` r #viz ggplotly(viz) ```
] --- # Modifying plotly `plotly` uses elements of `crosstalk` to provide additional interactivity, such as linked highlighting ``` r txh_shared <- highlight_key(txhousing, ~year) p <- ggplot(txh_shared, aes(month, median)) + geom_line(aes(group = year)) + geom_smooth(data = txhousing, method = "gam") + scale_x_continuous("", breaks=seq(1, 12, 1), labels=c("J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D")) + scale_y_continuous("Median price ('00,000)", breaks = seq(0,300000,100000), labels = seq(0,3,1)) + facet_wrap(~ city) gg <- ggplotly(p, height = 600, width = 1000) %>% plotly::layout(title = "Click on a line to highlight a year") #highlight(gg) ``` ---
--- class: inverse middle # Your turn - get the code from the previous plot to run in your RStudio session - the function `highlight` allows to make modifications in how highlighted values are presented in plotly. Read through the parameter details in `?highlight`. - the parameter `dynamic` is set to `FALSE` by default. Turn it to `TRUE`. What is the effect? --- # Animations - `gganimate` (Lin-Pederson) allows to make and save animations: [gganimate cheat sheet](https://rstudio.github.io/cheatsheets/gganimate.pdf) - Animations are different from interactive graphics in that the viewer does not have any control - useful for different important stages of a visualization (e.g. time) and to keep track of how different visualizations are related -- - can also be used in talks --- # An example animation <img src="index_files/figure-html/unnamed-chunk-13-1.gif" style="display: block; margin: auto;" /> Countries are colored manually by `country_colors` (hue shows continent, saturation is individual country) --- # How does `gganimate` work? #### Start with a ggplot2 specification -- #### Add layers with graphical primitives (geoms) -- #### Add formatting specifications -- #### Add animation specifications --- # A simple example - thanks to Mitch O'Hara Wild for the [example](https://github.com/numbats/gganimate-workshop) #### 1. Start by passing the data to ggplot .left-code[ ``` r *ggplot(economics) ``` ] .right-plot[ <img src="index_files/figure-html/plot1-1.png" style="display: block; margin: auto;" /> ] --- # A simple example - thanks to Mitch O'Hara Wild for the [example](https://github.com/numbats/gganimate-workshop) #### 2. Add the mapping .left-code[ ``` r ggplot(economics) + * aes(date, unemploy) ``` ] .right-plot[ <img src="index_files/figure-html/plot2-1.png" style="display: block; margin: auto;" /> ] --- # A simple example - thanks to Mitch O'Hara Wild for the [example](https://github.com/numbats/gganimate-workshop) #### 3. Add a graphical primitive -- let's do a line .left-code[ ``` r ggplot(economics) + aes(date, unemploy) + * geom_line() ``` ] .right-plot[ <img src="index_files/figure-html/plot3-1.png" style="display: block; margin: auto;" /> ] --- # A simple example - thanks to Mitch O'Hara Wild for the [example](https://github.com/numbats/gganimate-workshop) #### 4. Just one extra line of code turns this into an animation! .left-code[ ``` r ggplot(economics) + aes(date, unemploy) + geom_line() + * transition_reveal(date) ``` ] .right-plot[ <img src="index_files/figure-html/plot5-anim-1.gif" style="display: block; margin: auto;" /> ] --- ## A not-so-simple example, the datasaurus dozen Again, we first pass in the dataset to ggplot .left-code[ ``` r *ggplot(datasaurus_dozen) ``` ] .right-plot[ <img src="index_files/figure-html/plot5-1.png" style="display: block; margin: auto;" /> ] --- ## A not-so-simple example, the datasaurus dozen For each dataset we have x and y values, in addition we can map dataset to color .left-code[ ``` r ggplot(datasaurus_dozen) + * aes(x, y, color=dataset) ``` ] .right-plot[ <img src="index_files/figure-html/plot6-1.png" style="display: block; margin: auto;" /> ] --- ## A not-so-simple example, the datasaurus dozen Trying a simple scatter plot first, but there is too much information .left-code[ ``` r ggplot(datasaurus_dozen) + aes(x, y, color=dataset) + * geom_point() ``` ] .right-plot[ <img src="index_files/figure-html/plot7-1.png" style="display: block; margin: auto;" /> ] --- ## A not-so-simple example, the datasaurus dozen We can use facets to split up by dataset, revealing the different distributions .left-code[ ``` r ggplot(datasaurus_dozen) + aes(x, y, color=dataset) + geom_point() + * facet_wrap(~dataset) ``` ] .right-plot[ <img src="index_files/figure-html/plot8-1.png" style="display: block; margin: auto;" /> ] --- ## A not-so-simple example, the datasaurus dozen We can just as easily turn it into an animation, transitioning between dataset states! .left-code[ ``` r ggplot(datasaurus_dozen) + aes(x, y) + geom_point() + * transition_states(dataset, 3, 1) + * labs(title = "Dataset: {closest_state}") ``` ] .right-plot[ <img src="index_files/figure-html/plot9-1.gif" style="display: block; margin: auto;" /> ] --- class: inverse # Your turn The `datasaurus_dozen` data set is part of the R package `datasauRus`. - Load the gganimate package and get the animation from the previous page to run in your R session (might take a moment) - The function `transition_states` drives the animation. It has values 1 and 3. What do these values mean? Read up on their meaning and change them. --- # Controlling an animation We control plot movement with (a grammar of animation): #### Transitions: `transition_*()` defines which variable(s) should control the animation and how. -- #### Views: `view_*()` defines how the scales in x and y change during the animation (fixed? re-scale?). -- #### Shadows: `shadow_*()` defines how data from other points in time should be presented at any given point in time. -- #### Entrances/Exits: `enter_*()` and `exit_*()` define how new data should appear and how old data should disappear during the course of the animation. -- #### Easing: `ease_aes()` defines the pace of transitions. --- class: inverse middle # Your Turn The gapminder example from the beginning has the static part shown below Add animation parts! adding `transition_time(year)` results in the visualisation from the start. What other animation are helpful? What views do you want to set? Maybe a shadow looks interesting? ``` r library(gapminder) ggplot(gapminder, aes(gdpPercap, lifeExp, size = pop, colour = country)) + geom_point(alpha = 0.7) + scale_colour_manual(values = country_colors, guide=FALSE) + scale_size("Population size", range = c(2, 12), breaks=c(1*10^8, 2*10^8, 5*10^8, 10^9, 2*20^9)) + scale_x_log10() + facet_wrap(~continent) + theme(legend.position = "bottom") ``` --- # Resources - Carson Sievert [Interactive web-based data visualization with R, plotly, and shiny](https://plotly-r.com) - website for [gganimate](https://gganimate.com/) - Mitch O'Hara-Wild's [tutorial on gganimate](https://github.com/numbats/gganimate-workshop) --- # Share and share alike <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.