Shape morphism for data visualization
Shape morphism is the art of transitioning between 2 shapes as smoothly as possible. This post explores how it can be useful for data visualization and how it can be done using React
, d3.js
, react-spring
and flubber
.
This post is about shape morphism, which means animating the properties that define the actual shape of the elements.
As always when talking about animation, it is good to recall this citation by Josh Comeau:
Animation is like salt: too much of it spoils the dish
Examples
Here is a list of nifty viz examples using shape morphism to transition between several viz types
- Try to empeach this: choropleth to bubble map transition by Karim Douïeb
- d3.js show reel: several chart transition to showcase d3.js possibilities by Mike Bostock
- Choropleth to bubble plot transition, the the Spiegel
- Choropleth to scatterplot transition with scrolly-telling. By Maarten Lambrechts for the Pudding.
- Choropleth to circle pack, made with R by David Zumbach
Why
In the field of data visualization shape morphism is mostly usefull to transition between 2 chart types. It is pretty hard to implement that kind of smooth transition so why should we even care?
- Eye catching effect
- Highlight the direct relationship between 2 charts. During the transition one can follow a specific item and understand it's the same.
- Make sure that we're looking at the same dataset, but represented differently
What are we trying to do
Sometimes in dataviz we want to transition between 2 chart types, let's say between a pie chart and a barplot. This is pretty hard since the shapes used for those 2 charts are very different: arc versus rectangle.
This is still possible thanks to a few libraries. This post suggests to use d3.js
to build the start and end svg path, flubber
to interpolate those path, react-spring
for the animation and react
for the rendering.
This is the kind of thing we're gonna learn to build:
Shape morphism on the web: a review
I knew nothing about shape morphism 3 weeks ago. It took me a lot of effort to browse the web and find what the most appropriate tools are. To avoid you the hassle, here is a quick summary:
SMIL
(Synchronized Multimedia Integration Language) is a feature introduced in firefox 4, allowing to follow a motion path. Basically it means you can use ananimate
element in your svg that will support shape morphism.
Unfortunately, this feature is probably get deprecated soon. Furthermore, it supports transition only between shapes with the same number of nodes.
DocCodePen.- pure
CSS
: Chrome has started to allow shape morphing through css. You can simply change thed
attribute of apath
in a css file and add sometransition
to it. But chrome only and same number of nodes only.
CodePen greenSock MorphSvg plugin
: a promising javascript library for shape morphism, widely cited on the internet. Supports shapes with different number of nodes. But it's not free and not open source.
WebsiteCodePensuperformula
is a mathematic formula that can be used to describe many complex shapes. Using 6 numbers as parameters, this formula can build many complex shapes. Interpolating between 2 shapes becomes easy: we just have to interpolate those numbers. Problem: it does not work with any shape and building a chart from this formula is thus impossible.
Exampled3-interpolate
is a d3 module that provides a variety of interpolation methods. It works for paths, even with different number of nodes. But when the shape 2 has more nodes than shape 1 it just adds some nodes to the end of the shape 1 path. This result in a bad visual effect.
Docd3-interpolate-path
is an open-source js library that adds an interpolator optimized for SVGpath
elements. It works very well for path including segments only, but from my experience less well for arcs.
DocDemoVizzu
is a library for animated data visualizations and data stories. It looks very promising for transition between chart types. But since it is a library, it means that customization is limited to the offered options.
DocDemo
None of the item of this list suits my need. We need an open source library capable of interpolating any path, even with different number of nodes..
Shape interpolation with flubber
flubber is an open source javascript library built by Noah Veltman. Unlike most of the shape morphism libraries it works very well to interpolate shapes that are completely different and don't have the same number of nodes.
Let's start by creating 2 svg shapes
const shape1 = "M10,140 L50,60 L90,140 Z"; // triangle
const shape2 = "M350,50 L400,83 L400,116 L350,150 L300,116 L300,83"; // polygon
It's very straightforward to interpolate a y between the 2 of them thanks to the interpolate()
function offlubber
. This function expects 2 arguments: the starting shape and the ending shape:
const interpolator = interpolate(shape1, shape2);
interpolate()
returns a function. This function accepts only 1 argument: a value between 0 (start) and 1 (end). It will return the interpolated shape for this progress.
interpolator(0.2)
// M110,58L113.25,62.825L116.5,67.65L119.75,72.475L123,77.3L126.25,82.125L129.5,86.95L.......Z
Here is a visualization of the final result
Switching from a triangle to a polygon using flubber for shape interpolation
Awesome video by the Flubber creator: link
Animating the transition with react spring
Now that we know how to build an interpolated shape between a starting and an ending point, let's animated this transition using react-spring
.
The transition is now animated thanks to react-spring, a react library for spring animation.
Pie chart to barplot transition
I knew nothing about shape morphism 3 weeks ago. It took me a lot of effort to browse the web and find what the most appropriate tools are. To avoid you the hassle, here is a quick summary:
Violin to boxplot transition
I knew nothing about shape morphism 3 weeks ago. It took me a lot of effort to browse the web and find what the most appropriate tools are. To avoid you the hassle, here is a quick summary:
How to smoothly transition between a boxplot and a violin plot. Math by d3.js, rendering using react, animation using react-spring and interpolation using flubber.
Part Of A Whole
Contact
👋 Hey, I'm Yan and I'm currently working on this project!
Feedback is welcome ❤️. You can fill an issue on Github, drop me a message on Twitter, or even send me an email pasting yan.holtz.data
with gmail.com
. You can also subscribe to the newsletter to know when I publish more content!
Contact
👋 Hey, I'm Yan and I'm currently working on this project!
Feedback is welcome ❤️. You can fill an issue on Github, drop me a message on Twitter, or even send me an email pasting yan.holtz.data
with gmail.com
. You can also subscribe to the newsletter to know when I publish more content!