Revision: 4787
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4787&view=rev
Author:   mdboom
Date:     2007-12-21 11:40:59 -0800 (Fri, 21 Dec 2007)

Log Message:
-----------
Merged revisions 4773-4785 via svnmerge from 
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib

........
  r4783 | mdboom | 2007-12-21 10:08:38 -0500 (Fri, 21 Dec 2007) | 2 lines
  
  Add size-dependent highly-accurate arc drawing.
........
  r4785 | jdh2358 | 2007-12-21 11:22:42 -0500 (Fri, 21 Dec 2007) | 2 lines
  
  added unit support to arc
........

Modified Paths:
--------------
    branches/transforms/API_CHANGES
    branches/transforms/CODING_GUIDE
    branches/transforms/examples/units/ellipse_with_units.py
    branches/transforms/lib/matplotlib/axes.py
    branches/transforms/lib/matplotlib/legend.py
    branches/transforms/lib/matplotlib/mlab.py
    branches/transforms/lib/matplotlib/patches.py
    branches/transforms/unit/ellipse_large.py

Property Changed:
----------------
    branches/transforms/


Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
   - /trunk/matplotlib:1-4772
   + /trunk/matplotlib:1-4785

Modified: branches/transforms/API_CHANGES
===================================================================
--- branches/transforms/API_CHANGES     2007-12-21 18:53:29 UTC (rev 4786)
+++ branches/transforms/API_CHANGES     2007-12-21 19:40:59 UTC (rev 4787)
@@ -169,6 +169,9 @@
 
 END OF TRANSFORMS REFACTORING
 
+    For csv2rec, checkrows=0 is the new default indicating all rows
+    will be checked for type inference
+
     A warning is issued when an image is drawn on log-scaled
     axes, since it will not log-scale the image data.
 

Modified: branches/transforms/CODING_GUIDE
===================================================================
--- branches/transforms/CODING_GUIDE    2007-12-21 18:53:29 UTC (rev 4786)
+++ branches/transforms/CODING_GUIDE    2007-12-21 19:40:59 UTC (rev 4787)
@@ -12,6 +12,9 @@
 # checking out the main src
 svn co 
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/trunk/matplotlib 
matplotlib --username=youruser --password=yourpass
 
+# branch checkouts, eg the transforms branch 
+svn co 
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/transforms 
transbranch
+
 == Committing changes ==
 
 When committing changes to matplotlib, there are a few things to bear
@@ -27,12 +30,6 @@
     support 2.3, so avoid 2.4 only features like decorators until we
     remove 2.3 support
 
-  * Are your changes Numeric, numarray and numpy compatible?  Try
-    running simple_plot.py or image_demo.py with --Numeric, --numarray
-    and --numpy (Note, someone should add examples to
-    backend_driver.py which explicitly require numpy, numarray and
-    Numeric so we can automatically catch these)
-
   * Can you pass examples/backend_driver.py?  This is our poor man's
     unit test.
 
@@ -49,9 +46,8 @@
 For numpy, use:
 
     import numpy as npy
-    ...
     a = npy.array([1,2,3])
-    ...
+    
 
 For masked arrays, use:
     import matplotlib.numerix.npyma as ma
@@ -64,16 +60,20 @@
 For matplotlib main module, use:
 
     import matplotlib as mpl
-    ...
     mpl.rcParams['xtick.major.pad'] = 6
 
-For matplotlib modules, use:
+For matplotlib modules (or any other modules), use:
 
-    import matplotlib.cbook as cbook as mpl_cbook
-    ...
-    if mpl_cbook.iterable(z):
-        ...
+    import matplotlib.cbook as cbook 
+    
+    if cbook.iterable(z):
+        pass
 
+    We prefer this over the equivalent 'from matplotlib import cbook'
+    because the latter is ambiguous whether cbook is a module or a
+    function to the new developer.  The former makes it explcit that
+    you are importing a module or package.
+
 == Naming, spacing, and formatting conventions ==
 
 In general, we want to hew as closely as possible to the standard
@@ -114,15 +114,6 @@
 python, C and C++
 
 
-When importing modules from the matplotlib namespace
-
-  import matplotlib.cbook as cbook   # DO
-  from matplotlib import cbook       #DONT
-
-because the latter is ambiguous whether cbook is a module or a
-function to the new developer.  The former makes it explcit that you
-are importing a module or package.
-
 ; and similarly for c++-mode-hook and c-mode-hook
 (add-hook 'python-mode-hook
           (lambda ()

Modified: branches/transforms/examples/units/ellipse_with_units.py
===================================================================
--- branches/transforms/examples/units/ellipse_with_units.py    2007-12-21 
18:53:29 UTC (rev 4786)
+++ branches/transforms/examples/units/ellipse_with_units.py    2007-12-21 
19:40:59 UTC (rev 4787)
@@ -1,5 +1,5 @@
 """
-Compare the ellipse generated with arcs versus a polygonal approximation 
+Compare the ellipse generated with arcs versus a polygonal approximation
 """
 from basic_units import cm
 import numpy as npy
@@ -46,4 +46,24 @@
 #fig.savefig('ellipse_compare.png')
 fig.savefig('ellipse_compare')
 
+fig = figure()
+ax = fig.add_subplot(211, aspect='auto')
+ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow', linewidth=1, 
zorder=1)
+
+e1 = patches.Arc((xcenter, ycenter), width, height,
+             angle=angle, linewidth=2, fill=False, zorder=2)
+
+ax.add_patch(e1)
+
+ax = fig.add_subplot(212, aspect='equal')
+ax.fill(x, y, alpha=0.2, facecolor='green', edgecolor='green', zorder=1)
+e2 = patches.Arc((xcenter, ycenter), width, height,
+             angle=angle, linewidth=2, fill=False, zorder=2)
+
+
+ax.add_patch(e2)
+
+#fig.savefig('arc_compare.png')
+fig.savefig('arc_compare')
+
 show()

Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py  2007-12-21 18:53:29 UTC (rev 
4786)
+++ branches/transforms/lib/matplotlib/axes.py  2007-12-21 19:40:59 UTC (rev 
4787)
@@ -321,6 +321,8 @@
                 ret.append(seg)
 
             def makefill(x, y):
+                x = self.axes.convert_xunits(x)
+                y = self.axes.convert_yunits(y)
                 facecolor = self._get_next_cycle_color()
                 seg = mpatches.Polygon(zip(x, y),
                               facecolor = facecolor,
@@ -363,6 +365,8 @@
 
         def makefill(x, y):
             facecolor = color
+            x = self.axes.convert_xunits(x)
+            y = self.axes.convert_yunits(y)
             seg = mpatches.Polygon(zip(x, y),
                           facecolor = facecolor,
                           fill=True,

Modified: branches/transforms/lib/matplotlib/legend.py
===================================================================
--- branches/transforms/lib/matplotlib/legend.py        2007-12-21 18:53:29 UTC 
(rev 4786)
+++ branches/transforms/lib/matplotlib/legend.py        2007-12-21 19:40:59 UTC 
(rev 4787)
@@ -140,7 +140,7 @@
         self._offsetTransform = Affine2D()
         self._parentTransform = BboxTransformTo(parent.bbox)
         Artist.set_transform(self, self._offsetTransform + 
self._parentTransform)
-        
+
         if loc is None:
             loc = rcParams["legend.loc"]
             if not self.isaxes and loc in [0,'best']:
@@ -226,7 +226,7 @@
         bboxesAll = bboxesText
         bboxesAll.extend(bboxesHandles)
         bbox = Bbox.union(bboxesAll)
-        
+
         self.save = bbox
 
         ibox = bbox.inverse_transformed(self.get_transform())
@@ -328,7 +328,7 @@
 
             if isinstance(handle, Rectangle):
                 transform = handle.get_data_transform() + inverse_transform
-                bboxes.append(handle._bbox.transformed(transform))
+                bboxes.append(handle.get_bbox().transformed(transform))
             else:
                 transform = handle.get_transform() + inverse_transform
                 bboxes.append(handle.get_path().get_extents(transform))
@@ -499,7 +499,7 @@
         bbox = bbox.expanded(1 + self.pad, 1 + self.pad)
         l, b, w, h = bbox.bounds
         self.legendPatch.set_bounds(l, b, w, h)
-        
+
         ox, oy = 0, 0                           # center
 
         if iterable(self._loc) and len(self._loc)==2:

Modified: branches/transforms/lib/matplotlib/mlab.py
===================================================================
--- branches/transforms/lib/matplotlib/mlab.py  2007-12-21 18:53:29 UTC (rev 
4786)
+++ branches/transforms/lib/matplotlib/mlab.py  2007-12-21 19:40:59 UTC (rev 
4787)
@@ -2045,7 +2045,7 @@
     return newrec.view(npy.recarray)
 
 
-def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',',
+def csv2rec(fname, comments='#', skiprows=0, checkrows=0, delimiter=',',
             converterd=None, names=None, missing=None):
     """
     Load data from comma/space/tab delimited file in fname into a
@@ -2075,7 +2075,7 @@
     names, if not None, is a list of header names.  In this case, no
     header will be read from the file
 
-    if no rows are found, None is returned See examples/loadrec.py
+    if no rows are found, None is returned -- see examples/loadrec.py
     """
 
     if converterd is None:

Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py       2007-12-21 18:53:29 UTC 
(rev 4786)
+++ branches/transforms/lib/matplotlib/patches.py       2007-12-21 19:40:59 UTC 
(rev 4787)
@@ -366,10 +366,11 @@
 
         Patch.__init__(self, **kwargs)
 
-        left, right = self.convert_xunits((xy[0], xy[0] + width))
-        bottom, top = self.convert_yunits((xy[1], xy[1] + height))
-       self._bbox = transforms.Bbox.from_extents(left, bottom, right, top)
-       self._rect_transform = transforms.BboxTransformTo(self._bbox)
+        self._x = xy[0]
+        self._y = xy[1]
+        self._width = width
+        self._height = height
+        self._rect_transform = transforms.IdentityTransform()
     __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
     def get_path(self):
@@ -378,6 +379,19 @@
         """
        return Path.unit_rectangle()
 
+    def _update_patch_transform(self):
+        x = self.convert_xunits(self._x)
+        y = self.convert_yunits(self._y)
+        width = self.convert_xunits(self._width)
+        height = self.convert_yunits(self._height)
+        bbox = transforms.Bbox.from_bounds(x, y, width, height)
+        self._rect_transform = transforms.BboxTransformTo(bbox)
+        self._combined_transform = self._rect_transform + 
artist.Artist.get_transform(self)
+
+    def draw(self, renderer):
+        self._update_patch_transform()
+        Patch.draw(self, renderer)
+
     def get_patch_transform(self):
        return self._rect_transform
 
@@ -388,19 +402,19 @@
 
     def get_x(self):
         "Return the left coord of the rectangle"
-        return self._bbox.x0
+        return self._x
 
     def get_y(self):
         "Return the bottom coord of the rectangle"
-        return self._bbox.y0
+        return self._y
 
     def get_width(self):
         "Return the width of the  rectangle"
-        return self._bbox.width
+        return self._width
 
     def get_height(self):
         "Return the height of the rectangle"
-        return self._bbox.height
+        return self._height
 
     def set_x(self, x):
         """
@@ -408,9 +422,7 @@
 
         ACCEPTS: float
         """
-        w = self._bbox.width
-        x = self.convert_xunits(x)
-        self._bbox.intervalx = (x, x + w)
+        self._x = x
 
     def set_y(self, y):
         """
@@ -418,9 +430,7 @@
 
         ACCEPTS: float
         """
-        h = self._bbox.height
-        y = self.convert_yunits(y)
-        self._bbox.intervaly = (y, y + h)
+        self._y = y
 
     def set_width(self, w):
         """
@@ -428,8 +438,7 @@
 
         ACCEPTS: float
         """
-        w = self.convert_xunits(w)
-        self._bbox.x1 = self._bbox.x0 + w
+        self._width = w
 
     def set_height(self, h):
         """
@@ -437,8 +446,7 @@
 
         ACCEPTS: float
         """
-        h = self.convert_yunits(h)
-        self._bbox.y1 = self._bbox.y0 + h
+        self._height = h
 
     def set_bounds(self, *args):
         """
@@ -450,10 +458,13 @@
             l,b,w,h = args[0]
         else:
             l,b,w,h = args
-        l, w = self.convert_xunits((l, w))
-        b, h = self.convert_yunits((b, h))
-        self._bbox.bounds = l,b,w,h
+        self._x = l
+        self._y = b
+        self._width = w
+        self._height = h
 
+    def get_bbox(self):
+        return transforms.Bbox.from_bounds(self._x, self._y, self._width, 
self._height)
 
 class RegularPolygon(Patch):
     """
@@ -494,7 +505,6 @@
     def _get_xy(self):
         return self._xy
     def _set_xy(self, xy):
-        self._xy = xy
         self._update_transform()
     xy = property(_get_xy, _set_xy)
 
@@ -588,9 +598,23 @@
 
         """
         Patch.__init__(self, **kwargs)
-        self._path = Path.wedge(theta1, theta2)
+        self.center = center
+        self.r = r
+        self.theta1 = theta1
+        self.theta2 = theta2
+        self._patch_transform = transforms.IdentityTransform()
+        self._path = Path.wedge(self.theta1, self.theta2)
+
+    def draw(self, renderer):
+        x = self.convert_xunits(self.center[0])
+        y = self.convert_yunits(self.center[1])
+        rx = self.convert_xunits(self.r)
+        ry = self.convert_yunits(self.r)
         self._patch_transform = transforms.Affine2D() \
-            .scale(r).translate(*center)
+            .scale(rx, ry).translate(x, y)
+        self._combined_transform = self._patch_transform + \
+            artist.Artist.get_transform(self)
+        Patch.draw(self, renderer)
     __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
     def get_path(self):
@@ -806,8 +830,6 @@
         %(Patch)s
 
         """
-        self.center = xy
-        self.radius = radius
         RegularPolygon.__init__(self, xy,
                                 resolution,
                                 radius,
@@ -821,7 +843,7 @@
     A scale-free ellipse
     """
     def __str__(self):
-        return 
"Ellipse(%d,%d;%dx%d)"%(self.center[0],self.center[1],self.width,self.height)
+        return 
"Ellipse(%s,%s;%sx%s)"%(self.center[0],self.center[1],self.width,self.height)
 
     def __init__(self, xy, width, height, angle=0.0, **kwargs):
         """
@@ -835,18 +857,28 @@
         """
         Patch.__init__(self, **kwargs)
 
-        self._center = xy
-        self._width, self._height = width, height
-        self._angle = angle
-        self._recompute_transform()
+        self.center = xy
+        self.width, self.height = width, height
+        self.angle = angle
         self._path = Path.unit_circle()
+        self._patch_transform = transforms.IdentityTransform()
 
     def _recompute_transform(self):
+        center = (self.convert_xunits(self.center[0]),
+                  self.convert_yunits(self.center[1]))
+        width = self.convert_xunits(self.width)
+        height = self.convert_yunits(self.height)
         self._patch_transform = transforms.Affine2D() \
-           .scale(self._width * 0.5, self._height * 0.5) \
-           .rotate_deg(self._angle) \
-           .translate(*self._center)
+           .scale(width * 0.5, height * 0.5) \
+           .rotate_deg(self.angle) \
+           .translate(*center)
+        self._combined_transform = self._patch_transform + \
+            artist.Artist.get_transform(self)
 
+    def draw(self, renderer):
+        self._recompute_transform()
+        Patch.draw(self, renderer)
+
     def get_path(self):
         """
         Return the vertices of the rectangle
@@ -861,27 +893,7 @@
         x, y = self.get_transform().inverted().transform_point((ev.x, ev.y))
         return (x*x + y*y) <= 1.0, {}
 
-    def _get_center(self):
-        return self._center
-    def _set_center(self, center):
-        self._center = center
-        self._recompute_transform()
-    center = property(_get_center, _set_center)
 
-    def _get_xy(self):
-        return self._xy
-    def _set_xy(self, xy):
-        self._xy = xy
-        self._recompute_transform()
-    xy = property(_get_xy, _set_xy)
-
-    def _get_angle(self):
-        return self._angle
-    def _set_angle(self, angle):
-        self._angle = angle
-        self._recompute_transform()
-    angle = property(_get_angle, _set_angle)
-
 class Circle(Ellipse):
     """
     A circle patch
@@ -912,9 +924,14 @@
     """
     An elliptical arc.  Because it performs various optimizations, it
     can not be filled.
+
+    The arc must be used in an Axes instance it cannot be added
+    directly to a Figure) because it is optimized to only render the
+    segments that are inside the axes bounding box with high
+    resolution.
     """
     def __str__(self):
-        return 
"Arc(%d,%d;%dx%d)"%(self.center[0],self.center[1],self.width,self.height)
+        return 
"Arc(%s,%s;%sx%s)"%(self.center[0],self.center[1],self.width,self.height)
 
     def __init__(self, xy, width, height, angle=0.0, theta1=0.0, theta2=360.0, 
**kwargs):
         """
@@ -938,8 +955,8 @@
 
         Ellipse.__init__(self, xy, width, height, angle, **kwargs)
 
-        self._theta1 = theta1
-        self._theta2 = theta2
+        self.theta1 = theta1
+        self.theta2 = theta2
 
     def draw(self, renderer):
         """
@@ -984,13 +1001,20 @@
           pairs of vertices are drawn using the bezier arc
           approximation technique implemented in Path.arc().
         """
+        if not hasattr(self, 'axes'):
+            raise RuntimeError('Arcs can only be used in Axes instances')
+
+        self._recompute_transform()
+
         # Get the width and height in pixels
+        width = self.convert_xunits(self.width)
+        height = self.convert_yunits(self.height)
         width, height = self.get_transform().transform_point(
-            (self._width, self._height))
-        inv_error = (1.0 / 1.89818e-6)
+            (width, height))
+        inv_error = (1.0 / 1.89818e-6) * 0.5
 
         if width < inv_error and height < inv_error:
-            self._path = Path.arc(self._theta1, self._theta2)
+            self._path = Path.arc(self.theta1, self.theta2)
             return Patch.draw(self, renderer)
 
         def iter_circle_intersect_on_line(x0, y0, x1, y1):
@@ -1037,7 +1061,6 @@
                 if x >= x0e and x <= x1e and y >= y0e and y <= y1e:
                     yield x, y
 
-
         # Transforms the axes box_path so that it is relative to the unit
         # circle in the same way that it is relative to the desired
         # ellipse.
@@ -1050,8 +1073,8 @@
         TWOPI = PI * 2.0
         RAD2DEG = 180.0 / PI
         DEG2RAD = PI / 180.0
-        theta1 = self._theta1
-        theta2 = self._theta2
+        theta1 = self.theta1
+        theta2 = self.theta2
         thetas = {}
         # For each of the point pairs, there is a line segment
         for p0, p1 in zip(box_path.vertices[:-1], box_path.vertices[1:]):

Modified: branches/transforms/unit/ellipse_large.py
===================================================================
--- branches/transforms/unit/ellipse_large.py   2007-12-21 18:53:29 UTC (rev 
4786)
+++ branches/transforms/unit/ellipse_large.py   2007-12-21 19:40:59 UTC (rev 
4787)
@@ -6,7 +6,7 @@
 
 import math
 from pylab import *
-from matplotlib.patches import Arc
+from matplotlib.patches import Ellipse, Arc
 
 # given a point x, y
 x = 2692.440
@@ -47,39 +47,75 @@
    ellipseLine = ax.plot( xs, ys, **kwargs )
 
 
+
+
 ##################################################
 # make the axes
-ax = subplot( 211, aspect='equal' )
-ax.set_aspect( 'equal', 'datalim' )
+ax1 = subplot( 311, aspect='equal' )
+ax1.set_aspect( 'equal', 'datalim' )
 
 # make the lower-bound ellipse
 diam = (r - delta) * 2.0
-lower_ellipse = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkgreen" )
-ax.add_patch( lower_ellipse )
+lower_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkgreen" )
+ax1.add_patch( lower_ellipse )
 
 # make the target ellipse
 diam = r * 2.0
-target_ellipse = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkred" )
-ax.add_patch( target_ellipse )
+target_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkred" )
+ax1.add_patch( target_ellipse )
 
 # make the upper-bound ellipse
 diam = (r + delta) * 2.0
-upper_ellipse = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkblue" )
-ax.add_patch( upper_ellipse )
+upper_ellipse = Ellipse( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkblue" )
+ax1.add_patch( upper_ellipse )
 
 # make the target
 diam = delta * 2.0
+target = Ellipse( (x, y), diam, diam, 0.0, fill=False, edgecolor="#DD1208" )
+ax1.add_patch( target )
+
+# give it a big marker
+ax1.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red', 
markersize=10 )
+
+##################################################
+# make the axes
+ax = subplot( 312, aspect='equal' , sharex=ax1, sharey=ax1)
+ax.set_aspect( 'equal', 'datalim' )
+
+# make the lower-bound arc
+diam = (r - delta) * 2.0
+lower_arc = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False, 
edgecolor="darkgreen" )
+ax.add_patch( lower_arc )
+
+# make the target arc
+diam = r * 2.0
+target_arc = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False, edgecolor="darkred" 
)
+ax.add_patch( target_arc )
+
+# make the upper-bound arc
+diam = (r + delta) * 2.0
+upper_arc = Arc( (0.0, 0.0), diam, diam, 0.0, fill=False, edgecolor="darkblue" 
)
+ax.add_patch( upper_arc )
+
+# make the target
+diam = delta * 2.0
 target = Arc( (x, y), diam, diam, 0.0, fill=False, edgecolor="#DD1208" )
 ax.add_patch( target )
 
 # give it a big marker
 ax.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red', 
markersize=10 )
 
+
+
+
+
 ##################################################
 # now lets do the same thing again using a custom ellipse function
 
+
+
 # make the axes
-ax = subplot( 212, aspect='equal', sharex=ax, sharey=ax )
+ax = subplot( 313, aspect='equal', sharex=ax1, sharey=ax1 )
 ax.set_aspect( 'equal', 'datalim' )
 
 # make the lower-bound ellipse
@@ -97,11 +133,17 @@
 # give it a big marker
 ax.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red', 
markersize=10 )
 
+
+# give it a big marker
+ax.plot( [x], [y], marker='x', linestyle='None', mfc='red', mec='red', 
markersize=10 )
+
 ##################################################
 # lets zoom in to see the area of interest
 
-ax.set_xlim(2650, 2735)
-ax.set_ylim(6705, 6735)
+ax1.set_xlim(2650, 2735)
+ax1.set_ylim(6705, 6735)
+
+savefig("ellipse")
 show()
 
-# savefig("ellipse")
+


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: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to