Great question, @silly_lily!
Here’s a few different approaches.
Dash animation
The easiest trick is to animate SVG dash properties using this trick. It makes for a quick/easy effect but requires knowing the length of the line in pixels and has no relation to actual data values, which basically makes it a non-starter.
Using frames
A better solution is to use frames to enumerate every visual state of the plot, then use a slider to switch between them. You’ll notice on the last couple lines that I’ve enumerated every possible slice of the data, from [0]
to [0, 0.02, ..., 1]
. That uses O(n^2)
memory, which is pretty silly, though it does work. I’ve also used the id
property. If you’re familiar with d3, this gets applied to the points as the key
, which is not strictly necessary in this particular example, but which is generally a good idea when animating points in order to enforce object constancy.
Using frames with the filter transform
An optimization in order to avoid enumerating every possible slice is to use the filter transform to restrict the plotted range. Then, instead of changing the dataset for each frame, you can just change the range that gets plotted. In this example, each frame now just changes the value
attribute of the filter transform. Please note that transforms are currently experimental and so are not yet documented (at least in the official docs. You can find the documentation here). The filter transform is stable and unlikely to change, but it’s not currently accessible from the python API. (I looove it though, so if you’re using plotly.js, I’d recommend it.)
Frames + filter + transition
The examples above have about a hundred data points so that I’ve disabled transitions. If you have just a few data points, it may look nicer to keep them. This example adds a finite transition duration. You’ll notice that the path doesn’t animate very nicely. That’s a result of the way SVG animates paths containing a different number of points, so unfortunately there’s not much to be done about that without a significant amount of work (it’s why people usually use the dash animation trick above to accomplish the look of a hand-drawn path). I’ve also included line: {simplify: false}
when using transitions since plotly’s line simplification algorithm (it collapses lines connecting collinear points into a single segment) causes undesirable artifacts.
(One final caveat: I did just notice a bug in which the line opacity is not updated after restarting the last example. Looking into that now.)
I know that’s a lot if information. I’ve left the examples on the more feature-complete side rather than paring them down to the minimal code so that hopefully they’re close to what’s realistically needed for these to work well. Please let me know if you need clarification or if the effect is not quite the same as what you’re after.