I have made an animated choropleth (with a tooltip) as a visualization for some academic colleagues: https://observablehq.com/@theohonohan/birthright-indicators-2000-2020
A similar map was shared on Twitter a few weeks ago, although I can’t find it now. It had the same performance problems as mine.
Although the animation runs at an acceptable speed when the “Play” button is pressed, if I drag the time slider back and forth, the updates to the map are a bit slow. I suspect that this is because the data is somehow being recomputed for each year (rather than being some SVG rendering problem).
Is there an easy fix for this, perhaps involving some kind of caching/memoization of the data?
When I have a rapidly updating animation, there’s normally two optimizations I make. If the issue is with the svg rendering, then taking full advantage of the d3 data join and updating pattern can really help. Here’s a notebook where this is implemented really cleanly: Bar Chart Race, Explained / D3 / Observable
If the issue is with slow data processing, I find preprocessing to be the best solution. Forming a map from each possible year to the cleaned data for rendering that year will prevent additional work when you switch between years.
Thanks. The solution I have now involves precomputing data for each year, as you suggest, and then updating only the colour of each country path (not its geometry) which is more or less what Alex suggested. It is much more responsive:
I don’t think I need to get into the details of the D3 join and updating pattern this time, but it’s good to know about (along with the possibility of rendering with canvas).
Another thing that can help is simplifying the paths of the map based on the scale of the map. The Natural Earth vector data you are using are supposed to be based on a map about 80 cm (2.5 feet) wide, and even a bit more detailed than necessary for that size. But on my display your map here is about 10x smaller than that. You can probably get away with throwing away about 9/10 of the points on the borders of the shapes on your maps without making any visual difference. That will speed every operation up by a factor of 10.
Hmmm, good catch. Many of the world maps on Observable use this 1:50,000,000 dataset, and I had noticed the “50m” in the filename. I just inherited the file from one of @mbostock’s notebooks, (as did the animated choropleth by @gmleon which I alluded to earlier: Choropleth Map + Animation / Gabriela Molina / Observable)
Taking the earth’s projected dimensions as being on the order of 10,000 km, then the 50m data should be appropriate for a map 20 cm wide. I think this is probably not overkill. The larger 110m scale is a bit lacking in detail; one could use topojson to simplify the 50m data a bit, I suppose.
I was thinking of the distance between the poles being roughly 1.5 times the diameter! The 40,000 km figure is good to know, although I think you’ll find that the definition of the metre arose from the business of measuring the length of meridian arcs rather than the equator. Paris meridian - Wikipedia (Edit: Ah, I see you said polar circumference—but it’s the equator that determines the width of a map, which is what confused me. Also the fact that the earth is significantly oblate so I don’t think of polar circumferences as being circular)
(While the process of surveying a distance on the ground would be the same on the equator as on a meridian, measuring a difference in latitude is a lot easier astronomically than determining a difference of longitude…)
I was going to make a point about how Nicole Oresme (inventor of graphing) referred to the independent variable as the “longitude” and the dependent variable as a the “latitude”. For him they were clearly qualitatively different dimensions.
All this aside, I think we can probably agree that the 110m scale data doesn’t hold up under zooming (if I’m not mistaken, this notebook uses unmodified 110m data Zoom World Choropleth / Fil / Observable) and an ability to zoom is something I might want to add, to allow smaller territories to be inspected properly.