SourceForge logo
SourceForge logo
Menu

matplotlib-users

From: Andrew S. <str...@as...> - 2004年06月26日 07:56:31
Attachments: dynamic_image_wxagg.py
Hi plotters,
I've shamelessly modified dynamic_demo_wx.py to create 
dynamic_image_wxagg.py, attached. This is my initial attempt to get 
matplotlib to dynamically update images. Basically it all works 
hunky-dory except 1) an apparent memory leak and 2) flicker when I run 
this in linux (haven't tested other OSes). I offer #1 to John or other 
memory-leak hunters out there and ask if any WXpert can address #2. 
I've googled a bit and it appears the WX backend (from which WXAgg is 
derived) does the Right Thing and calls wxClientDC on a non-OS generated 
redraw request, which is supposed to reduce or eliminate flicker. The 
other tip is to catch EVT_ERASE_BACKGROUND, which I've also done to no 
apparent improvement. Thus, I ask for help -- any suggestions on how to 
eliminate this flicker?
John -- feel free to stick this in examples if you think it's worthy.
Cheers!
Andrew
From: Andrew S. <str...@as...> - 2004年06月26日 08:32:11
Sorry, I also added the following line to backend_wxagg to get my demo 
to work:
from backend_wx import FigureManager
Anyhow, I've added this to CVS, but you can just as easily modify your 
copy of the affected file.
Cheers!
Andrew
From: John H. <jdh...@ac...> - 2004年06月29日 03:47:33
>>>>> "Andrew" == Andrew Straw <str...@as...> writes:
 Andrew> Hi plotters, I've shamelessly modified dynamic_demo_wx.py
 Andrew> to create dynamic_image_wxagg.py, attached. This is my
 Andrew> initial attempt to get matplotlib to dynamically update
 Andrew> images. Basically it all works hunky-dory except 1) an
 Andrew> apparent memory leak and 2) flicker when I run this in
 Andrew> linux (haven't tested other OSes). I offer #1 to John or
 Andrew> other memory-leak hunters out there and ask if any WXpert
 Andrew> can address #2. I've googled a bit and it appears the WX
 Andrew> backend (from which WXAgg is derived) does the Right Thing
 Andrew> and calls wxClientDC on a non-OS generated redraw request,
 Andrew> which is supposed to reduce or eliminate flicker. The
 Andrew> other tip is to catch EVT_ERASE_BACKGROUND, which I've
 Andrew> also done to no apparent improvement. Thus, I ask for help
 Andrew> -- any suggestions on how to eliminate this flicker?
Hi Andrew,
Haven't had a chance to test your example yet but hopefully I can take
a look tomorrow. I haven't done much memory leak testing against the
_image module yet so this will be a good opportunity. I very recently
rewrote _image.cpp using cxx. I trust you have a fresh CVS checkout?
As for the flicker problem, I've noticed it too, and would also be
thankful if any wx gurus have some advice.
BTW, wxagg currently uses a string copy in python to render agg to a
wx bitmap via a wx image. It would be nice if some enterprising
soul wrote some extension code ala _tkagg.cpp and _gtkagg.cpp which
transfers the agg canvas to wx directly. Should be a pretty big win
performance wise. We could keep the string method as a fallback in
case the extension wasn't compiled, but it would help for people who
want to use wxagg for dynamic applications (hint hint). 
This should at least be on the goals page.
JDH
From: John H. <jdh...@ac...> - 2004年07月01日 13:49:52
>>>>> "John" == John Hunter <jdh...@ac...> writes:
 John> Haven't had a chance to test your example yet but hopefully
 John> I can take a look tomorrow. I haven't done much memory leak
 John> testing against the _image module yet so this will be a good
 John> opportunity. I very recently rewrote _image.cpp using cxx.
 John> I trust you have a fresh CVS checkout?
Hi Andrew - found and fixed the memory leak. Can't really call it a
leak - more like a "memory gusher". This was in the agg (and image)
module "to string" methods. In my tests, the leak went from 600k per
frame to approx 600 bytes per frame, which is on par for what I see in
other agg memory leak tests.
I made a number of comments in your example to point out places where
you probably should be using matplotlib a little differently - most of
these I flagged with my initials so you can search for them. Modified
script is below. 
After you get the script in the final form you want and purge the
comments and memory reporting stuff where appropriate, please add it
to CVS.
I liked the example so much I made an analogous one dynamic_image_gtk.
It's faster than wxagg (13FPS vs 4FPS on my system) which is not
surprising since gtkagg has extension code to transfer agg to the GUI
canvas, and doesn't flicker. Very nice! I would really like to get
that wxagg flicker problem figured out, and the extension code
added... Did I hear you volunteering to be the wxagg maintainer :-)?
#!/usr/bin/env python
"""
Copyright (C) 2003-2004 Jeremy O'Donoghue and others
 
License: This work is licensed under the PSF. A copy should be included
with this source code, and is also available at
http://www.python.org/psf/license.html
"""
import sys, time, os, gc
import matplotlib
matplotlib.use('WXAgg')
# jdh: you need to control Numeric vs numarray with numerix, otherwise
# matplotlib may be using numeric under the hood and while you are
# using numarray and this isn't efficient. Also, if you use
# numerix=numarray, it is important to compile matplotlib for numarray
# by setting NUMERIX = 'numarray' in setup.py before building
from matplotlib import rcParams
rcParams['numerix'] = 'numarray'
# jdh: you can import cm directly, you don't need to go via
# matplotlib.matlab
import matplotlib.cm as cm
from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg
# jdh: you don't need a figure manager in the GUI - this class was
# designed for the matlab interface
from matplotlib.figure import Figure
import matplotlib.numerix as numerix
from wxPython.wx import *
TIMER_ID = wxNewId()
# jdh: use this function, or something similar, when reporting a
# memory leak
def report_memory(i):
 pid = os.getpid()
 a2 = os.popen('ps -p %d -o rss,sz' % pid).readlines()
 print i, ' ', a2[1],
 return int(a2[1].split()[0])
class PlotFigure(wxFrame):
 def __init__(self):
 wxFrame.__init__(self, None, -1, "Test embedded wxFigure")
 self.fig = Figure((5,4), 75)
 self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
 self.toolbar = Toolbar(self.canvas)
 self.toolbar.Realize()
 # On Windows, default frame size behaviour is incorrect
 # you don't need this under Linux
 tw, th = self.toolbar.GetSizeTuple()
 fw, fh = self.canvas.GetSizeTuple()
 self.toolbar.SetSize(wxSize(fw, th))
 # Create a figure manager to manage things
 # Now put all into a sizer
 sizer = wxBoxSizer(wxVERTICAL)
 # This way of adding to sizer allows resizing
 sizer.Add(self.canvas, 1, wxLEFT|wxTOP|wxGROW)
 # Best to allow the toolbar to resize!
 sizer.Add(self.toolbar, 0, wxGROW)
 self.SetSizer(sizer)
 self.Fit()
 EVT_TIMER(self, TIMER_ID, self.onTimer)
 self.cnt = 0
 def init_plot_data(self):
 # jdh you can add a subplot directly from the fig rather than
 # the fig manager
 a = self.fig.add_subplot(111)
 self.x = numerix.arange(120.0)*2*numerix.pi/120.0
 self.x.resize((100,120))
 self.y = numerix.arange(100.0)*2*numerix.pi/100.0
 self.y.resize((120,100))
 self.y = numerix.transpose(self.y)
 z = numerix.sin(self.x) + numerix.cos(self.y)
 self.im = a.imshow( z, cmap=cm.jet)#, interpolation='nearest')
 def GetToolBar(self):
 # You will need to override GetToolBar if you are using an 
 # unmanaged toolbar in your frame
 return self.toolbar
		
 def onTimer(self, evt):
 self.x += numerix.pi/15
 self.y += numerix.pi/20
 z = numerix.sin(self.x) + numerix.cos(self.y)
 self.im.set_array(z)
 self.canvas.draw()
 #self.canvas.gui_repaint() # jdh wxagg_draw calls this already
 val = report_memory(self.cnt)
 if self.cnt==1:
 self.start = val # skip cnt=0
 self.tstart = time.time()
 elif self.cnt==50:
 end = val
 print 'Average memory consumed per loop: %1.4f\n' % ((end-self.start)/float(self.cnt))
 print 'FPS', self.cnt/(time.time() - self.tstart)
 sys.exit()
 
 self.cnt += 1
 gc.collect()
 
 def onEraseBackground(self, evt):
 # this is supposed to prevent redraw flicker on some X servers...
 pass
 
if __name__ == '__main__':
 app = wxPySimpleApp()
 frame = PlotFigure()
 frame.init_plot_data()
 
 # Initialise the timer - wxPython requires this to be connected to the
 # receivicng event handler
 t = wxTimer(frame, TIMER_ID)
 t.Start(200)
 
 frame.Show()
 app.MainLoop()
From: Jim B. <jb...@se...> - 2004年07月01日 21:37:53
Hi John,
 Today i finally got around to trying a suggestion 
that you made on May 22...on how to put a legend on a Figure
(outside of the axis). So i hacked up the example 
legendDemo.py to experiment with:
# Haked up legendDemp.py
# Thanks to Charles Twardy for this example
from matplotlib.matlab import *
a = arange(0,3,.02)
b = arange(0,3,.02)
c=exp(a)
d=c.tolist()
d.reverse()
d = array(d)
ax = subplot(111)
lines = plot(a,c,'k--',a,d,'k:',a,c+d,'k')
#legend(('Model length', 'Data length', 'Total message length'), 'upper 
left')
fig = gcf()
line1 = lines[0]
line2 = lines[1]
line3 = lines[2]
fig.legend((line1, line2, line3),
 ('Model length', 'Data length', 'Total message length'),
 'upper left')
ax.set_ylim([-1,20])
ax.grid(0)
xlabel('Model complexity --->')
ylabel('Message length --->')
title('Minimum Message Length')
set(gca(), 'yticklabels', [])
set(gca(), 'xticklabels', [])
savefig('legend_demo_small', dpi=60)
savefig('legend_demo_large', dpi=120)
show()
# End of: Haked up legendDemp.py
I then go the following error:
clavius:/home/jbenson/python>python legendDemo.py
Traceback (most recent call last):
 File "legendDemo.py", line 22, in ?
 'upper left')
 File "/usr/local/lib/python2.3/site-packages/matplotlib/figure.py", line 
179, in legend
 l = Legend(handles, labels, loc)
TypeError: __init__() takes exactly 5 arguments (4 given)
clavius:/home/jbenson/python>
Should that line 179 in figure.py be:
 l = Legend(self, handles, labels, loc) # -added ->self<- ?
Just for fun, i tried that change and re-ran:
clavius:/home/jbenson/python>python legendDemo.py
Traceback (most recent call last):
 File "legendDemo.py", line 22, in ?
 'upper left')
 File "/usr/local/lib/python2.3/site-packages/matplotlib/figure.py", line 
179, in legend
 l = Legend(self, handles, labels, loc)
 File "/usr/local/lib/python2.3/site-packages/matplotlib/legend.py", line 
107, in __init__
 self._texts = self._get_texts(labels, textleft, upper)
 File "/usr/local/lib/python2.3/site-packages/matplotlib/legend.py", line 
215, in _get_texts
 HEIGHT = self._approx_text_height()
 File "/usr/local/lib/python2.3/site-packages/matplotlib/legend.py", line 
126, in _approx_text_height
 return 
self.FONTSIZE/72.0*self.figure.dpi.get()/self.parent.bbox.height()
AttributeError: 'NoneType' object has no attribute 'dpi'
clavius:/home/jbenson/python>
...so those errors look worse.
(i'm using matplotlib-0.54.2)
Any more hints?
Thanks,
Jim 
From: John H. <jdh...@ac...> - 2004年07月03日 21:42:00
>>>>> "Jim" == Jim Benson <jb...@se...> writes:
 Jim> Any more hints?
Make that
 l = Legend(self, handles, labels, loc)
Should work - let me know if you have any more troubles.
JDH
From: Jim B. <jb...@se...> - 2004年07月04日 02:14:44
On Sat, 3 Jul 2004, John Hunter wrote:
> Make that
> 
> l = Legend(self, handles, labels, loc)
> 
> Should work - let me know if you have any more troubles.
> 
Thanks John...i did actually try that before i sent my
previous email...sorry that the error messages were buried 
under a bunch of other stuff. I did have a problem after 
i added the self. Here is what i get (my hacked up legendDemp.py follows 
the error messages):
floyd:/home/jbenson/python>python legendDemo.py
Traceback (most recent call last):
 File "legendDemo.py", line 30, in ?
 'upper left')
 File "/usr/local/lib/python2.3/site-packages/matplotlib/figure.py", line 
179, in legend
 l = Legend(self, handles, labels, loc)
 File "/usr/local/lib/python2.3/site-packages/matplotlib/legend.py", line 
107, in __init__
 self._texts = self._get_texts(labels, textleft, upper)
 File "/usr/local/lib/python2.3/site-packages/matplotlib/legend.py", line 
215, in _get_texts
 HEIGHT = self._approx_text_height()
 File "/usr/local/lib/python2.3/site-packages/matplotlib/legend.py", line 
126, in _approx_text_height
 return 
self.FONTSIZE/72.0*self.figure.dpi.get()/self.parent.bbox.height()
AttributeError: 'NoneType' object has no attribute 'dpi'
floyd:/home/jbenson/python>
 
# legendDemo.py
 
from matplotlib.matlab import *
 
a = arange(0,3,.02)
b = arange(0,3,.02)
c=exp(a)
d=c.tolist()
d.reverse()
d = array(d)
 
ax = subplot(111)
lines = plot(a,c,'k--',a,d,'k:',a,c+d,'k')
 
bNotHacked = False
 
if bNotHacked:
 
 legend(('Model length', 'Data length', 'Total message length'), 'upper 
left')
 
else:
 
 fig = gcf()
 
 line1 = lines[0]
 line2 = lines[1]
 line3 = lines[2]
 
 fig.legend((line1, line2, line3),
 ('Model length', 'Data length', 'Total message length'),
 'upper left')
 
ax.set_ylim([-1,20])
ax.grid(0)
xlabel('Model complexity --->')
ylabel('Message length --->')
title('Minimum Message Length')
set(gca(), 'yticklabels', [])
set(gca(), 'xticklabels', [])
 
savefig('legend_demo_small', dpi=60)
savefig('legend_demo_large', dpi=120)
 
show()
~
Jim
 
From: Andrew S. <str...@as...> - 2004年07月10日 06:31:30
John Hunter wrote:
>>>>>>"John" == John Hunter <jdh...@ac...> writes:
>>>>>> 
>>>>>>
>
> John> Haven't had a chance to test your example yet but hopefully
> John> I can take a look tomorrow. I haven't done much memory leak
> John> testing against the _image module yet so this will be a good
> John> opportunity. I very recently rewrote _image.cpp using cxx.
> John> I trust you have a fresh CVS checkout?
>
>Hi Andrew - found and fixed the memory leak. Can't really call it a
>leak - more like a "memory gusher". This was in the agg (and image)
> 
>
That makes a HUGE difference -- great!
>I made a number of comments in your example to point out places where
>you probably should be using matplotlib a little differently.
> 
>
OK, I see I have a lot of learning to do! It's a lot cleaner now, but I 
left comments in for "common pitfalls to avoid when embedding in wx" 
enthusiasts.
>Please add it to CVS.
> 
>
Done.
>I liked the example so much I made an analogous one dynamic_image_gtk.
> 
>
Cool! The GTK demo is nice because of the simplicity allowed by not 
embedding in a foreign GUI, but mainly using the matplotlib interface.
>It's faster than wxagg (13FPS vs 4FPS on my system) which is not
>surprising since gtkagg has extension code to transfer agg to the GUI
>canvas, 
>
It's even less surprising given that the wxagg app is driven by a timer 
callback set to run at 5 FPS! :)
>and doesn't flicker. Very nice! I would really like to get
>that wxagg flicker problem figured out, and the extension code
>added... Did I hear you volunteering to be the wxagg maintainer :-)?
> 
>
Well, I'll hopefully have a chance to poke around in wxagg once in a 
while, but "maintainer" may be a bit grandiose for my time availability 
in the forseeable futurue...
Cheers!
Andrew
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /