Re: [matplotlib-devel] [patch] RegularPolyCollection.get_transformed_patches speed-up
Tim, I couldn't resist; here is a numerix version of the method, which I committed to svn: def get_transformed_patches(self): # Shouldn't need all these calls to asarray; # the variables should be converted when stored. # Similar speedups with numerix should be attainable # in many other places. verts = asarray(self._verts) offsets = asarray(self._offsets) Npoly = len(offsets) scales = sqrt(asarray(self._sizes)*self._dpi.get()/72.0) Nscales = len(scales) if Nscales >1: scales = resize(scales, (Npoly, 1, 1)) transOffset = self.get_transoffset() xyo = transOffset.numerix_xy(offsets) polys = scales * verts + xyo[:, newaxis, :] return polys It is faster even when there are only three polygons; and as the comment indicates, it would be even faster with additional numpification of the entire class. (Present version with 3 polys, 161 usecs vs 241 usecs; with 1000, 6.4 msec vs 47.3 msec.) It is also only lightly tested. I hope I haven't overlooked some situation that would work with the old version but not with this one. Eric Tim Leslie wrote: > On 5/10/07, Eric Firing <[EMAIL PROTECTED]> wrote: >> Tim, >> >> Based on a *very superficial* quick look, I have two comments: >> >> 1) Since the plan is (or was?) to have one more release before >> specializing to numpy-only support, the ".T" won't work at present. >> >> 2) In the following (possibly mangled by mailer), >> >> > +if Nsizes == 1: >> > +xy = asarray([xverts, yverts]).T * sizes[0] >> > +polys = [xy + offset for offset in >> transOffset.seq_xy_tups(self._offsets)] >> >> I think you can gain additional speedup by eliminating the list >> comprehension. Instead of using seq_xy_tups you can use numerix_xy to >> return a 2-D array (with columns x and y), and simply add that to xy. >> > > Thanks for the feedback Eric, I'll rework the patch with your comments > in mind. I also just noticed a rather glaring bug, in that I don't > actually have a 'return polys' after I calculate them in the special > case, which is somewhat embarrassing. I'll fix all this up and submit > a new patch later today. > > Cheers, > > Tim > >> Eric >> >> >> Tim Leslie wrote: >> > Hi All, >> > >> > I've attached a patch which optimizes a particular case of the >> > RegularPolyCollection.get_transformed_patches method. This is >> > particularly useful when using a picker on a scatter plot with ~40,000 >> > points (as I happen to be doing) and cuts the time spent in this >> > function from ~4s to ~1s, which accounts for about 50% of the lag in >> > my particular use case. >> > >> > Similar improvements might be possible in the N > 1 case, but I don't >> > have a) a data set or b) the time to work them out with, so hopefully >> > someone is happy to check in this patch as it stands, as I think the >> > N==1 is probably the common case. >> > >> > If there are any problems with the patch let me know and I'll try to >> > fix it up. It's against latest svn (3262) >> > >> > Cheers, >> > >> > Tim >> > >> > >> > >> >> > >> > Index: lib/matplotlib/collections.py >> > === >> > --- lib/matplotlib/collections.py (revision 3262) >> > +++ lib/matplotlib/collections.py (working copy) >> > @@ -153,7 +153,7 @@ >> > if not self.pickable(): return >> > ind = [] >> > x, y = mouseevent.x, mouseevent.y >> > -for i, thispoly in enumerate(self.get_transformed_patches()): >> > +for i, thispoly in enumerate(self.get_transformed_patches()): >> > inside = nxutils.pnpoly(x, y, thispoly) >> > if inside: ind.append(i) >> > if len(ind): >> > @@ -167,7 +167,6 @@ >> > The ith element in the returned sequence is a list of x,y >> > vertices defining the ith polygon >> > """ >> > - >> > verts = self._verts >> > offsets = self._offsets >> > usingOffsets = offsets is not None >> > @@ -451,13 +450,19 @@ >> > __init__.__doc__ = dedent(__init__.__doc__) % kwdocd >> > >> > def get_transformed_patches(self): >> > - >> > + >> > xverts, yverts = zip(*self._verts) >> > xverts = asarray(xverts) >> > yverts = asarray(yverts) >> > sizes = sqrt(asarray(self._sizes)*self._dpi.get()/72.0) >> > Nsizes = len(sizes) >> > transOffset = self.get_transoffset() >> > + >> > +# optimize this case for an approx 4x speedup >> > +if Nsizes == 1: >> > +xy = asarray([xverts, yverts]).T * sizes[0] >> > +polys = [xy + offset for offset in >> transOffset.seq_xy_tups(self._offsets)] >> > + >> > polys = [] >> > for i, loc in enumerate(self._offsets): >> > xo,yo = tr
Re: [matplotlib-devel] [patch] RegularPolyCollection.get_transformed_patches speed-up
Hi Eric, I just checked out your change and it works another 0.2s faster than what I had for my example, so I'm more than happy with the final result. Thanks for taking the time to put my hazy ideas into practice the right way :-) Cheers, Tim On 5/10/07, Eric Firing <[EMAIL PROTECTED]> wrote: > Tim, > > I couldn't resist; here is a numerix version of the method, which I > committed to svn: > > def get_transformed_patches(self): > # Shouldn't need all these calls to asarray; > # the variables should be converted when stored. > # Similar speedups with numerix should be attainable > # in many other places. > verts = asarray(self._verts) > offsets = asarray(self._offsets) > Npoly = len(offsets) > scales = sqrt(asarray(self._sizes)*self._dpi.get()/72.0) > Nscales = len(scales) > if Nscales >1: > scales = resize(scales, (Npoly, 1, 1)) > transOffset = self.get_transoffset() > xyo = transOffset.numerix_xy(offsets) > polys = scales * verts + xyo[:, newaxis, :] > return polys > > It is faster even when there are only three polygons; and as the comment > indicates, it would be even faster with additional numpification of the > entire class. (Present version with 3 polys, 161 usecs vs 241 usecs; > with 1000, 6.4 msec vs 47.3 msec.) > > It is also only lightly tested. I hope I haven't overlooked some > situation that would work with the old version but not with this one. > > Eric > > Tim Leslie wrote: > > On 5/10/07, Eric Firing <[EMAIL PROTECTED]> wrote: > >> Tim, > >> > >> Based on a *very superficial* quick look, I have two comments: > >> > >> 1) Since the plan is (or was?) to have one more release before > >> specializing to numpy-only support, the ".T" won't work at present. > >> > >> 2) In the following (possibly mangled by mailer), > >> > >> > +if Nsizes == 1: > >> > +xy = asarray([xverts, yverts]).T * sizes[0] > >> > +polys = [xy + offset for offset in > >> transOffset.seq_xy_tups(self._offsets)] > >> > >> I think you can gain additional speedup by eliminating the list > >> comprehension. Instead of using seq_xy_tups you can use numerix_xy to > >> return a 2-D array (with columns x and y), and simply add that to xy. > >> > > > > Thanks for the feedback Eric, I'll rework the patch with your comments > > in mind. I also just noticed a rather glaring bug, in that I don't > > actually have a 'return polys' after I calculate them in the special > > case, which is somewhat embarrassing. I'll fix all this up and submit > > a new patch later today. > > > > Cheers, > > > > Tim > > > >> Eric > >> > >> > >> Tim Leslie wrote: > >> > Hi All, > >> > > >> > I've attached a patch which optimizes a particular case of the > >> > RegularPolyCollection.get_transformed_patches method. This is > >> > particularly useful when using a picker on a scatter plot with ~40,000 > >> > points (as I happen to be doing) and cuts the time spent in this > >> > function from ~4s to ~1s, which accounts for about 50% of the lag in > >> > my particular use case. > >> > > >> > Similar improvements might be possible in the N > 1 case, but I don't > >> > have a) a data set or b) the time to work them out with, so hopefully > >> > someone is happy to check in this patch as it stands, as I think the > >> > N==1 is probably the common case. > >> > > >> > If there are any problems with the patch let me know and I'll try to > >> > fix it up. It's against latest svn (3262) > >> > > >> > Cheers, > >> > > >> > Tim > >> > > >> > > >> > > >> > >> > > >> > Index: lib/matplotlib/collections.py > >> > === > >> > --- lib/matplotlib/collections.py (revision 3262) > >> > +++ lib/matplotlib/collections.py (working copy) > >> > @@ -153,7 +153,7 @@ > >> > if not self.pickable(): return > >> > ind = [] > >> > x, y = mouseevent.x, mouseevent.y > >> > -for i, thispoly in enumerate(self.get_transformed_patches()): > >> > +for i, thispoly in enumerate(self.get_transformed_patches()): > >> > inside = nxutils.pnpoly(x, y, thispoly) > >> > if inside: ind.append(i) > >> > if len(ind): > >> > @@ -167,7 +167,6 @@ > >> > The ith element in the returned sequence is a list of x,y > >> > vertices defining the ith polygon > >> > """ > >> > - > >> > verts = self._verts > >> > offsets = self._offsets > >> > usingOffsets = offsets is not None > >> > @@ -451,13 +450,19 @@ > >> > __init__.__doc__ = dedent(__init__.__doc__) % kwdocd > >> > > >> > def get_transformed_patches(self): > >> > - > >> > + > >> > xverts, yverts = zip(*self._verts) > >> > xverts = asarray(xverts) > >> > yverts = asarray(yverts)
[matplotlib-devel] SaveFig bug in TkAgg backend
Hi, When the "save" button is used on the matplotlib tkagg toolbar, it uses the "Tk" "asksavefilename" object from the "tkFileDialog" class, to pop up a little window that allows you to select the name and type of file to save.This function internally calls "figure.destroy()". and the currently active figure gets destroyed (but it is still visible and memory is not freed). The next plot then creates a new figure window with the same figure._num as the previous. see... backend_tkagg.py : line 621 -> class NavigationToolbar2TkAgg :: def save_figure(...) (callback for the toolbar.bsave button) The "asksavefilename" function call, triggers Gcf.destroy(). This can be seen by placing a print statement in _pylab_helpers.py : line 16 -> class Gcf :: def destroy(num) A script to trigger this is attached Does anyone else see this, and does anyone have a way to fix this ? Thank you very much ! Regards, Urvashi Rau savetest.py Description: application/python - This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/___ Matplotlib-devel mailing list Matplotlib-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-devel