Revision: 3830
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3830&view=rev
Author:   mdboom
Date:     2007-09-11 10:56:13 -0700 (Tue, 11 Sep 2007)

Log Message:
-----------
Just marking a milestone -- about to totally rip things up again.

Modified Paths:
--------------
    branches/transforms/lib/matplotlib/affine.py
    branches/transforms/lib/matplotlib/artist.py
    branches/transforms/lib/matplotlib/axes.py
    branches/transforms/lib/matplotlib/backend_bases.py
    branches/transforms/lib/matplotlib/backends/backend_agg.py
    branches/transforms/lib/matplotlib/backends/backend_tkagg.py
    branches/transforms/lib/matplotlib/bbox.py
    branches/transforms/lib/matplotlib/figure.py
    branches/transforms/lib/matplotlib/lines.py
    branches/transforms/lib/matplotlib/patches.py
    branches/transforms/lib/matplotlib/text.py
    branches/transforms/src/_backend_agg.cpp

Modified: branches/transforms/lib/matplotlib/affine.py
===================================================================
--- branches/transforms/lib/matplotlib/affine.py        2007-09-11 12:46:27 UTC 
(rev 3829)
+++ branches/transforms/lib/matplotlib/affine.py        2007-09-11 17:56:13 UTC 
(rev 3830)
@@ -58,10 +58,8 @@
        self.mtx = matrix
 
     def __repr__(self):
-       return repr(self.mtx)
-
-    def __str__(self):
-       return str(self.mtx)
+       return "Affine2D(%s)" % repr(self.mtx)
+    __str__ = __repr__
     
     [EMAIL PROTECTED]
     def from_values(a, b, c, d, e, f):
@@ -156,8 +154,8 @@
 
 class BlendedAffine2D(Affine2D):
     def __init__(self, x_transform, y_transform):
-       assert isinstance(x_transform, Affine2D)
-       assert isinstance(y_transform, Affine2D)
+#      assert isinstance(x_transform, Affine2D)
+#      assert isinstance(y_transform, Affine2D)
        assert x_transform.is_separable()
        assert y_transform.is_separable()
        x_mtx = x_transform.mtx

Modified: branches/transforms/lib/matplotlib/artist.py
===================================================================
--- branches/transforms/lib/matplotlib/artist.py        2007-09-11 12:46:27 UTC 
(rev 3829)
+++ branches/transforms/lib/matplotlib/artist.py        2007-09-11 17:56:13 UTC 
(rev 3830)
@@ -138,6 +138,7 @@
 
         ACCEPTS: a matplotlib.transform transformation instance
         """
+       print "set_transform", t
         self._transform = t
         self._transformSet = True
         self.pchanged()

Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py  2007-09-11 12:46:27 UTC (rev 
3829)
+++ branches/transforms/lib/matplotlib/axes.py  2007-09-11 17:56:13 UTC (rev 
3830)
@@ -10,9 +10,9 @@
 
 from matplotlib import artist as martist
 from matplotlib import affine as maffine
-from matplotlib import bbox as mbbox
 from matplotlib import agg
 from matplotlib import axis as maxis
+from matplotlib import bbox as mbbox
 from matplotlib import cbook
 from matplotlib import collections as mcoll
 from matplotlib import colors as mcolors
@@ -33,9 +33,9 @@
 
 iterable = cbook.iterable
 is_string_like = cbook.is_string_like
+Wrapper = cbook.Wrapper
 
 
-
 def delete_masked_points(*args):
     """
     Find all masked points in a set of arguments, and return
@@ -437,7 +437,6 @@
               1 : 'log',
               }
 
-    
     def __str__(self):
         return 
"Axes(%g,%g;%gx%g)"%(self._position[0].get(),self._position[1].get(),
                                     
self._position[2].get(),self._position[3].get())
@@ -535,7 +534,6 @@
         if self.yaxis is not None:
             self._ycid = self.yaxis.callbacks.connect('units finalize', 
self.relim)
 
-
     def get_window_extent(self, *args, **kwargs):
         'get the axes bounding box in display space; args and kwargs are empty'
         return self.bbox
@@ -655,16 +653,16 @@
             bottom = 0.0
             top = 1.0
 
-
-
         self.viewLim = Bbox.from_lbrt(left, bottom, right, top)
-        self.dataLim = Bbox.unit()
-
+       self.dataLim = Bbox.unit()
+       
         self.transData = maffine.get_bbox_transform(
             self.viewLim, self.bbox)
         self.transAxes = maffine.get_bbox_transform(
-            Bbox.unit(), self.bbox)
+            self.dataLim, self.bbox)
 
+       print "_set_lim_and_transforms", self.viewLim, self.transData, 
self.dataLim, self.transAxes, self.bbox
+
        # MGDTODO
 #         if self._sharex:
 #             self.transData.set_funcx(self._sharex.transData.get_funcx())
@@ -677,7 +675,8 @@
         if original:
             return self._originalPosition[:]
         else:
-            return [val.get() for val in self._position]
+            return self._position[:]
+           # return [val.get() for val in self._position]
 
     def set_position(self, pos, which='both'):
         """
@@ -699,10 +698,13 @@
 #             # Change values within self._position--don't replace it.
 #             for num,val in zip(pos, self._position):
 #                 val.set(num)
+           print "set_position", self._position, pos
            self._position = pos
+           # MGDTODO: side-effects
         if which in ('both', 'original'):
             self._originalPosition = pos
-
+           
+           
     def _set_artist_props(self, a):
         'set the boilerplate props for artists added to axes'
         a.set_figure(self.figure)
@@ -1181,7 +1183,10 @@
         #print type(x), type(y)
        # MGDTODO
         ## self.dataLim.update_numerix(x, y, -1)
-       pass
+       print "update_datalim_numerix", self.dataLim,
+       self.dataLim = mbbox.Bbox.from_data(x, y)
+       print self.dataLim
+       # MGDTODO side-effects
 
     def _get_verts_in_data_coords(self, trans, xys):
         if trans == self.transData:
@@ -1190,8 +1195,8 @@
         # display and then back to data to get it in data units
         #xys = trans.seq_xy_tups(xys)
         #return [ self.transData.inverse_xy_tup(xy) for xy in xys]
-        xys = trans.numerix_xy(npy.asarray(xys))
-        return self.transData.inverse_numerix_xy(xys)
+        xys = trans(npy.asarray(xys))
+        return self.transData.inverted()(xys)
 
     def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
         'look for unit kwargs and update the axis instances as necessary'
@@ -1242,7 +1247,8 @@
         axis direction reversal that has already been done.
         """
         # if image data only just use the datalim
-
+       print "autoscale_view"
+       
         if not self._autoscaleon: return
         if (tight or (len(self.images)>0 and
                       len(self.lines)==0 and
@@ -1278,7 +1284,7 @@
         if not self.get_visible(): return
         renderer.open_group('axes')
         self.apply_aspect()
-       # MGDTODO
+       # MGDTODO -- this is where we can finalize all of the transforms
         # self.transData.freeze()  # eval the lazy objects
         # self.transAxes.freeze()
         if self.axison and self._frameon: self.axesPatch.draw(renderer)
@@ -1544,9 +1550,12 @@
 #             raise ValueError('Cannot set nonpositive limits with log 
transform')
 
         xmin, xmax = mbbox.nonsingular(xmin, xmax, increasing=False)
-        self.viewLim.intervalx().set_bounds(xmin, xmax)
-        if emit: self.callbacks.process('xlim_changed', self)
 
+       # MGDTODO: This is fairly cumbersome
+       # MGDTODO: side-effects on x-bounds should propagate
+       self.viewLim = mbbox.Bbox.from_lbrt(xmin, self.viewLim.ymin(), xmax, 
self.viewLim.ymax())
+       print 'set_xlim', self.viewLim
+       
         return xmin, xmax
 
     def get_xscale(self):
@@ -1649,7 +1658,7 @@
         ACCEPTS: len(2) sequence of floats
         """
 
-
+       print "set_ylim", ymin, ymax, emit
         if ymax is None and iterable(ymin):
             ymin,ymax = ymin
 
@@ -1669,9 +1678,11 @@
 #             raise ValueError('Cannot set nonpositive limits with log 
transform')
 
         ymin, ymax = mbbox.nonsingular(ymin, ymax, increasing=False)
-        self.viewLim.intervaly().set_bounds(ymin, ymax)
+       # MGDTODO: side-effects on y-bounds should propagate
+       self.viewLim = mbbox.Bbox.from_lbrt(self.viewLim.xmin(), ymin, 
self.viewLim.xmax(), ymax)
         if emit: self.callbacks.process('ylim_changed', self)
-
+       print "set_ylim", self.viewLim
+       
         return ymin, ymax
 
     def get_yscale(self):
@@ -2158,7 +2169,7 @@
         %(Annotation)s
         """
         a = mtext.Annotation(*args, **kwargs)
-        a.set_transform(maffine.Affine2D.identity())
+        a.set_transform(maffine.Affine2D())
         self._set_artist_props(a)
         if kwargs.has_key('clip_on'):  a.set_clip_box(self.bbox)
         self.texts.append(a)
@@ -2197,7 +2208,7 @@
         %(Line2D)s
         """
 
-        trans = maffine.blend_xy_sep_transform( self.transAxes, self.transData)
+        trans = maffine.blend_xy_sep_transform(self.transAxes, self.transData)
         l, = self.plot([xmin,xmax], [y,y], transform=trans, scalex=False, 
**kwargs)
         return l
 

Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py 2007-09-11 12:46:27 UTC 
(rev 3829)
+++ branches/transforms/lib/matplotlib/backend_bases.py 2007-09-11 17:56:13 UTC 
(rev 3830)
@@ -752,7 +752,7 @@
         else: # Just found one hit
             self.inaxes = axes_list[0]
 
-        try: xdata, ydata = self.inaxes.transData.inverse_xy_tup((x, y))
+        try: xdata, ydata = self.inaxes.transData.inverted()([[x, y]])[0]
         except ValueError:
             self.xdata  = None
             self.ydata  = None

Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py  2007-09-11 
12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py  2007-09-11 
17:56:13 UTC (rev 3830)
@@ -113,11 +113,12 @@
                                      debug=False)
         if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
                                      'debug-annoying')
-        self.draw_polygon = self._renderer.draw_polygon
+        # self.draw_polygon = self._renderer.draw_polygon
         self.draw_rectangle = self._renderer.draw_rectangle
         self.draw_path = self._renderer.draw_path
+       # MGDTODO -- remove these lines
         # self.draw_lines = self._renderer.draw_lines
-        self.draw_markers = self._renderer.draw_markers
+        # self.draw_markers = self._renderer.draw_markers
         self.draw_image = self._renderer.draw_image
         self.draw_line_collection = self._renderer.draw_line_collection
         self.draw_quad_mesh = self._renderer.draw_quad_mesh
@@ -161,8 +162,13 @@
 
     def draw_lines(self, gc, x, y, transform):
        return self._renderer.draw_lines(gc, x, y, transform.to_values())
-       
 
+    def draw_markers(self, gc, path, color, x, y, transform):
+       return self._renderer.draw_markers(gc, path, color, x, y, 
transform.to_values())
+
+    def draw_polygon(self, *args):
+       return self._renderer.draw_polygon(*args)
+    
     def draw_point(self, gc, x, y):
         """
         Draw a single point at x,y
@@ -325,8 +331,10 @@
         """
         if __debug__: verbose.report('RendererAgg.points_to_pixels',
                                      'debug-annoying')
-        return points*self.dpi.get()/72.0
-
+       # MGDTODO
+        # return points*self.dpi.get()/72.0
+        return points*self.dpi/72.0
+    
     def tostring_rgb(self):
         if __debug__: verbose.report('RendererAgg.tostring_rgb',
                                      'debug-annoying')

Modified: branches/transforms/lib/matplotlib/backends/backend_tkagg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_tkagg.py        
2007-09-11 12:46:27 UTC (rev 3829)
+++ branches/transforms/lib/matplotlib/backends/backend_tkagg.py        
2007-09-11 17:56:13 UTC (rev 3830)
@@ -175,7 +175,8 @@
             self._resize_callback(event)
 
         # compute desired figure size in inches
-        dpival = self.figure.dpi.get()
+       # dpival = self.figure.dpi.get() MGDTODO
+       dpival = self.figure.dpi
         winch = width/dpival
         hinch = height/dpival
         self.figure.set_size_inches(winch, hinch)

Modified: branches/transforms/lib/matplotlib/bbox.py
===================================================================
--- branches/transforms/lib/matplotlib/bbox.py  2007-09-11 12:46:27 UTC (rev 
3829)
+++ branches/transforms/lib/matplotlib/bbox.py  2007-09-11 17:56:13 UTC (rev 
3830)
@@ -21,9 +21,6 @@
     def get_bounds(self):
        return self._bounds
 
-    def set_bounds(self, lower, upper):
-       self._bounds = lower, upper
-
     def span(self):
        bounds = self._bounds
        return bounds[1] - bounds[0]
@@ -47,8 +44,23 @@
        return Bbox([[left, bottom], [right, top]])
     from_lbrt = staticmethod(from_lbrt)
 
+    [EMAIL PROTECTED]
+    def from_data(x, y):
+       return Bbox([[x.min(), y.min()], [x.max(), y.max()]])
+    from_data = staticmethod(from_data)
+    
     def copy(self):
        return Bbox(self._points.copy())
+
+    def __repr__(self):
+       return 'Bbox(%s)' % repr(self._points)
+    __str__ = __repr__
+
+    def __cmp__(self, other):
+       # MGDTODO: Totally suboptimal
+       if isinstance(other, Bbox):
+           return (self._points == other._points).all()
+       return -1
     
     # MGDTODO: Probably a more efficient ways to do this...
     def xmin(self):
@@ -79,6 +91,7 @@
        return (self.xmin(), self.ymin(),
                self.xmax() - self.xmin(), self.ymax() - self.ymin())
 
+    # MGDTODO: This is an inefficient way to do this
     def intervalx(self):
        return Interval(self._points[0])
 
@@ -92,10 +105,11 @@
        deltah = (sh * height - height) / 2.0
        a = N.array([[-deltaw, -deltah], [deltaw, deltah]])
        return Bbox(self._points + a)
-       
-def lbwh_to_bbox(left, bottom, width, height):
-    return Bbox([[left, bottom], [left + width, bottom + height]])
-    
+
+    def contains(self, x, y):
+       return (x >= self.xmin() and x <= self.xmax() and
+               y >= self.ymin() and y <= self.ymax())
+
 def bbox_union(bboxes):
     """
     Return the Bbox that bounds all bboxes

Modified: branches/transforms/lib/matplotlib/figure.py
===================================================================
--- branches/transforms/lib/matplotlib/figure.py        2007-09-11 12:46:27 UTC 
(rev 3829)
+++ branches/transforms/lib/matplotlib/figure.py        2007-09-11 17:56:13 UTC 
(rev 3830)
@@ -105,8 +105,9 @@
 class Figure(Artist):
 
     def __str__(self):
-        return "Figure(%gx%g)"%(self.figwidth.get(),self.figheight.get())
-
+        return "Figure(%gx%g)"%(self.figwidth, self.figheight)
+        # return "Figure(%gx%g)"%(self.figwidth.get(),self.figheight.get())
+    
     def __init__(self,
                  figsize   = None,  # defaults to rc figure.figsize
                  dpi       = None,  # defaults to rc figure.dpi
@@ -129,10 +130,9 @@
         if edgecolor is None: edgecolor = rcParams['figure.edgecolor']
 
         self.dpi = dpi
-       self.figsize = figsize
-       self.bbox = Bbox.from_lbwh(0, 0,
-                                  figsize[0] * dpi,
-                                  figsize[1] * dpi)
+       self.figwidth = figsize[0] * dpi
+       self.figheight = figsize[1] * dpi
+       self.bbox = Bbox.from_lbwh(0, 0, self.figwidth, self.figheight)
        
         self.frameon = frameon
 
@@ -324,11 +324,16 @@
             w,h = args[0]
         else:
             w,h = args
-        self.figwidth.set(w)
-        self.figheight.set(h)
 
+       
+        self.figwidth = w
+        self.figheight = h
+        # self.figwidth.set(w) MGDTODO
+        # self.figheight.set(h)
+       
         if forward:
-            dpival = self.dpi.get()
+            # dpival = self.dpi.get()
+            dpival = self.dpi
             canvasw = w*dpival
             canvash = h*dpival
             manager = getattr(self.canvas, 'manager', None)
@@ -336,7 +341,8 @@
                 manager.resize(int(canvasw), int(canvash))
 
     def get_size_inches(self):
-        return self.figwidth.get(), self.figheight.get()
+        return self.figwidth, self.figheight
+        # return self.figwidth.get(), self.figheight.get() MGDTODO
 
     def get_edgecolor(self):
         'Get the edge color of the Figure rectangle'
@@ -348,7 +354,8 @@
 
     def get_figwidth(self):
         'Return the figwidth as a float'
-        return self.figwidth.get()
+       return self.figwidth
+        # return self.figwidth.get() MGDTODO
 
     def get_figheight(self):
         'Return the figheight as a float'
@@ -356,7 +363,8 @@
 
     def get_dpi(self):
         'Return the dpi as a float'
-        return self.dpi.get()
+        return self.dpi
+        # return self.dpi.get() MGDTODO
 
     def get_frameon(self):
         'get the boolean indicating frameon'
@@ -384,7 +392,8 @@
 
         ACCEPTS: float
         """
-        self.dpi.set(val)
+        # self.dpi.set(val) MGDTODO
+       self.dpi = val
 
     def set_figwidth(self, val):
         """
@@ -392,15 +401,17 @@
 
         ACCEPTS: float
         """
-        self.figwidth.set(val)
-
+        # self.figwidth.set(val)  MGDTODO
+        self.figwidth = val
+       
     def set_figheight(self, val):
         """
         Set the height of the figure in inches
 
         ACCEPTS: float
         """
-        self.figheight.set(val)
+       # MGDTODO (set())
+        self.figheight = val
 
     def set_frameon(self, b):
         """

Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py 2007-09-11 12:46:27 UTC (rev 
3829)
+++ branches/transforms/lib/matplotlib/lines.py 2007-09-11 17:56:13 UTC (rev 
3830)
@@ -18,7 +18,7 @@
 from cbook import iterable, is_string_like, is_numlike
 from colors import colorConverter
 
-from bbox import lbwh_to_bbox
+from bbox import Bbox
 from matplotlib import rcParams
 
 # special-purpose marker identifiers:
@@ -368,6 +368,7 @@
        a = npy.vstack((x, y)).swapaxes(0, 1)
        ####
         x, y = self.get_transform()(a)
+       print "get_window_extent", self.get_transform()
        
         #x, y = self.get_transform().seq_x_y(x, y)
 
@@ -384,10 +385,11 @@
             bottom -= ms/2
             width += ms
             height += ms
-        return lbwh_to_bbox(left, bottom, width, height)
+        return Bbox.from_lbwh(left, bottom, width, height)
 
 
     def set_axes(self, ax):
+       print "set_axes"
         Artist.set_axes(self, ax)
         if ax.xaxis is not None:
             self._xcid = ax.xaxis.callbacks.connect('units', self.recache)

Modified: branches/transforms/lib/matplotlib/patches.py
===================================================================
--- branches/transforms/lib/matplotlib/patches.py       2007-09-11 12:46:27 UTC 
(rev 3829)
+++ branches/transforms/lib/matplotlib/patches.py       2007-09-11 17:56:13 UTC 
(rev 3830)
@@ -212,7 +212,7 @@
         tverts = self.get_transform()(verts)
 
        # MGDTODO: This result is an Nx2 numpy array, which could be passed
-       # directly to renderer.draw_polygon.  However, it currently expects
+       # directly to renderer.draw_polygon since it currently expects
        # a list of tuples so we're converting it to that now.
        tverts = [tuple(x) for x in tverts]
        

Modified: branches/transforms/lib/matplotlib/text.py
===================================================================
--- branches/transforms/lib/matplotlib/text.py  2007-09-11 12:46:27 UTC (rev 
3829)
+++ branches/transforms/lib/matplotlib/text.py  2007-09-11 17:56:13 UTC (rev 
3830)
@@ -15,7 +15,7 @@
 from cbook import enumerate, is_string_like, maxdict, is_numlike
 from font_manager import FontProperties
 from patches import bbox_artist, YAArrow
-from bbox import lbwh_to_bbox, bbox_union
+from bbox import Bbox, bbox_union
 from lines import Line2D
 
 import matplotlib.nxutils as nxutils
@@ -40,8 +40,6 @@
         angle = float(rotation)
     return angle%360
 
-_unit_box = lbwh_to_bbox(0,0,1,1)
-
 # these are not available for the object inspector until after the
 # class is build so we define an initial set here for the init
 # function and they will be overridden after object defn
@@ -264,7 +262,7 @@
         ymin += offsety
         ymax += offsety
 
-        bbox = lbwh_to_bbox(xmin, ymin, width, height)
+        bbox = Bbox.from_lbwh(xmin, ymin, width, height)
 
 
         # now rotate the positions around the first x,y position
@@ -423,10 +421,10 @@
 
     def get_window_extent(self, renderer=None):
         #return _unit_box
-        if not self.get_visible(): return _unit_box
+        if not self.get_visible(): return Bbox.unit()
         if self._text == '':
             tx, ty = self._get_xy_display()
-            return lbwh_to_bbox(tx,ty,0,0)
+            return Bbox.from_lbwh(tx,ty,0,0)
 
         if renderer is not None:
             self._renderer = renderer

Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp    2007-09-11 12:46:27 UTC (rev 
3829)
+++ branches/transforms/src/_backend_agg.cpp    2007-09-11 17:56:13 UTC (rev 
3830)
@@ -56,7 +56,7 @@
     throw Py::ValueError("Transformation matrix must be given as a 6-element 
list.");
   }
 
-  agg::trans_affine xytrans = agg::trans_affine
+  return agg::trans_affine
     (Py::Float(seq[0]), 
      Py::Float(seq[1]), 
      Py::Float(seq[2]), 
@@ -1935,18 +1935,8 @@
   if (ya==NULL)
     throw Py::TypeError("RendererAgg::_draw_markers_cache expected numerix 
array");
   
-  Transformation* mpltransform = static_cast<Transformation*>(args[5].ptr());
+  agg::trans_affine xytrans = 
py_sequence_to_agg_transformation_matrix(args[5]);
   
-  double a, b, c, d, tx, ty;
-  try {
-    mpltransform->affine_params_api(&a, &b, &c, &d, &tx, &ty);
-  }
-  catch(...) {
-    throw Py::ValueError("Domain error on affine_params_api in 
RendererAgg::_draw_markers_cache");
-  }
-  
-  agg::trans_affine xytrans = agg::trans_affine(a,b,c,d,tx,ty);
-  
   size_t Nx = xa->dimensions[0];
   size_t Ny = ya->dimensions[0];
   
@@ -2006,15 +1996,16 @@
   for (size_t i=0; i<Nx; i++) {
     thisx = *(double *)(xa->data + i*xa->strides[0]);
     thisy = *(double *)(ya->data + i*ya->strides[0]);
+
+    // MGDTODO
+//     if (mpltransform->need_nonlinear_api())
+//       try {
+//     mpltransform->nonlinear_only_api(&thisx, &thisy);
+//       }
+//       catch(...) {
+//     continue;
+//       }
     
-    if (mpltransform->need_nonlinear_api())
-      try {
-       mpltransform->nonlinear_only_api(&thisx, &thisy);
-      }
-      catch(...) {
-       continue;
-      }
-    
     xytrans.transform(&thisx, &thisy);
     
     thisy = heightd - thisy;  //flipy


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