RJ Budzyński
RJ Budzyński8mo ago

Animate mpl

Is there any way to animate a matplotlib plot in marimo?
20 Replies
Myles Scolnick
Myles Scolnick8mo ago
Did you try mo.mpl.interactive? Or is it more animate a loop to show data over time?
RJ Budzyński
RJ BudzyńskiOP8mo ago
I mean animate a plot to show how a simulation evolves over time I'm trying with marimo.ui.refresh() but it's not ideal - I don't know how to reset the value to 0. Not to mention that the docs wrongly state that refresh.value is the time in seconds since activation, while it's actually a string.
Myles Scolnick
Myles Scolnick8mo ago
Yea the value does contain a mix of the selected time and time in seconds. We did make it a string, but we could make it dictionary / something more useful
RJ Budzyński
RJ BudzyńskiOP8mo ago
well I just parse it with a regexp,
Myles Scolnick
Myles Scolnick8mo ago
you could create your own time tracker too with mo.state, its probably safer and you can track iterations. for other animations, plotly supports animating muliple views https://marimo.app/l/orxu05
marimo | a next-generation Python notebook
Explore data and build apps seamlessly with marimo, a next-generation Python notebook.
RJ Budzyński
RJ BudzyńskiOP8mo ago
afaics matplotlib.animation which is built into the lib does not work with marimo. I'll have to try mo.state then. but actually no matter what interval I choose for the refresh, I only get one refresh per second. I tried counting the number of refreshes instead of parsing refresh.value, and no matter what interval I set it always refreshes once per second. well unless I choose an interval > 1s, then it does slow down. By using my own counter I can reset it of course, but it's still rather unexpected that re-running the code that creates the refresh does not reset the running time.
Myles Scolnick
Myles Scolnick8mo ago
refresh it not the tool you really want to use anyways. thats more for dashboard building (not running animations) - as there is not guarantee the timing will be consistent (due to queued up runs of other cells) i'd use a for loop with time.sleep or use the animation features in plotly for example
RJ Budzyński
RJ BudzyńskiOP8mo ago
I should use matplotlib (for reasons), but I;'ll be trying the plotly features anyway. I've been trying a for loop with sleep but haven't figured it out yet.
Myles Scolnick
Myles Scolnick8mo ago
if you can share some of your code, happy to look at it when i free up
RJ Budzyński
RJ BudzyńskiOP8mo ago
Here's what I currently have: https://marimo.app/l/d4sqrz Use a for loop? How would you force a picture to update while the loop is running? Also, it's strange that a refresh timer once initialized cannot be stopped (programatically) or reset (at all, other than by reloading the notebook afaics).
Myles Scolnick
Myles Scolnick8mo ago
There is an off setting for refresh. It’s mostly for dashboards though. For the for loop, you can do mo.output.replace to replace it while the cell is still running
RJ Budzyński
RJ BudzyńskiOP8mo ago
Hey I missed that - I'll see how it works. Yeah animating a plot with a python loop works not too badly - well, 5 fps at most on my laptop, but what would you expect without any blitting. This is actually not too bad: https://marimo.app/l/3elexb - could use a pause/run button perhaps, but that's probably doable. Maybe the animation should be running asynchronously? Is that even possible in marimo? From what I found online, there seems to be no way to control animation framerate in plotly, or at least in plotly.express, which is what everyone uses. I'm not very happy with plotly animations. Plotly forces me to reformat my data into a dataframe, which is a very uneconomical representation and limits the number of parameter values I can visualize. It precomputes all the frames (afaics), so for any reasonable montecarlo it exceeds marimo's memory limit by like an order of magnitude. Anyway, unless I'm mistaken plotly is rendering to svg, which isn't very good for animations - rendering to canvas works better. For simple plots of aggregate quantities it should work okay, but visualizing dynamics of many units, nope. Basically, I am looking at the possibility of reproducing something like https://rjb-brownian.surge.sh/ in marimo, as a test case.
Myles Scolnick
Myles Scolnick8mo ago
that is pretty cool - is that not plotly though? what are the particles renderered with?
RJ Budzyński
RJ BudzyńskiOP8mo ago
The plots on the right are plotly.js, the particles are raw canvas.
Myles Scolnick
Myles Scolnick8mo ago
you could probably write raw canvas as an AnyWidget plugin (https://anywidget.dev/)
RJ Budzyński
RJ BudzyńskiOP8mo ago
It seems that plotly.js has better animation options than plotly.py, or I just can't figure them out.
Myles Scolnick
Myles Scolnick8mo ago
plotly.py is just a wrapper pretty much. we use it to pass down the options to plotly.js as well. if there are missing options, we can try to add these (even if vanialla plotly.py doesnt support them)
RJ Budzyński
RJ BudzyńskiOP8mo ago
on second thought, I guess that's not the real problem - it's that in js I can update stuff async by calling requestAnimationFrame() on the canvas I just clear and redraw, on the plots I use Plotly.react() (but only every 10 frames, since otherwise there's too much flicker, or maybe they don't keep up - don't remember exactly) any way to plug an AnyWidget into marimo?
RJ Budzyński
RJ BudzyńskiOP8mo ago
👍 I'll admit any time that the matplotlib api is a godawful mess - but it does get the job done. In plotly I always hit on some block I can't resolve based on the docs or the available examples.