«

»

Print this Post

Fixing Slow Matplotlib in Python(x,y)

I recently migrated to Python(x,y) and noticed my matplotlib graphs are resizing unacceptably slowly when I use the pan/zoom button. I’m quite a fan of numpy, scipy, matplotlib, the python imaging library (PIL), and GUI platforms like Tk/TkInter, pyGTK, and pyQT, but getting them all to play nicely is a sometimes pain. I’m considering migrating entirely to Python(x,y) because, as a single distribution, it’s designed to install all these libraries (and many more) in a compatible way out of the box. However, when I did, I noticed matplotlib graphs would resize, rescale, and drag around the axes very slowly. After a lot of digging on the interweb, I figured out what was going wrong. I’ll show you by plotting 20 random data points the slow way (left) then the fast way (right).

THE PROBLEM: See the difference between the two plots? The one on the left (SLOW!) uses the Qt4Agg backend, which renders the matplotlib plot on a QT4 canvas. This is slower than the one on the right, which uses the more traditional TkAgg backend to draw the plot on a Tk canvas with tkinter (FASTER!). Check out matplotlib’s official description of what a backend is and which ones you can use. When you just install Python and matplotlib, Tk is used by default. 

import numpy
import matplotlib
matplotlib.use('TkAgg') # <-- THIS MAKES IT FAST!
import pylab
pylab.plot(numpy.random.random_integers(0,100,20))
pylab.title("USING: "+matplotlib.get_backend())
pylab.show()

THE FIX: Tell matplotlib to stop using QT to draw the plot, and let it plot with Tk. This can be done immediately after importing matplotlib, but must be done before importing pylab using the line matplotlib.use('TkAgg'). Here’s the full example I used to generate the demonstration plots above. Change TkAgg to Qt4Agg (or comment-out the ‘use’ line if you’re using PythonXY) and you will see performance go down the tube. Alternatively, make a change to the matplotlib rc file to customize default behavior when the package is loaded.

About the author

Scott W Harden

Scott Harden has had a lifelong passion for computer programming and electrical engineering, and recently has become interested in its relationship with biomolecular sciences. He has run a personal website since he was 15, which has changed names from HardenTechnologies.com, to KnightHacker.com, to ScottIsHot.com, to its current SWHarden.com. Scott has been in college for 10 years, with 3 more years to go. He has an AA in Biology (Valencia College), BS in Cell Biology (Union University), MS in Molecular Biology and Microbiology (University of Central Florida), and is currently in a combined DMD (doctor of dental medicine) / PhD (neuroscience) program through the collaboration of the College of Dentistry and College of Medicine (Interdisciplinary Program in Biomedical Science, IDP) at the University of Florida in Gainesville, Florida. In his spare time Scott builds small electrical devices (with an emphasis on radio frequency) and enjoys writing cross-platform open-source software.

Permanent link to this article: http://www.SWHarden.com/blog/2013-04-15-fixing-slow-matplotlib-in-pythonxy/

5 comments

  1. Chris Parrish

    Cool. Thanks!

    Right now, I’m struggling with embedding a matplotlib object into a Tkinter frame.

    Reading your CV, I wonder if you get tired? Do you do any ZigBee stuff?

    Regards,

    Chris Parrish
    Field Engineer, Sr.
    City of Atlanta
    Dept of Watershed Management
    Office of Watershed Protection
    Flow Monitoring Division
    72 Marietta St NW
    Atlanta, GA 30303

  2. hyry

    Qt4Agg is slow because it don’t repaint the figure immediately. You can fix this by change the following code in draw() method in backend_qt4agg.py:

    FigureCanvasAgg.draw(self)
    #self.update() # this don’t repaint the QWidget immediately
    self.repaint() # this will make the response faster

  3. Daniel Flores Vergara

    Thanks a lot !!!

  4. Christoph

    Hi,

    I want to do some realtime FFT. At the moment I am using matplotlib 1.3.1, compiled it myself.
    I tried to speed it up with self.repaint(), but I cannot see any difference.

    At first the plot is updated very rapidly but then slows down and the complete gui looses responsiveness.

    Is there any way to further speed up matplotlibs plotting?

    I would like to stick with matplotlib…

    Regards,
    Christoph

  5. tellis

    Thanks for this! I’ve been tearing my hair out trying to get ipython to plot stuff in under a week!

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>