Bug with blitting in Qt4Agg backend

Hello,
I am experiencing a bug when trying to blit a canvas that contains two
axes, one with a line plot and the other with an imshow plot. The
attached example, QtBlitBugDemo.py demonstrates the problem. As is, on
my machine, the
imshow plot updates correctly, but the line plot acts like the
background is not being restored correctly, the lines keep piling up
on top of each other, even though I am explicitly restoring a clean
background before drawing the artist. If I simply comment out the
line:
       self.specPlotB.draw_artist(self.specArtistB)
which draws the imshow artist, the line plot behaves correctly.
I haven't been able to figure out what is causing this behavior.
I am using r5186 from the SVN. The output from running with debug mode
on is below.

Thanks for any help on this.
Glenn

matplotlib data path /usr/lib/python2.5/site-packages/matplotlib/mpl-data
loaded rc file /home/glenn/.matplotlib/matplotlibrc
matplotlib version 0.98pre
verbose.level debug
interactive is False
units is True
platform is linux2
loaded modules: ['numpy.lib.pkgutil', 'numpy.lib.tempfile',
'numpy.ma.types', 'xml.sax.urlparse', 'distutils', 'matplotlib.errno',
'matplotlib.matplotlib', '_bisect', 'numpy.core.defchararray',
'pprint', 'numpy.lib.bz2', 'matplotlib.tempfile',
'distutils.sysconfig', 'ctypes._endian', 'encodings.encodings',
'matplotlib.colors', 'numpy.core.numerictypes', 'numpy.testing.sys',
'numpy.core.info', 'xml', 'numpy.fft.types', 'numpy.ma.operator',
'numpy.ma.cPickle', 'struct', 'numpy.random.info', 'tempfile', 'mmap',
'xml.sax.urllib', 'numpy.linalg', 'numpy.testing.operator', 'imp',
'compiler.sys', 'collections', 'compiler.pyassem', 'numpy.core.umath',
'_struct', 'unittest', 'compiler.new', 'numpy.lib.numpy',
'numpy.testing.types', 'compiler.ast', 'numpy.ma.sys', 'zipimport',
'string', 'numpy.testing.os', 'matplotlib.locale',
'numpy.lib.arraysetops', 'numpy.testing.unittest',
'numpy.lib.inspect', 'encodings.utf_8', 'matplotlib.__future__',
'numpy.linalg.numpy', 'pytz.tzinfo', 'numpy.ctypeslib',
'numpy.testing.re', 'itertools', 'numpy.version', 'numpy.lib.re',
'distutils.re', 'ctypes.os', 'compiler.token', 'numpy.core.os',
'compiler', 'numpy.lib.type_check', 'httplib', 'bisect', 'signal',
'compiler.consts', 'numpy.lib._datasource', 'random',
'numpy.ma.extras', 'token', 'numpy.fft.fftpack_lite', 'shlex',
'ctypes.ctypes', 'xml.sax.xmlreader', 'matplotlib.pytz',
'numpy.__builtin__', 'numpy.testing.shlex', 'dis', 'pytz.tzfile',
'cStringIO', 'zlib', 'numpy.numpy', 'matplotlib.StringIO', 'locale',
'numpy.add_newdocs', 'numpy.lib.getlimits', 'PyQt4',
'compiler.transformer', 'xml.sax.saxutils', 'compiler.struct',
'pkgutil', 'compiler.parser', 'numpy.lib.sys', 'encodings',
'compiler.symbol', 'numpy.lib.io', 'numpy.ma.itertools', 'StringIO',
'dateutil', 'pydoc', 'pytz.cStringIO', 'numpy.imp', 'numpy.ctypes',
'matplotlib.warnings', 'rfc822', 'matplotlib.string', 'pytz.pytz',
'urllib', 'matplotlib.sys', 're', 'numpy.lib._compiled_base',
'numpy.core.mmap', 'new', 'numpy.lib.struct', 'symbol', 'math',
'numpy.fft.helper', 'fcntl', 'numpy.ma.warnings', 'compiler.imp',
'UserDict', 'inspect', 'distutils.os', 'matplotlib', 'urllib2',
'pytz.os', 'fnmatch', 'numpy.lib.info', 'numpy.testing',
'numpy.testing.glob', 'numpy.lib.warnings', 'ctypes.struct', 'codecs',
'numpy.core._sort', 'PyQt4.QtGui', 'compiler.visitor', 'md5',
'_locale', 'matplotlib.sre_constants', 'matplotlib.os', 'thread',
'numpy.lib.ufunclike', 'numpy.core.memmap', 'traceback',
'numpy.core._dotblas', 'numpy.testing.warnings', 'weakref',
'numpy.core._internal', 'numpy.fft.fftpack', 'opcode',
'numpy.core.scalarmath', 'numpy.linalg.lapack_lite', 'ctypes',
'distutils.sys', 'os', 'marshal', 'numpy.lib.shutil', '__future__',
'numpy.core.string', 'matplotlib.copy', 'xml.sax.types',
'numpy.random.numpy', '_sre', 'numpy.lib.gzip', 'numpy.core.sys',
'numpy.random', 'numpy.testing.utils', '__builtin__',
'numpy.lib.twodim_base', 'numpy.ma.core', 'matplotlib.re',
'numpy.core.cPickle', 'base64', 'compiler.dis', 'operator',
'numpy.testing.parametric', 'numpy.core.arrayprint',
'distutils.string', 'ctypes._ctypes', '_heapq', 'ctypes.sys', 'heapq',
'numpy.os', 'posixpath', 'numpy.lib.financial',
'numpy.core.multiarray', 'errno', 'numpy.testing.numpy', '_socket',
'binascii', 'numpy.lib.compiler', 'sre_constants',
'compiler.cStringIO', 'datetime', 'compiler.os', 'matplotlib.md5',
'types', 'pytz.sys', 'tokenize', 'FigureWindow', 'xml.sax.handler',
'numpy.core.numpy', 'numpy', 'numpy.lib.urlparse',
'matplotlib.dateutil', 'numpy.core.defmatrix', 'xml.sax.os',
'cPickle', 'matplotlib.xml', '_codecs', 'numpy.testing.difflib',
'matplotlib.traceback', 'numpy.__config__', 'numpy.fft.info',
'numpy.lib.types', 'pytz', 'matplotlib.pyparsing',
'compiler.copy_reg', 'numpy.ma.numpy', 'copy', 'numpy.core.re',
'socket', '_types', 'numpy.core.fromnumeric', 'hashlib',
'compiler.future', 'matplotlib.cbook', 'numpy.core.copy_reg',
'numpy.lib.scimath', 'numpy.fft', 'numpy.lib', '_ctypes',
'apport_python_hook', 'posix', 'encodings.aliases',
'matplotlib.fontconfig_pattern', 'exceptions', 'sre_parse',
'pytz.bisect', 'sets', 'numpy.core.cStringIO', 'numpy.core.ctypes',
'mimetools', 'distutils.distutils', 'copy_reg', 'sre_compile',
'xml.sax', 'compiler.compiler', '_hashlib', '_random', 'parser',
'site', 'numpy.lib.polynomial', 'numpy._import_tools', 'numpy.glob',
'pytz.struct', 'numpy.lib.time', '__main__', 'compiler.misc',
'numpy.core.records', 'shutil', 'numpy.lib.cPickle', 'numpy.sys',
'matplotlib.weakref', 'numpy.lib.pydoc', 'sip',
'numpy.testing.traceback', 'strop', 'compiler.pycodegen',
'numpy.core.numeric', 'numpy.linalg.info', 'encodings.codecs',
'gettext', 'pytz.datetime', 'numpy.core.__svn_version__',
'numpy.lib.cStringIO', 'numpy.core', 'numpy.testing.info',
'matplotlib.rcsetup', 'matplotlib.time', 'pytz.sets',
'matplotlib.numpy', 'xml.sax._exceptions', 'xml.sax.codecs', 'stat',
'_ssl', 'numpy.lib.utils', 'numpy.lib.index_tricks', 'PyQt4.QtCore',
'warnings', 'encodings.types', 'numpy.lib.math', 'glob',
'numpy.lib.shape_base', 'numpy.core.types', 'numpy.fft.numpy', 'repr',
'sys', 'numpy.core.warnings', 'numpy.lib.urllib2', 'compiler.types',
'numpy.core.__builtin__', 'xml.sax.sys', 'numpy.lib.format',
'numpy.lib.os', 'numpy.ma', 'os.path', 'bz2', 'pytz.gettext',
'numpy.random.mtrand', 'numpy.lib.pprint', 'compiler.symbols',
'matplotlib.datetime', 'matplotlib.distutils', '_weakref',
'numpy.testing.numpytest', 'difflib', 'distutils.errors', 'urlparse',
'linecache', 'matplotlib.shutil', 'numpy.lib.function_base',
'numpy.testing.imp', 'time', 'gzip', 'numpy.lib.machar',
'compiler.marshal', 'numpy.linalg.linalg', 'compiler.syntax']
$HOME=/home/glenn
CONFIGDIR=/home/glenn/.matplotlib
Using fontManager instance from /home/glenn/.matplotlib/fontManager.cache
numerix numpy 1.1.0.dev5077
0.98pre Qt4Agg

FigureWindow.py (3.31 KB)

QtBlitBugDemo.py (5.78 KB)

I'm not convinced this is a bug in matplotlib. The following example works:

import matplotlib
matplotlib.use('qt4agg')

from matplotlib import widgets
from matplotlib import pyplot as plt
import numpy as np

ax=plt.axes()
cursor = widgets.Cursor(ax, useblit=True)
ax.imshow(np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), cmap=plt.cm.jet,
interpolation='nearest')
plt.show()

I can't follow your example. It would be better to submit a single script with
as simple an example as possible that illustrates the problem. Maybe you
could have a look at matplotlib.widgets.Cursor to get some ideas of how to
structure your code.

Darren

···

On Monday 19 May 2008 03:36:01 am G Jones wrote:

Hello,
I am experiencing a bug when trying to blit a canvas that contains two
axes, one with a line plot and the other with an imshow plot. The
attached example, QtBlitBugDemo.py demonstrates the problem. As is, on
my machine, the
imshow plot updates correctly, but the line plot acts like the
background is not being restored correctly, the lines keep piling up
on top of each other, even though I am explicitly restoring a clean
background before drawing the artist. If I simply comment out the
line:
       self.specPlotB.draw_artist(self.specArtistB)
which draws the imshow artist, the line plot behaves correctly.
I haven't been able to figure out what is causing this behavior.
I am using r5186 from the SVN. The output from running with debug mode
on is below.

I don't have qt installed so I can't test this here, but poking
through the code one thing looks badly wrong (though it may be
unrelated to your problem)

        if self.autoSpec:
            self.specPlotT.relim()
            self.specPlotT.autoscale_view(scalex = False, scaley = True)

you cannot change the viewlim when updating your animated artists (nor
should you change the grid). The idea is

  - draw (everything but animated by default)

  -- copy the background

  start animation loop:

      * restore background

      * update *only* your animated artists and change nothing else
about the figure (viewlim, grid, labels, etc)

      * draw your animated artists

      * blit

If you need to change anything else, you need to invoke a draw, then a
copy a new background, and then proceed through the animation loop.
Also, be aware that zorder is not respected for animated artists, so I
think you will want to update and draw your image before the lines.

JDH

···

On Mon, May 19, 2008 at 2:36 AM, G Jones <glenn.caltech@...287...> wrote:

Hello,
I am experiencing a bug when trying to blit a canvas that contains two
axes, one with a line plot and the other with an imshow plot. The
attached example, QtBlitBugDemo.py demonstrates the problem. As is, on
my machine, the
imshow plot updates correctly, but the line plot acts like the
background is not being restored correctly, the lines keep piling up
on top of each other, even though I am explicitly restoring a clean
background before drawing the artist. If I simply comment out the
line:
      self.specPlotB.draw_artist(self.specArtistB)
which draws the imshow artist, the line plot behaves correctly.
I haven't been able to figure out what is causing this behavior.
I am using r5186 from the SVN. The output from running with debug mode
on is below.

Thank you for the notes. I found that if I draw the image before the
line, it works as expected. Even though you say I shouldn't try to
change the viewlim when blitting, this does seem to work, the plot
stays within bounds. The axes do not display the correct values until
I resize the window (which forces a full redraw), but I can live with
that.
However, I am curious how one should achieve dynamic autoscaling while
doing an animated plot. Doing a full draw each iteration is too slow.
Is there any other way?

Thanks again,
Glenn

···

On 5/19/08, John Hunter <jdh2358@...287...> wrote:

On Mon, May 19, 2008 at 2:36 AM, G Jones <glenn.caltech@...287...> wrote:
> Hello,
> I am experiencing a bug when trying to blit a canvas that contains two
> axes, one with a line plot and the other with an imshow plot. The
> attached example, QtBlitBugDemo.py demonstrates the problem. As is, on
> my machine, the
> imshow plot updates correctly, but the line plot acts like the
> background is not being restored correctly, the lines keep piling up
> on top of each other, even though I am explicitly restoring a clean
> background before drawing the artist. If I simply comment out the
> line:
> self.specPlotB.draw_artist(self.specArtistB)
> which draws the imshow artist, the line plot behaves correctly.
> I haven't been able to figure out what is causing this behavior.
> I am using r5186 from the SVN. The output from running with debug mode
> on is below.

I don't have qt installed so I can't test this here, but poking
through the code one thing looks badly wrong (though it may be
unrelated to your problem)

        if self.autoSpec:
            self.specPlotT.relim()
            self.specPlotT.autoscale_view(scalex = False, scaley = True)

you cannot change the viewlim when updating your animated artists (nor
should you change the grid). The idea is

  - draw (everything but animated by default)

  -- copy the background

  start animation loop:

      * restore background

      * update *only* your animated artists and change nothing else
about the figure (viewlim, grid, labels, etc)

      * draw your animated artists

      * blit

If you need to change anything else, you need to invoke a draw, then a
copy a new background, and then proceed through the animation loop.
Also, be aware that zorder is not respected for animated artists, so I
think you will want to update and draw your image before the lines.

JDH