1

I am using Matplotlib 2.0.2 in a Python 3.6 script on Windows 10 to plot data received over a network connection. New data arrives 4 times per second. I need to update two figures, each containing 8 subplots. I do this using animation:

anim = []

anim.append( matplotlib.animation.FuncAnimation(fig_A, updatePlots_A, frames=None, interval=100, repeat=True) )
anim.append( matplotlib.animation.FuncAnimation(fig_B, updatePlots_B, frames=None, interval=100, repeat=True) )

plt.show()

My question is whether it is ok to make two FuncAnimation calls in this way? Is that the most efficient way of handling the plots?

The figures are not very responsive to user input. Moving a figure by dragging it with the mouse is very sluggish.

I've chosen:

frames=None, interval=100

because I want each of my update functions to be called at 10Hz. Will the code achieve this (machine performance permitting)?

I tried using matplotlib.pyplot.pause() instead of FuncAnimation() but found the update rate was then worse, so went back to using FuncAnimation().

Any comments for improvement would be appreciated.

DavidA
  • 2,053
  • 6
  • 30
  • 54
  • It's fine to use two FuncAnimations, although you would achive the same with one FuncAnimation which calls a function that then calls both updatePlots functions. The slugghish update rate or lost responsivity is rather due to updating 16 subplots at the same time, I would guess. Depending on what is drawn in them this may take some time. There are some limited means to improve performance in matplotlib animations, but you should look around for them yourself and see if they can be applied to your case. – ImportanceOfBeingErnest Jul 21 '17 at 08:42
  • Thanks. I did consider using a single FuncAnimation that calls both updatePlots functions, but FuncAnimation takes a fig object, so I don't know what to do as I have two fig objects. – DavidA Jul 21 '17 at 08:48
  • Oh, well, now that you meantion it, it's clear that `fig_A` is different from `fig_B`. Sorry for the confusion. But the main argument stays the same: You probably have too many objects that need to be updated. – ImportanceOfBeingErnest Jul 21 '17 at 08:52
  • Thanks for your help. – DavidA Jul 21 '17 at 09:01
  • @DavidA If you get new data only 4 times per second, why do you want to update the figures at 10Hz? This feels like you artificially slow down your application. Maybe check when you actually do get new data and trigger figure updates 'manually' with `figure.canvas.draw()`? – Thomas Kühn Jul 21 '17 at 09:24
  • @ThomasKühn Yes, I follow what you're saying. I poll the network socket using select and only update the subplots if data is available. 10Hz is effectively my polling frequency. I can reduce that. Alternatively I can poll and draw in my own loop, as I think you're suggesting. Does figure.canvas.draw() work ok if I'm using scatter collections? I set the data using sc.set_offsets(np.c_[i_data, q_data]). What matplotlib functions would my loop need to call in order to update a scatter in a subplot? – DavidA Jul 21 '17 at 10:59
  • In my loop that replaces FuncAnimation I'm calling plt.pause(1e-17) but that is introducing a delay of ~1s or more. – DavidA Jul 21 '17 at 11:14
  • @DavidA Here a [very basic example](https://stackoverflow.com/a/18793416/2454357) of how to continuously update of a plot (drawn with `plot`). Here an [example](https://stackoverflow.com/a/42738014/2454357) on how to update a scatter plot. About `plt.pause`, I don't know why the delay is so large. How if you try, say, `0.01`? Do you need `plt.pause` in your `for`-loop? – Thomas Kühn Jul 21 '17 at 11:31
  • @DavidA In the first example, instead of waiting a fixed time, you could check whether you data has actually changed before updating... – Thomas Kühn Jul 21 '17 at 11:33
  • 1
    @ThomasKühn Thanks again. For unknown reasons, plt.pause is taking seconds, but I replaced it with fig.canvas.flush_events() and that is much faster. So I think I have a solution now. – DavidA Jul 21 '17 at 12:21
  • Not perfect yet. fig.canvas.flush_events() takes 350ms. Any ideas why please? – DavidA Jul 21 '17 at 12:52

0 Answers0