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

Reply via email to