3

My application is receiving data over the network at about 30fps, and needs to update a horizontal bar chart dynamically based on this new data.

I am using a matplotlib figure inside a tkinter window for this purpose. Profiling my code has shown that a major bottleneck in my code is the updating of this figure.

A simplified version of the code is given below:

    def update_bars(self):
        """
        Updates a horizontal bar chart
        """
        for bar, new_d in zip(self.bars, self.latest_data):
            bar.set_width(new_d)
        self.figure.draw()

The lag I am experiencing is significant, and grows quickly over time. Is there a more efficient way to update the matplotlib figure? Any help would be great.

EDIT: I will be looking at this for possible speedup tips. I'll update if I get something working.

oczkoisse
  • 1,561
  • 3
  • 17
  • 31
  • You may look at the following questions (a) [fast-live-plotting-in-matplotlib-pyplot](http://stackoverflow.com/questions/40126176/fast-live-plotting-in-matplotlib-pyplot) (b) [real-time-plotting-in-while-loop-with-matplotlib](http://stackoverflow.com/questions/11874767/real-time-plotting-in-while-loop-with-matplotlib) (c) [why-is-plotting-with-matplotlib-so-slow](http://stackoverflow.com/questions/8955869/why-is-plotting-with-matplotlib-so-slow) – ImportanceOfBeingErnest Mar 18 '17 at 08:59

1 Answers1

1

You can update the data of the plot objects. But to some extent, you can't change the shape of the plot, you can manually reset the x and y axis limits.

e.g.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y)

for phase in np.linspace(0, 10*np.pi, 500):
    line1.set_ydata(np.sin(x + phase))
    # render the figure
    # re-draw itself the next time 
    # some GUI backends add this to the GUI frameworks event loop.
    fig.canvas.draw() 
    fig.canvas.flush_events() # flush the GUI events

flush_events

Flush the GUI events for the figure. Implemented only for backends with GUIs.

flush_events make sure that the GUI framework has a chance to run its event loop and clear any GUI events.Sometimes this needs to be in a try/except block because the default implementation of this method is to raise NotImplementedError.

draw will render the figure,in the above code,maybe remove draw still work.But to some extent they're different.

McGrady
  • 10,869
  • 13
  • 47
  • 69
  • I will try what you suggested, thanks btw. I am curious though, I see the call to draw(), wouldn't it be redundant to call flush_events() after that? (I am not much familiar with GUI development so forgive me if my question seems ignorant) EDIT: I just tried what you suggested, doesn't seem to make any difference :( – oczkoisse Mar 18 '17 at 08:47