Revision: 7100
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7100&view=rev
Author:   efiring
Date:     2009-05-13 19:59:16 +0000 (Wed, 13 May 2009)

Log Message:
-----------
Experimental clipping of Line _transformed_path to speed zoom and pan.

This can be modified to work with x monotonically decreasing, but
for a first try it works only with x monotonically increasing.
The intention is to greatly speed up zooming and panning into
a small segment of a very long time series (e.g., 10^6 points)
without incurring any significant speed penalty in other situations.

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/lib/matplotlib/axes.py
    trunk/matplotlib/lib/matplotlib/lines.py
    trunk/matplotlib/lib/matplotlib/path.py

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2009-05-12 19:35:25 UTC (rev 7099)
+++ trunk/matplotlib/CHANGELOG  2009-05-13 19:59:16 UTC (rev 7100)
@@ -1,4 +1,11 @@
 ======================================================================
+2009-05-13 When the x-coordinate of a line is monotonically
+           increasing, it is now automatically clipped at
+           the stage of generating the transformed path in
+           the draw method; this greatly speeds up zooming and
+           panning when one is looking at a short segment of
+           a long time series, for example. - EF
+
 2009-05-11 aspect=1 in log-log plot gives square decades.
 
 2009-05-08 clabel takes new kwarg, rightside_up; if False, labels

Modified: trunk/matplotlib/lib/matplotlib/axes.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/axes.py     2009-05-12 19:35:25 UTC (rev 
7099)
+++ trunk/matplotlib/lib/matplotlib/axes.py     2009-05-13 19:59:16 UTC (rev 
7100)
@@ -765,7 +765,10 @@
                 self.xaxis.get_transform(), self.yaxis.get_transform()))
         if hasattr(self, "lines"):
             for line in self.lines:
-                line._transformed_path.invalidate()
+                try:
+                    line._transformed_path.invalidate()
+                except AttributeError:
+                    pass
 
     def get_position(self, original=False):
         'Return the a copy of the axes rectangle as a Bbox'

Modified: trunk/matplotlib/lib/matplotlib/lines.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/lines.py    2009-05-12 19:35:25 UTC (rev 
7099)
+++ trunk/matplotlib/lib/matplotlib/lines.py    2009-05-13 19:59:16 UTC (rev 
7100)
@@ -440,12 +440,22 @@
         self._x = self._xy[:, 0] # just a view
         self._y = self._xy[:, 1] # just a view
 
-        # Masked arrays are now handled by the Path class itself
+        self._subslice = False
+        if len(x) > 100 and self._is_sorted(x):
+            self._subslice = True
         self._path = Path(self._xy)
-        self._transformed_path = TransformedPath(self._path, 
self.get_transform())
-
+        self._transformed_path = None
         self._invalid = False
 
+    def _transform_path(self, subslice=None):
+        # Masked arrays are now handled by the Path class itself
+        if subslice is not None:
+            _path = Path(self._xy[subslice,:])
+        else:
+            _path = self._path
+        self._transformed_path = TransformedPath(_path, self.get_transform())
+
+
     def set_transform(self, t):
         """
         set the Transformation instance used by this artist
@@ -454,7 +464,6 @@
         """
         Artist.set_transform(self, t)
         self._invalid = True
-        # self._transformed_path = TransformedPath(self._path, 
self.get_transform())
 
     def _is_sorted(self, x):
         "return true if x is sorted"
@@ -465,7 +474,15 @@
     def draw(self, renderer):
         if self._invalid:
             self.recache()
-
+        if self._subslice:
+            # Need to handle monotonically decreasing case also...
+            x0, x1 = self.axes.get_xbound()
+            i0, = self._x.searchsorted([x0], 'left')
+            i1, = self._x.searchsorted([x1], 'right')
+            subslice = slice(max(i0-1, 0), i1+1)
+            self._transform_path(subslice)
+        if self._transformed_path is None:
+            self._transform_path()
         renderer.open_group('line2d', self.get_gid())
 
         if not self._visible: return

Modified: trunk/matplotlib/lib/matplotlib/path.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/path.py     2009-05-12 19:35:25 UTC (rev 
7099)
+++ trunk/matplotlib/lib/matplotlib/path.py     2009-05-13 19:59:16 UTC (rev 
7100)
@@ -118,7 +118,10 @@
                                 (len(vertices) >= 128 and
                                  (codes is None or np.all(codes <= 
Path.LINETO))))
         self.simplify_threshold = rcParams['path.simplify_threshold']
-        self.has_nonfinite = not np.isfinite(vertices).all()
+        # The following operation takes most of the time in this
+        # initialization, and it does not appear to be used anywhere;
+        # if it is occasionally needed, it could be made a property.
+        #self.has_nonfinite = not np.isfinite(vertices).all()
         self.codes = codes
         self.vertices = vertices
 


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

------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image 
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to