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
import matplotlib
matplotlib.use("Qt4Agg")
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import os
class ResizableMainWindow(QMainWindow):
def resizeEvent(self,event):
self.emit(SIGNAL("resize"),event)
class FigureWindow():
"""
Public attributes
canvas : The FigureCanvas instance
num : The Figure number
toolbar : The qt.QToolBar
window : The qt.QMainWindow
"""
def __init__( self):
self.figure = matplotlib.figure.Figure(figsize=(4,3))
self.canvas = FigureCanvasQTAgg(self.figure)
self.window = ResizableMainWindow()
self.window.setWindowTitle("Figure")
image = os.path.join( matplotlib.rcParams['datapath'],'images','matplotlib.png' )
self.window.setWindowIcon(QIcon( image ))
# Give the keyboard focus to the figure instead of the manager
self.canvas.setFocusPolicy( Qt.ClickFocus )
self.canvas.setFocus()
QObject.connect( self.window, SIGNAL( 'destroyed()' ),
self._widgetclosed )
self.window._destroying = False
self.toolbar = self._get_toolbar(self.canvas, self.window)
self.window.addToolBar(self.toolbar)
QObject.connect(self.toolbar, SIGNAL("message"),
self.window.statusBar().showMessage)
self.window.setCentralWidget(self.canvas)
self.window.show()
# attach a show method to the figure for pylab ease of use
self.canvas.figure.show = lambda *args: self.window.show()
def notify_axes_change( fig ):
# This will be called whenever the current axes is changed
if self.toolbar != None: self.toolbar.update()
self.canvas.figure.add_axobserver( notify_axes_change )
self.window.closeEvent = self._closeH
self.window.connect(self.window,SIGNAL("resize"),self._resizeH)
def _closeH(self,event):
event.ignore()
def _resizeH(self,event):
self.saveBackground()
def saveBackground(self):
self.canvas.draw()
self.bbox = self.figure.bbox
print self.bbox.corners()
self.background = self.canvas.copy_from_bbox(self.bbox)
def restoreBackground(self):
self.canvas.restore_region(self.background)
def blit(self):
self.canvas.blit(self.bbox)
def _widgetclosed( self ):
print "widg closed"
if self.window._destroying: return
self.window._destroying = True
def _get_toolbar(self, canvas, parent):
# must be inited after the window, drawingArea and figure
# attrs are set
toolbar = matplotlib.backends.backend_qt4.NavigationToolbar2QT(canvas, parent, False)
return toolbar
def resize(self, width, height):
'set the canvas size in pixels'
self.window.resize(width, height)
def destroy( self, *args ):
if self.window._destroying: return
self.window._destroying = True
QObject.disconnect( self.window, SIGNAL( 'destroyed()' ),
self._widgetclosed )
if self.toolbar: self.toolbar.destroy()
self.window.close()
def set_window_title(self, title):
self.window.setWindowTitle(title)
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from FigureWindow import FigureWindow
import os, sys
import time
if os.name == 'posix':
_time = time.time
else:
_time = time.clock
import numpy as np
class MySpecDialog(QMainWindow):
def __init__(self, parent = None):
super(MySpecDialog, self).__init__(parent)
self.nch = 512
self.nadc = 8192
self.histI = np.zeros((512,self.nch),'float32')
self.histQ = np.zeros((512,self.nch),'float32')
self.move(0,0)
self.ch = 100
self.running = False
self.LastPacketTime = 0
self.LastUpdateTime = 0
self.UpdatePeriod = 0.1
self.LastSlowUpdate = 0
self.SlowUpdatePeriod = 5
self.lastdataI = 0
self.adcI = np.zeros((512,))
self.adcQ = np.zeros((512,))
self.dataI = 0
self.dataQ = 0
self.LO = 0
self.openPlotWindows()
self.initSpecWin()
self.initScopeWin()
self.autoscaleScope()
self.autoscaleSpec()
self.timer = QTimer()
QObject.connect(self.timer,SIGNAL("timeout()"),self.onTimer)
self.timer.start(200)
def autoscaleScope(self):
self.autoScope = True
def autoscaleSpec(self):
self.autoSpec = True
def onTimer(self):
ch = self.nch
self.dataI = np.random.random(self.nch)*8
self.dataQ = -np.random.random(self.nch)
self.histI[1:,:] = self.histI[:-1,:]
self.histI[0,:] = self.dataI
self.histQ[1:,:] = self.histI[:-1,:]
self.histQ[0,:] = self.dataQ
self.adcI = np.random.random(self.nch)
self.adcQ = np.random.random(self.nch)*40
self.updateSpecPlot()
self.updateScopePlot()
def updateSlowPlot(self):
specI = self.dataI
specQ = self.dataQ
adcI = self.adcI
adcQ = self.adcQ
self.slowTop.cla()
self.slowBot.cla()
self.slowTop.hist(adcI,range(-128,128,8))
self.slowBot.hist(adcQ,range(-128,128,8))
self.slowFig.canvas.draw()
def updateSpecPlot(self):
specI = self.dataI
specQ = self.dataQ
a = _time()
self.specWin.restoreBackground()
b = _time()
for label in self.specArtistsT:
artist = self.specArtistsT[label]
if label == "I Spectrum":
artist.set_ydata(10*np.log10(specI+1))
if label == "Q Spectrum":
artist.set_ydata(10*np.log10(specQ+1))
if label == "I(n)/I(n-1)":
artist.set_ydata(specI)
if label == "Q(n)/Q(n-1)":
artist.set_ydata(specQ)
self.specPlotT.draw_artist(artist)
self.specArtistB.set_data(np.log10(self.histI))
# Comment out this next line and the line plot above blits correctly
# otherwise, the line plot acts as though the canvas is not being cleared
self.specPlotB.draw_artist(self.specArtistB)
self.specPlotT.grid(True)
c = _time()
if self.autoSpec:
self.specPlotT.relim()
self.specPlotT.autoscale_view(scalex = False, scaley = True)
self.specWin.blit()
# Even when the line is moved here, the same problem occurs.
#self.specPlotB.draw_artist(self.specArtistB)
d = _time()
print "%g %g %g" % ((b-a)*1000,(c-b)*1000,(d-c)*1000)
def updateScopePlot(self):
pass
def openPlotWindows(self):
self.specWin = FigureWindow()
self.scopeWin = FigureWindow()
self.specFig = self.specWin.figure
self.scopeFig = self.scopeWin.figure
self.specPlotT = self.specFig.add_axes([.1,.55,.8,.4])
self.specPlotB = self.specFig.add_axes([.1,.05,.8,.5],sharex = self.specPlotT)
self.specPlotB.set_xlim(0,self.nch-1)
self.scopePlot = self.scopeFig.add_subplot(111)
self.scopePlot.set_xlim(0,self.nch-1)
self.slowWin = FigureWindow()
self.slowFig = self.slowWin.figure
self.slowTop = self.slowFig.add_subplot(2,1,1)
self.slowBot = self.slowFig.add_subplot(2,1,2)
self.specWin.window.move(0,300)
self.scopeWin.window.move(340,0)
self.slowWin.window.move(340,300)
def initSpecWin(self):
self.specArtistsT = dict()
self.specPlotT.cla()
self.specPlotB.cla()
self.specPlotT.hold(False)
self.specArtistsT['I Spectrum'], = self.specPlotT.plot(np.zeros(self.nch),'b',animated = True)
self.specPlotT.legend(self.specArtistsT.values(),self.specArtistsT.keys(),'upper right')
self.specArtistB = self.specPlotB.imshow(np.random.random((512,self.nch)),aspect = 'auto', animated = True)
self.specFig.canvas.draw()
self.specWin.window.update()
self.specWin.window.repaint()
self.specWin.saveBackground()
def initScopeWin(self):
self.scopeArtists = dict()
self.scopePlot.cla()
#self.scopeArtists[str(self.comboEqn1.currentText())], = self.scopePlot.plot(np.zeros(self.nch),'b',animated = True)
#self.scopeArtists[str(self.comboEqn2.currentText())], = self.scopePlot.plot(np.zeros(self.nch),'r',animated = True)
#self.scopePlot.legend(self.scopeArtists.values(),self.scopeArtists.keys(),'upper right')
self.scopeFig.canvas.draw()
self.scopeWin.saveBackground()
print self.scopeWin.bbox
print self.scopeArtists
def closeEvent(self,event):
QCoreApplication.quit()
import matplotlib
print matplotlib.__version__, matplotlib.get_backend()
app = QApplication(sys.argv)
SpectrometerDialog = MySpecDialog()
SpectrometerDialog.show()
sys.exit(app.exec_())
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users