Animated interactive ggplots - rstats-gsoc/gsoc2018 GitHub Wiki
Animint is an R package for making interactive animated data visualizations on the web, using ggplot syntax and two new keywords:
- showSelected=variable means that only the subset of the data that corresponds to the selected value of variable will be shown.
- clickSelects=variable means that clicking a plot element will change the currently selected value of variable.
Toby Dylan Hocking initiated the project in 2013, and Susan VanderPlas (2013), Carson Sievert (2014), Tony Tsai (2015), Kevin Ferris (2015), and Faizan Khan (2016-2017) have provided important contributions during previous GSOC projects.
Animint2 is a re-write of animint, intended to be easier to install and put on CRAN (which is the goal of this GSOC project).
Standard R graphics are based on the pen and paper model, which makes animations and interactivity difficult to accomplish. Some existing packages that provide interactivity and/or animation are
- Non-interactive animations can be accomplished with the animation package (animint provides interactions other than moving forward/back in time).
- Some interactions with non-animated linked plots can be done with the qtbase, qtpaint, and cranvas packages (animint provides animation and showSelected).
- Linked plots in the web are possible using SVGAnnotation or gridSVG but using these to create such a visualization requires knowledge of Javascript (animint designers write only R/ggplot2 code).
- The svgmaps package defines interactivity (hrefs, tooltips) in R code using igeoms, and exports SVG plots using gridSVG, but does not support showing/hiding data subsets (animint does).
- The ggvis package defines a grammar of interactive graphics that relies on shiny’s reactivity model for most of its interactive capabilities (animint does not need a shiny server).
- Vega can be used for describing plots in Javascript, but does not implement clickSelects/showSelected (animint does).
- RIGHT and DC implement interactive plots for some specific plot types (animint uses the multi-layered grammar of graphics so is not limited to pre-defined plot types).
For even more related work see the Graphics and Web technologies task views on CRAN, and Visualization design resources from the UBC InfoVis Group.
Currently animint2 depends on faizan-khan-iit/ggplot2@validate-params,
which is a fork of ggplot2 (the forked pacakge was re-named
ggplot2Animint) with a few modifications necessary for defining
interactive ggplots. However there is a major issue that needs to be
fixed: S3 methods for ggplot
objects defined in the standard
ggplot2
package conflict with the objects/methods used for
animint. The goal of this GSOC project is to fix this and clean up
animint2 in preparation for a CRAN submission:
- copy all the code from Faizan’s ggplot2 fork into a new branch of animint2, so we only need to submit/maintain animint2 on CRAN (rather than both ggplot2Animint and animint2).
- change
ggplot
function toa_plot
and change the class/method names as well, so that the newaplot
objects/methods do not conflict with ggplot2. - change functions such as
geom_point
toa_geom_point
– the prefixeda_
is for easy tab completion for all animint2 functions. - Run R CMD check –as-cran and eliminate all ERRORs and WARNINGs, then submit to CRAN at the end of GSOC.
An ideal student project also will implement several new features to Animint, and also write some tests and documentation (vignette, web page, blog). Some important items from the TODO list:
- object-oriented implementation of geoms – currently they are implemented with a lot of conditional code (if geom is point then, else if geom is rect then, etc). Move that code to a new method (e.g. animint_compile) in the geom object definition, so the code is easier to understand and maintain.
- Upgrade to d3.js version 4, which makes data join easier. The new
merge
function allows combining the ENTER and UPDATE selections, which reduces duplication and can make animint.js code easier to understand, as explained in this article. - htmlwidgets/crosstalk support – see how Carson did this with plotly.
- New aesthetics that only make sense on the web/SVG (not in ggplot2), for example an aesthetic for stroke-opacity and fill-opacity.
- Support for multiple clickSelects aesthetics per geom.
- Currently, selected items in Animint are shown with a black border outline stroke for rectangles, and with 0.5 more alpha transparency for all other geoms. This should be configurable using new aesthetics such as selected.color, selected.alpha, etc.
- introduce dependency on data.table, so that data visualizations with large data sets can be compiled faster.
- New hoverSelects aesthetic which updates the selection just by hovering the mouse over an element, including tests that simulate mouseover/mouseout events.
- Last year Faizan implemented updating of axes/legends after changing the currently displayed data subset. Currently the computations are done in the compiler but there are some limitations (ask @faizan-khan-iit), so it would be preferable to move the computations to the renderer.
- Compute stats based on the current subset, e.g. total homicides, maybe animint syntax like this.
Any other ideas for improving Animint are welcome as well!
The best source of documentation for the original animint is the Animint Designer Manual. The source code is in tdhock/animint-book.
However there is no equivalent reference for animint2. This GSOC project would be to translate the Animint Designer Manual to animint2 code, and create additional chapters to further document animint2 usage. For ideas for additional chapters you can look in animint2/tests/testthat which is our set of test cases.
Animint already provides useRs with some unique features for interactive data visualization. At the end of GSOC, the animint2 package will be more portable, and perhaps have even more features, tests, and documentation.
YES. If you don’t know JavaScript then I suggest you read some tutorials, e.g. Mozilla JavaScript basics, W3Schools, mbostock’s blocks examples.
Please get in touch with Toby Dylan Hocking <[email protected]> and Faizan Khan <[email protected]> after completing at least one of the tests below.
Do one or several — doing more hard tests makes you more likely to be selected.
- Easy: use animint2 to visualize some data from your domain of
expertise, and upload your visualization to the web using
animint2gist
. Show an example of an error that you see when animint2 is loaded/attached at the same time as standard ggplot2. - Medium: translate an example of the animation package into an
Animint. Do not do one of the examples that has already been
ported. Post a link to your result on the Ports of animation
examples page on the Animint wiki.
- look at source code of one of the animation package functions e.g. grad.desc() for a demonstration of the gradient descent algorithm. Translate the for loops and plot() calls into code that generates data.frames. In the grad.desc() example, there should be one data.frame for the contour lines, one for the arrows, and one for the values of the objective/gradient at each iteration.
- Use the data.frames to make some ggplots. In the grad.desc()
example, there should be one ggplot with a
geom_contour
and ageom_path
, and another ggplot with ageom_line
that shows objective or gradient value versus iteration, and ageom_tallrect
in the background for selecting the iteration number. - Make a list of ggplots and pass that to animint2dir. For the grad.desc() example the plot list should be something like list(contour=ggplot(), objective=ggplot(), time=list(variable=”iteration”, ms=2000)).
- Hard: write a testthat unit test based on one of your Animint visualizations. Fork animint and add a renderer test (using animint2HTML) to tests/testthat/test-renderer3-YOUR-TEST.R, then send us a Pull Request.
- Students, please post a link to your test results here.
- Easy test: Gapminder world poster with animint / Source code
- Proposed test: How French voted with animint2 / Source code
- Easy Test Result: pseudo facebook data mapping (jitter) with animnint
- Source Code: Click Here