Revision: 5042
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5042&view=rev
Author:   efiring
Date:     2008-04-12 21:52:41 -0700 (Sat, 12 Apr 2008)

Log Message:
-----------
Speed up zooming and panning of dense images.

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/lib/matplotlib/image.py

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2008-04-13 04:20:54 UTC (rev 5041)
+++ trunk/matplotlib/CHANGELOG  2008-04-13 04:52:41 UTC (rev 5042)
@@ -1,3 +1,5 @@
+2008-04-12 Speed up zooming and panning of dense images. - EF
+
 2008-04-11 Fix global font rcParam setting after initialization
            time. - MGD
 

Modified: trunk/matplotlib/lib/matplotlib/image.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/image.py    2008-04-13 04:20:54 UTC (rev 
5041)
+++ trunk/matplotlib/lib/matplotlib/image.py    2008-04-13 04:52:41 UTC (rev 
5042)
@@ -81,6 +81,7 @@
         self._extent = extent
         self.set_filternorm(filternorm)
         self.set_filterrad(filterrad)
+        self._filterrad = filterrad
 
 
 
@@ -122,13 +123,61 @@
         if self._A is None:
             raise RuntimeError('You must first set the image array or the 
image attribute')
 
+        xmin, xmax, ymin, ymax = self.get_extent()
+        dxintv = xmax-xmin
+        dyintv = ymax-ymin
+
+        # the viewport scale factor
+        sx = dxintv/self.axes.viewLim.width
+        sy = dyintv/self.axes.viewLim.height
+        numrows, numcols = self._A.shape[:2]
+        if sx > 2:
+            x0 = (self.axes.viewLim.x0-xmin)/dxintv * numcols
+            ix0 = max(0, int(x0 - self._filterrad))
+            x1 = (self.axes.viewLim.x1-xmin)/dxintv * numcols
+            ix1 = min(numcols, int(x1 + self._filterrad))
+            xslice = slice(ix0, ix1)
+            xmin_old = xmin
+            xmin = xmin_old + ix0*dxintv/numcols
+            xmax = xmin_old + ix1*dxintv/numcols
+            dxintv = xmax - xmin
+            sx = dxintv/self.axes.viewLim.width
+        else:
+            xslice = slice(0, numcols)
+
+        if sy > 2:
+            y0 = (self.axes.viewLim.y0-ymin)/dyintv * numrows
+            iy0 = max(0, int(y0 - self._filterrad))
+            y1 = (self.axes.viewLim.y1-ymin)/dyintv * numrows
+            iy1 = min(numrows, int(y1 + self._filterrad))
+            if self.origin == 'upper':
+                yslice = slice(numrows-iy1, numrows-iy0)
+            else:
+                yslice = slice(iy0, iy1)
+            ymin_old = ymin
+            ymin = ymin_old + iy0*dyintv/numrows
+            ymax = ymin_old + iy1*dyintv/numrows
+            dyintv = ymax - ymin
+            sy = dyintv/self.axes.viewLim.height
+        else:
+            yslice = slice(0, numrows)
+
+        if xslice != self._oldxslice or yslice != self._oldyslice:
+            self._imcache = None
+            self._oldxslice = xslice
+            self._oldyslice = yslice
+
         if self._imcache is None:
             if self._A.dtype == npy.uint8 and len(self._A.shape) == 3:
-                im = _image.frombyte(self._A, 0)
+                im = _image.frombyte(self._A[xslice,yslice,:], 0)
                 im.is_grayscale = False
             else:
-                x = self.to_rgba(self._A, self._alpha)
-                im = _image.fromarray(x, 0)
+                if self._rgbacache is None:
+                    x = self.to_rgba(self._A, self._alpha)
+                    self._rgbacache = x
+                else:
+                    x = self._rgbacache
+                im = _image.fromarray(x[yslice,xslice], 0)
                 if len(self._A.shape) == 2:
                     im.is_grayscale = self.cmap.is_gray()
                 else:
@@ -150,14 +199,7 @@
 
         im.set_interpolation(self._interpd[self._interpolation])
 
-        xmin, xmax, ymin, ymax = self.get_extent()
-        dxintv = xmax-xmin
-        dyintv = ymax-ymin
 
-        # the viewport scale factor
-        sx = dxintv/self.axes.viewLim.width
-        sy = dyintv/self.axes.viewLim.height
-
         # the viewport translation
         tx = (xmin-self.axes.viewLim.x0)/dxintv * numcols
         ty = (ymin-self.axes.viewLim.y0)/dyintv * numrows
@@ -165,18 +207,14 @@
         l, b, widthDisplay, heightDisplay = self.axes.bbox.bounds
         widthDisplay *= magnification
         heightDisplay *= magnification
-
         im.apply_translation(tx, ty)
-        im.apply_scaling(sx, sy)
 
         # resize viewport to display
         rx = widthDisplay / numcols
         ry = heightDisplay  / numrows
-        im.apply_scaling(rx, ry)
-
+        im.apply_scaling(rx*sx, ry*sy)
         im.resize(int(widthDisplay+0.5), int(heightDisplay+0.5),
                   norm=self._filternorm, radius=self._filterrad)
-
         return im
 
 
@@ -232,6 +270,9 @@
         self._A = X
 
         self._imcache =None
+        self._rgbacache = None
+        self._oldxslice = None
+        self._oldyslice = None
 
     def set_array(self, A):
         """
@@ -409,6 +450,12 @@
         cm.ScalarMappable.set_cmap(self, norm)
 
 class PcolorImage(martist.Artist, cm.ScalarMappable):
+    '''
+    Make a pcolor-style plot with an irregular rectangular grid.
+
+    This uses a variation of the original irregular image code,
+    and it is used by pcolorfast for the corresponding grid type.
+    '''
     def __init__(self, ax,
                  x=None,
                  y=None,


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to