Speeding up Matplotlib plotting times for real- time ...

[Pages:6]10/7/2014

Speeding up Matplotlib plotting times for real-time monitoring purposes | Danial Taherzadeh

Danial Taherzadeh

Speeding up Matplotlib plotting times for realtime monitoring purposes

Working on a side project I had to plot a parameter read from a

nano-second-range sensor, and naturally I got curious how fast I can push Matplotlib. Needless to say, Matplotlib is meant to be used for publication quality graphs, and has been never meant to be used for performance plotting.

Matplotlib refresh rate with and without Blit



1/6

10/7/2014

Speeding up Matplotlib plotting times for real-time monitoring purposes | Danial Taherzadeh

My initial test shows that with background "caching" I can make it ~1.5 times faster. Not very much gain. I will try next PyQtGraph1 which looks the most often updated codebase between highperformance plotting libs, and based on initial tests can run up to 400 Hz on my machine (i7 iMac), giving a 2.5 ms time resolution.

import time # for Mac OSX import matplotlib matplotlib.use('TkAgg') import matplotlib.pylab as plt import random from mpltools import style style.use('ggplot') fig = plt.figure() ax1 = fig.add_subplot(1, 1, 1) def test_fps(use_blit=True): ax1.cla() ax1.set_title('Sensor Input vs. Time -' + 'Blit [{0:3s}]'.format("On" if use ax1.set_xlabel('Time (s)') ax1.set_ylabel('Sensor Input (mV)') plt.ion() # Set interactive mode ON, so matplotlib will not be blocking the plt.show(False) # Set to false so that the code doesn't stop here cur_time = time.time() ax1.hold(True) x, y = [], []



2/6

10/7/2014

Speeding up Matplotlib plotting times for real-time monitoring purposes | Danial Taherzadeh

times = [time.time() - cur_time] # Create blank array to hold time values

y.append(0)

line1, = ax1.plot(times, y, '.-', alpha=0.8, color="gray", markerfacecolor="

fig.show()

fig.canvas.draw()

if use_blit:

background = fig.canvas.copy_from_bbox(ax1.bbox) # cache the background

tic = time.time()

niter = 200

i = 0

while i < niter:

fields = random.random() * 100

times.append(time.time() - cur_time)

y.append(fields)

# this removes the tail of the data so you can run for long hours. You can c

# and store it in a pickle variable in parallel.

if len(times) > 50:

del y[0]

del times[0]

xmin, xmax, ymin, ymax = [min(times) / 1.05, max(times) * 1.1, -5,110]

# feed the new data to the plot and set the axis limits again

line1.set_xdata(times)

line1.set_ydata(y)

plt.axis([xmin, xmax, ymin, ymax])

if use_blit:

fig.canvas.restore_region(background) # restore background

ax1.draw_artist(line1)

# redraw just the points

fig.canvas.blit(ax1.bbox)

# fill in the axes rectangle

else:

fig.canvas.draw()

i += 1



3/6

10/7/2014

Speeding up Matplotlib plotting times for real-time monitoring purposes | Danial Taherzadeh

fps = niter / (time.time() - tic) print "Blit [{0:3s}] -- FPS: {1:.1f}, time resolution: {2:.4f}s".format("On" return fps fps1 = test_fps(use_blit=True) fps2 = test_fps(use_blit=False) print "-"*50 print "With Blit ON plotting is {0:.2f} times faster.".format(fps1/fps2)

Edit 1: Following the advice on bastibe.de, one can also use

ax1.draw_artist(ax1.patch) ax1.draw_artist(line1) fig.canvas.update() fig.canvas.flush_events()

instead of

fig.canvas.restore_region(background) ax1.draw_artist(line1) fig.canvas.blit(ax1.bbox) fig.canvas.flush_events()

# restore background # redraw just the points # fill in the axes rectangle

Note that this time I am using Qt4Agg, which would be ideal since most of my development is using Qt4, but has one tiny problem of blocking the diagram until done. Hence one can use plt.pause(0.001) or simply fig.canvas.flush_events() without the lazy sleep() in the pause



4/6

10/7/2014

Speeding up Matplotlib plotting times for real-time monitoring purposes | Danial Taherzadeh

function. This change increase the speed to 1.85 times the original.

Also apparently it won't break the plot if you resize it.

Edit 2: One of the reasons that this is rather slow still is due to the fact that I am rescaling the axis each step -- redrawing axis is costly. If you set the axis limits to fixed number the speedup becomes amazing, a whooping 600 Hz and 1 ms resolution; A 14 times speedup.

October 17, 2013

admin

matplotlib, python

Transfer dynamic many-column labeled data from MySQL to Excellike layout - MySQL Pivot Table

Hide Trello activity logs in comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Name *

Email *

Website



5/6

10/7/2014

Comment

Speeding up Matplotlib plotting times for real-time monitoring purposes | Danial Taherzadeh

You may use these HTML tags and attributes:

Post Comment

Search ...

Proudly powered by WordPress ~ Theme: Syntax by .



6/6

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download