Hi list (yes, me, again :D)
I'm having difficulties with matplotlib svn (rev 7249) and animations.
I'm a bit lost on what I have to do to get my animation running smoothly?
I had various attempts, It seems that the best result I can have is by
totally skipping the canvas.restore_region(self.background) shown in the
examples : the resizing of the window make the plot look terribly broken
sorry for this question that seems well covered by documentation and
examples :S
I'm attaching a sample code that reproduces the behavior of my app, It's
a bit long but I hope there's some good things in it that can be usefull
to others
===code snippet===
import wxversion
wxversion.ensureMinimal('2.8')
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
FigureCanvas
import wx
import wx.aui
from matplotlib.figure import Figure
import sys
import getopt
from threading import *
from itertools import izip
import time
class myplotData(Figure):
def __init__(self,name,width=5,height=4,dpi=60,x_axis=None):
Figure.__init__(self,figsize=(width, height),dpi=dpi)
self.name = name
self.ax = self.add_subplot(111,label=name,animated=True)
self.bg = None
self.mdirty = False
def refreshbg(self):
self.bg = self.canvas.copy_from_bbox(self.ax.bbox)
def feed(self,n):
timestamp = n[0]
self.n = 0
if self.bg == None:
self.canvas = self.ax.figure.canvas
self.canvas.draw()
self.bg = self.canvas.copy_from_bbox(self.ax.bbox)
for xs in n[1:]:
self.ax.plot([timestamp],[xs],animated=True)
return
#self.canvas.restore_region(self.bg)
mylines = self.ax.get_lines()
for xs,line in izip(n[1:],mylines):
x,y = line.get_data()
x = np.concatenate((x,[timestamp]))
y = np.concatenate((y,[xs]))
line.set_data([x,y])
self.ax.set_xlim(xmax=timestamp)
curyminlim,curymaxlim = self.ax.get_ylim()
self.ax.set_ylim(ymin=min(xs,curyminlim),ymax=max(xs,curymaxlim))
self.ax.draw_artist(line)
self.mdirty = True
wx.WakeUpIdle()
def blit(self):
if self.mdirty:
self.mdirty = False
self.canvas.blit(self.ax.get_figure().bbox)
class CanvasPanel(wx.Panel):
def __init__(self,name,callback=None,parent=None):
wx.Panel.__init__(self, parent)
self.SetSize((120, 80))
self.figure = myplotData(name)
self.canvas = FigureCanvas(self,-1,self.figure)
self.parent = parent
self.callback = callback
color = (255,255,255)
self.SetColor(color)
self._SetSize()
self._resizeflag = False
self.Bind(wx.EVT_IDLE, self._onIdle)
self.Bind(wx.EVT_SIZE, self._onSize)
def SetColor(self,rgbtuple=None):
"""Set figure and canvas colours to be the same."""
if rgbtuple is None:
rgbtuple =
wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
clr = [c/255. for c in rgbtuple]
self.figure.set_facecolor(clr)
self.figure.set_edgecolor(clr)
self.canvas.SetBackgroundColour(wx.Colour(*rgbtuple))
def _onSize(self,event):
self._resizeflag = True
def _onIdle(self,evt):
if self._resizeflag:
self._resizeflag = False
self._SetSize()
self.figure.blit()
def _SetSize(self):
pixels = tuple(self.parent.GetClientSize())
self.SetSize(pixels)
self.canvas.SetSize(pixels)
self.figure.set_size_inches(float(pixels[0])/self.figure.get_dpi(),
float(pixels[1])/self.figure.get_dpi())
#self.figure.refreshbg()
def process(self,data):
if self.callback != None:
x = self.callback(data)
self.figure.feed(x)
else:
self.figure.feed(data)
# Define notification event for thread notifications
EVT_RESULT_ID = wx.NewId()
def EVT_RESULT(win, func):
"""Define Result Event."""
win.Connect(-1, -1, EVT_RESULT_ID, func)
class ResultEvent(wx.PyEvent):
"""Simple event to carry arbitrary result data."""
def __init__(self, data):
"""Init Result Event."""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_RESULT_ID)
self.data = data
class ParserThread(Thread):
def __init__(self,source,notify_window):
Thread.__init__(self)
self._notify_window = notify_window
self.data = np.arange(0,2*np.pi,0.01)
self.n = 0
self.round = 0
self.start()
def run(self):
while(1):
mbuff = {}
mbuff['name'] = "My Sin Plot"
mbuff['x'] = self.data[self.n] + self.round*2*np.pi
mbuff['y1'] = np.sin(mbuff['x'])
mbuff['y2'] = np.sin(mbuff['x'] + np.pi/2)
self.n+=1
if self.n == len(self.data):
self.n = 0
self.round += 1
wx.PostEvent(self._notify_window, ResultEvent(('test',[mbuff])))
time.sleep(.1)
def mycback(data):
return data['x'],data['y1'],data['y2']
class MyApp(wx.Frame):
def __init__(self,parent=None,
id=wx.ID_ANY,pos=wx.DefaultPosition,size=wx.DefaultSize,
style=wx.DEFAULT_FRAME_STYLE):
wx.Frame.__init__(self, parent)
self.bestsize = (120,75)
self.SetSize(self.GetBestSize())
self.panel = wx.Panel(self,wx.ID_ANY)
self.panel.nb = wx.aui.AuiNotebook(self.panel)
self.label = wx.StaticText(self.panel.nb,wx.ID_ANY,"\n\n\n\naaa\n")
self.panel.nb.AddPage(self.label, "txt")
sizer = wx.BoxSizer()
sizer.Add(self.panel.nb, 1, wx.EXPAND)
self.panel.SetSizer(sizer)
self.plotlist = {}
self.Fit()
EVT_RESULT(self,self.OnResult)
self.worker = ParserThread(5758,self)
def OnResult(self,event):
tag,mbuff = event.data
if tag == -1:
return
for buff in mbuff:
if not self.plotlist.has_key(buff['name']):
cback = mycback
page = CanvasPanel(buff['name'],mycback,self.panel.nb)
self.panel.nb.AddPage(page,buff['name'])
self.plotlist[buff['name']] = page
myPlot = self.plotlist[buff['name']]
myPlot.process(buff)
def main(argv=None):
if argv != None:
sys.argv = argv
app = wx.App()
frame = MyApp()
frame.Show()
app.MainLoop()
if __name__ == "__main__":
main()
===code snippet===
···
----
This message contains confidential information and may contain information that is legally privileged. If you have received this message by mistake, please immediately notify us and delete the original message. Thank you.
Ce message contient des informations confidentielles. S'il vous est parvenu par erreur, merci de bien vouloir nous en aviser par retour, de n'en faire aucun usage et de n'en garder aucune copie.
----