SourceForge logo
SourceForge logo
Menu

matplotlib-checkins

From: <jd...@us...> - 2007年07月18日 21:30:16
Revision: 3567
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3567&view=rev
Author: jdh2358
Date: 2007年07月18日 14:30:12 -0700 (2007年7月18日)
Log Message:
-----------
playing around with mpl1 api
Modified Paths:
--------------
 trunk/matplotlib/mpl1/mpl1.py
 trunk/matplotlib/mpl1/mtraits.py
Added Paths:
-----------
 trunk/matplotlib/mpl1/scratch.py
 trunk/matplotlib/mpl1/test.py
Modified: trunk/matplotlib/mpl1/mpl1.py
===================================================================
--- trunk/matplotlib/mpl1/mpl1.py	2007年07月18日 20:38:32 UTC (rev 3566)
+++ trunk/matplotlib/mpl1/mpl1.py	2007年07月18日 21:30:12 UTC (rev 3567)
@@ -1,5 +1,4 @@
-from matplotlib.enthought.traits import HasTraits
-import matplotlib.enthought.traits as traits
+import enthought.traits.api as traits
 
 from matplotlib import agg
 import numpy as npy
@@ -54,7 +53,7 @@
 identity = Identity()
 
 
-class Path(HasTraits):
+class Path(traits.HasTraits):
 """
 The path is an object that talks to the backends, and is an
 intermediary between the high level path artists like Line and
@@ -102,6 +101,7 @@
 def color_to_rgba8(self, color):
 if color is None: return None
 rgba = [int(255*c) for c in color.r, color.g, color.b, color.a]
+
 return agg.rgba8(*rgba)
 
 # coordinates:
@@ -178,7 +178,7 @@
 self.scanlinebin = agg.scanline_bin()
 
 def add_path(self, pathid, path):
- pathid = Renderer.add_path(self, pathid, path)
+ Renderer.add_path(self, pathid, path)
 self.aggpathd[pathid] = AggPath(path)
 
 def remove_path(self, pathid):
@@ -274,6 +274,7 @@
 path.verts = model(X)
 path.codes = codes 
 path.fillcolor = None
+ path.strokecolor = color
 path.strokewidth = linewidth
 path.alpha = alpha
 path.antialiased = antialiased
@@ -281,43 +282,49 @@
 
 
 
-class AxesCoords(HasTraits):
+class AxesCoords(traits.HasTraits):
 xviewlim = mtraits.interval
 yviewlim = mtraits.interval
 affineview = mtraits.affine
 affineaxes = mtraits.affine 
 affine = mtraits.affine 
 
+ 
 def _affineview_changed(self, old, new):
- self.affine = npy.dot(
- npy.dot(self.affineaxes, new), self.affinedata)
+ print 'affine view changed'
+ self.affine = npy.dot(self.affineaxes, new)
 
 def _affineaxes_changed(self, old, new):
- self.affine = npy.dot(
- npy.dot(new, self.affineview), self.affinedata)
+ print 'affine axes changed'
+ self.affine = npy.dot(new, self.affineview)
 
-
+ 
 def _xviewlim_changed(self, old, new):
+ print 'xviewlim changed'
 xmin, xmax = new
 scale = 1./(xmax-xmin)
 tx = -xmin*scale
 self.affineview[0][0] = scale
 self.affineview[0][-1] = tx
-
+ self.affine = npy.dot(self.affineaxes, self.affineview)
+ print '\t', self.affine
+ 
 def _yviewlim_changed(self, old, new):
+ print 'yviewlim changed'
 ymin, ymax = new
 scale = 1./(ymax-ymin)
 ty = -ymin*scale
 self.affineview[1][1] = scale
 self.affineview[1][-1] = ty
-
+ self.affine = npy.dot(self.affineaxes, self.affineview)
+ print '\t', self.affine
 
 
 class Figure:
 def __init__(self):
 self.renderer = None
 self._pathid = 0
- self._pathd = dict()
+ self.pathd = dict()
 
 def add_path(self, path):
 id_ = self._pathid
@@ -336,6 +343,7 @@
 raise RuntimeError('call set_renderer renderer first')
 
 for pathid, path in self.pathd.items():
+ print 'path', pathid, path.affine
 renderer.push_affine(path.affine)
 renderer.render_path(pathid)
 
@@ -374,25 +382,12 @@
 [0,0,1]],
 dtype=npy.float_)
 
-xlim = mtraits.interval()
-ylim1 = mtraits.interval()
-ylim2 = mtraits.interval()
 
-affineaxes = affine_axes([0.1, 0.1, 0.4, 0.4]) # lower, left quadrant
-
 coords1 = AxesCoords()
-coords1.xlim = xlim
-coords1.ylim = ylim1
-print 'typedata', affineaxes.shape, affineaxes.dtype
-coords1.affineaxes = affineaxes
+coords1.affineaxes = affine_axes([0.55, 0.55, 0.4, 0.4]) # upper right quadrant
 
-coords2 = AxesCoords()
-coords2.xlim = xlim
-coords2.ylim = ylim2
-coords2.affineaxes = affineaxes
 
 
-
 fig = Figure()
 
 x = npy.arange(0, 10, 0.01)
@@ -400,22 +395,32 @@
 y2 = 10*npy.exp(-x)
 
 line1 = line(x, y1, color='blue', linewidth=2.0)
-line1.affine = coords1.affime
+line1.affine = coords1.affine
 
-line2 = line(x, y2, color='red', linewidth=2.0)
-line2.affine = coords1.affime
-
 fig.add_path(line1)
-fig.add_path(line2)
 
+print 'before', line1.affine
 # update the view limits, all the affines should be automagically updated
-xlim = 0,10
-ylim1 = -1.1, 1.1
-ylim2 = 0, 10
+coords1.xviewlim = 0, 10
+coords1.yviewlim = -1.1, 1.1
 
+print 'after', line1.affine
 
-renderer = RendererAgg(600,400)
-fig.set_renderer(renderer)
-fig.draw()
-print 'renderer affine', renderer.affine
-renderer.show()
+
+if 0:
+ coords2 = AxesCoords()
+ coords2.xviewlim = coords1.xviewlim # share the x axis
+ coords2.affineaxes = affine_axes([0.1, 0.1, 0.4, 0.4]) # lower left quadrant
+
+
+ line2 = line(x, y2, color='red', linewidth=2.0)
+ line2.affine = coords2.affine
+ coords2.yviewlim = 0, 10
+ fig.add_path(line2)
+
+
+if 0:
+ renderer = RendererAgg(600,400)
+ fig.set_renderer(renderer)
+ fig.draw()
+ renderer.show()
Modified: trunk/matplotlib/mpl1/mtraits.py
===================================================================
--- trunk/matplotlib/mpl1/mtraits.py	2007年07月18日 20:38:32 UTC (rev 3566)
+++ trunk/matplotlib/mpl1/mtraits.py	2007年07月18日 21:30:12 UTC (rev 3567)
@@ -1,3 +1,17 @@
+"""
+Install instructions for traits 2.0
+
+ rm -rf ~/dev/lib/python2.4/site-packages/enthought.*
+
+ easy_install --install-dir=~/dev/lib/python2.4/site-packages --prefix=~/dev -f http://code.enthought.com/enstaller/eggs/source/unstable/ enthought.etsconfig enthought.util enthought.debug
+
+ svn co https://svn.enthought.com/svn/enthought/branches/enthought.traits_2.0 enthought_traits
+
+ cd enthought_traits/
+ python setup.py install --prefix=~/dev
+
+
+"""
 # Here is some example code showing how to define some representative
 # rc properties and construct a matplotlib artist using traits.
 # Because matplotlib ships with enthought traits already, you can run
@@ -7,7 +21,7 @@
 # below.
 
 import sys, os, re
-import matplotlib.enthought.traits as traits
+import enthought.traits.api as traits
 from matplotlib.cbook import is_string_like
 from matplotlib import colors as mcolors
 import numpy as npy
@@ -86,7 +100,7 @@
 
 def path_exists(ob, name, val):
 os.path.exists(val)
-linestyles = ('-', '--', '-.', ':', 'steps', 'None')
+linestyles = ('-', '--', '-.', ':', 'steps')
 TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN = range(4)
 linemarkers = (None, '.', ',', 'o', '^', 'v', '<', '>', 's',
 '+', 'x', 'd', 'D', '|', '_', 'h', 'H',
@@ -95,7 +109,7 @@
 TICKRIGHT,
 TICKUP,
 TICKDOWN,
- 'None')
+ )
 
 
 linewidth = traits.Float(0.5)
@@ -105,9 +119,10 @@
 markersize = traits.Float(6)
 antialiased = flexible_true_trait
 alpha = traits.Range(0., 1., 0.)
-interval = traits.Array('d', (2,))
-affine = traits.Array('d', (3,3))
-verts = traits.Array('d')
-codes = traits.Array('b')
+interval = traits.Array('d', (2,), npy.array([0.0, 1.0], npy.float_))
+affine = traits.Array('d', (3,3),
+ npy.array([[1,0,0],[0,1,0],[0,0,1]], npy.float_))
+verts = traits.Array('d', value=npy.array([[0,0],[0,0]], npy.float_))
+codes = traits.Array('b', value=npy.array([0,0], dtype=npy.uint8))
 
 
Added: trunk/matplotlib/mpl1/scratch.py
===================================================================
--- trunk/matplotlib/mpl1/scratch.py	 (rev 0)
+++ trunk/matplotlib/mpl1/scratch.py	2007年07月18日 21:30:12 UTC (rev 3567)
@@ -0,0 +1,150 @@
+
+class Axis(Artist):
+ tickcolor = mtraits.color('black')
+ axiscolor = mtraits.color('black')
+ tickwidth = mtraits.linewidth(0.5)
+ viewlim = mtraits.interval
+ tickpath = mtraits.path
+ axispath = mtraits.path
+ 
+ def __init__(self, figure): 
+ self.figure = figure
+ self.pathids = set()
+ 
+class XAxis(Axis):
+ def __init__(self, figure, **kwargs):
+ Axis.__init__(self, figure, **kwargs)
+
+ def set_ticks(self, yloc, ysize, ticks, fmt):
+ # we'll deal with locators, formatter and autoscaling later...
+ # todo, remove old paths
+
+ for pathid in self.pathids:
+ self.figure.remove_path(pathid)
+ 
+ codes = []
+ verts = []
+ tickmin = yloc-ysize/2.
+ tickmax = yloc+ysize/2.
+ for tick in ticks:
+ codes.append(Path.MOVETO)
+ verts.append((tick, tickmin))
+ codes.append(Path.LINETO)
+ verts.append((tick, tickmax))
+ 
+
+ path = Path()
+ path.verts = npy.array(verts)
+ path.codes = npy.array(codes)
+ path.strokecolor = self.tickcolor
+ path.fillcolor = None
+ path.linewidth = self.tickwidth
+ path.antialiased = False
+
+ self.pathids.add(self.figure.add_path(path))
+
+ 
+ xmin, xmax = self.viewlim
+
+ # the axis line
+ codes = []
+ verts = []
+ codes.append(Path.MOVETO)
+ verts.append((xmin, yloc))
+ codes.append(Path.LINETO)
+ verts.append((xmax, yloc))
+
+ path = Path()
+ path.verts = npy.array(verts)
+ path.codes = npy.array(codes)
+ path.strokecolor = self.axiscolor
+ path.fillcolor = None
+ path.antialiased = False
+ 
+ self.pathids.add(self.figure.add_path(path))
+
+ 
+class YAxis:
+ def __init__(self, figure):
+ Axis.__init__(self, figure)
+
+ def set_ticks(self, xloc, xsize, ticks, fmt):
+
+ for pathid in self.pathids:
+ self.figure.remove_path(pathid)
+
+ codes = []
+ verts = []
+ tickmin = yloc-ysize/2.
+ tickmax = yloc+ysize/2.
+ for tick in ticks:
+ codes.append(Path.MOVETO)
+ verts.append((tickmin, tick))
+ codes.append(Path.LINETO)
+ verts.append((tickmax, tick))
+ 
+
+ self.tickpath = path = Path()
+ path.verts = npy.array(verts)
+ path.codes = npy.array(codes)
+ path.strokecolor = self.tickcolor
+ path.fillcolor = None
+ path.linewidth = self.tickwidth
+ path.antialiased = False
+
+ self.pathids.add(self.figure.add_path(path))
+
+ 
+ ymin, ymax = self.viewlim
+
+ # the axis line
+ codes = []
+ verts = []
+ codes.append(Path.MOVETO)
+ verts.append((xloc, ymin))
+ codes.append(Path.LINETO)
+ verts.append((xloc, ymax))
+
+ self.axispath = path = Path()
+ path.verts = npy.array(verts)
+ path.codes = npy.array(codes)
+ path.strokecolor = self.axiscolor
+ path.fillcolor = None
+ path.antialiased = False
+ 
+ self.pathids.add(self.figure.add_path(path))
+
+
+
+
+
+
+if 0:
+ ax1.set_ylim(-1.1, 1.1)
+
+ xaxis = XAxis(ax1)
+ xaxis.set_ticks(0, 0.1, npy.arange(11.0), '%d')
+
+ yaxis1 = YAxis(ax1)
+ yaxis1.set_ticks(-1.1, 0.2, npy.arange(-1.0, 1.1, 0.5), '%d')
+ yaxis1.axiscolor = line1.color
+
+ yaxis2 = YAxis(ax1)
+ yaxis2.set_ticks(5.0, 0.2, npy.arange(-1.0, 1.1, 0.5), '%d')
+
+
+
+
+
+ theta = 0.25*npy.pi # 45 degree axes rotation
+ #rotate_axes(ax1, theta)
+
+
+ r = npy.arange(0, 1, 0.01)
+ theta = r*4*npy.pi
+ X2 = npy.array([r,theta]).T
+ line2 = Line(X2, model=Polar())
+ ax2.add_line(line2)
+ # currently cartesian
+ ax2.set_xlim(-1,1)
+ ax2.set_ylim(-1,1)
Added: trunk/matplotlib/mpl1/test.py
===================================================================
--- trunk/matplotlib/mpl1/test.py	 (rev 0)
+++ trunk/matplotlib/mpl1/test.py	2007年07月18日 21:30:12 UTC (rev 3567)
@@ -0,0 +1,15 @@
+import numpy
+from enthought.traits.api import HasTraits, Array
+import mtraits
+
+
+class Path(HasTraits):
+ """
+ The path is an object that talks to the backends, and is an
+ intermediary between the high level path artists like Line and
+ Polygon, and the backend renderer
+ """
+ strokecolor = mtraits.color('white')
+
+p = Path()
+print 'strokecolor', p.strokecolor
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <jd...@us...> - 2007年07月19日 02:40:18
Revision: 3569
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3569&view=rev
Author: jdh2358
Date: 2007年07月18日 19:40:15 -0700 (2007年7月18日)
Log Message:
-----------
added design goals doc
Modified Paths:
--------------
 trunk/matplotlib/mpl1/mpl1.py
 trunk/matplotlib/mpl1/mtraits.py
Added Paths:
-----------
 trunk/matplotlib/mpl1/DESIGN_GOALS
Added: trunk/matplotlib/mpl1/DESIGN_GOALS
===================================================================
--- trunk/matplotlib/mpl1/DESIGN_GOALS	 (rev 0)
+++ trunk/matplotlib/mpl1/DESIGN_GOALS	2007年07月19日 02:40:15 UTC (rev 3569)
@@ -0,0 +1,116 @@
+Here are some of the things I would like to accomplish with mpl1. Any
+and all of this is open to discussion. What I present below is pretty
+ambitious, so if there is support, we will need significant
+contributions from several developers for several months. Ideally, we
+would get a good sketch working, and then organize a spint (4 days?)
+for late August, where we try get as far as possible to making this
+viable.
+
+= data copying =
+
+Push the data to the backend only once, or only when required. update
+the transforms to the backend, but do not push transformed data on
+every draw. This is potentially a major win, because we currently
+move the data around on every draw
+
+
+= transformations = 
+
+Support a normal transformation architecture. The current draft
+implmentation assumes one nonlinear transformation, which happens at a
+high layer, and all transformations after that are affines. Currently
+there are two affines: the transformation from view limits -> axes
+units, the transformation from axes units to normalized figure untis,
+and the transformation from normalized figure units to display
+
+do we want to use 3x3 or 4x4 to leave the door open for 3D developers?
+
+= objects that talk to the backend "primitives" = 
+
+Have just a few, fairly rich obects the backends need to understand.
+clear candidates are a Path, Text and Image. Each of these will carry
+their metadata, eg a path will carry its stroke color, facecolor,
+linewidth, etc.. Text will carry its font size, color, etc. We may
+need some optimizations down the road, but start small. For now,
+let's call these objects primitives
+
+= where do the plot functions live? =
+
+In matplotlib, the plot functions are axes methods and this is a poor
+design. Where should these live, what should they create, etc?
+
+= how much of an intermediate artist layer do we need = 
+
+Do we want to create high level objects like Circle, Rectangle and
+Line, each of which manage a Path object under the hood? Probably.
+By using traits properly here, these will be thin interfaces around
+one of our primitives.
+
+= z-ordering, containers, etc = 
+
+Peter has been doing a lot of nice work on z-order and layers and
+stuff like that for chaco, stuff that looks really useful for picking,
+interactive, etc... We should look at their approach, and think
+carefully about how this should be handled. Paul is a good candidate
+for this.
+
+= extension code = 
+
+I would like to shed all of the CXX extension code -- it is just too
+small a nitch of the python world to base our proect on. SWIG is
+pretty clearly the right choice. mpl1 will use numpy for
+transformations with some carefully chosen extension code where
+necessary, so this gets rid of _transforms.cpp. I also plan to use
+the SWIG agg wrapper, so this gets rid of _backend_agg. If we can
+enhance the SWIG agg wrapper, we can also do images through here.
+Having a fully featured python agg wrapper will be a plus. But with
+the agg license change, I'm open to discussion of alternatives.
+
+I want to do away with *all* GUI extension code. This should live
+outside MPL, eg in a toolkit, if we need it. This means someone
+(Michael is probably a good choice) needs to figure out how to get tk
+talking to a python buffer or numpy array. Maintaining the GUI
+extension code is a drag.
+
+= traits = 
+
+I think we should make a major committment to traits and use them from
+the ground up. w/o the UI stuff, they add plenty to make them
+worthwhile. With the UI (wx only) , they are a major win for GUI
+developers.
+
+= axis handling = 
+
+The whole conception of the Axes needs to be reworked, in light of the
+fact that we need to support multiple axis objects on one Axes. This
+will require a fair amount of thought, but we should aim for
+supporting an arbitrary number of axis obects, presumably associated
+with individual artists or primitives, on each Axes. They also need
+to be *much* faster. matplotlib uses Artists for each tick, tickline,
+gridline, ticklabel, etc, and this is mind-numbingsly slow.
+
+= breakage = 
+
+I think we need to be prepared to break the hell out of this thing.
+The API will basically be a total rewrite. pylab will still mostly
+work unchanged -- that is the beauty of pylab. We'll probably want to
+install into a new namespace, eg mpl, and envision both matplotlib and
+mpl co-existing for some time. In fact, mpl might depend on
+matplotlib for a while (eg until a CXX free ft2font is available)
+
+We should expect to be supporting and using matplotlib for a long
+time, since the proposals discussed here imply that it will be a long
+wait until mpl1 is feature complete with matplotlib. In fact, we could
+rightly consider this to be the mpl2 proposal, and keep releaseing
+matplotlib ehancements to 1.0 and beyond w/o signfificant breakage.
+It's a nominal difference so I don't really have a preference.
+
+= chaco and kiva = 
+
+This is probably a good idea for an enterprising developer to take a
+careful look at Chaco and Kiva to see if we can integrate with them.
+I am gunshy because they seem formiddable and complex, and one of my
+maor goals here is to streamline and simplify, but they are incredible
+pieces of work and we need to consider them, especially if we
+integrate other parts of the enthought suite into our core, eg traits
+
Modified: trunk/matplotlib/mpl1/mpl1.py
===================================================================
--- trunk/matplotlib/mpl1/mpl1.py	2007年07月18日 21:52:01 UTC (rev 3568)
+++ trunk/matplotlib/mpl1/mpl1.py	2007年07月19日 02:40:15 UTC (rev 3569)
@@ -1,3 +1,4 @@
+# see install instructions for enthrought traits2 in mtraits
 import enthought.traits.api as traits
 
 from matplotlib import agg
@@ -395,7 +396,7 @@
 y2 = 10*npy.exp(-x)
 
 line1 = line(x, y1, color='blue', linewidth=2.0)
-line1.affine = coords1.affine
+line1.sync_trait('affine', coords1)
 
 fig.add_path(line1)
 
Modified: trunk/matplotlib/mpl1/mtraits.py
===================================================================
--- trunk/matplotlib/mpl1/mtraits.py	2007年07月18日 21:52:01 UTC (rev 3568)
+++ trunk/matplotlib/mpl1/mtraits.py	2007年07月19日 02:40:15 UTC (rev 3569)
@@ -1,14 +1,19 @@
 """
 Install instructions for traits 2.0
 
+ # blow away old enthought
 rm -rf ~/dev/lib/python2.4/site-packages/enthought.*
 
- easy_install --install-dir=~/dev/lib/python2.4/site-packages --prefix=~/dev -f http://code.enthought.com/enstaller/eggs/source/unstable/ enthought.etsconfig enthought.util enthought.debug
+ # get easy_install, if necessary
+ wget http://peak.telecommunity.com/dist/ez_setup.py
+ sudo python sez_setup.py
 
+ sudo easy_install -f http://code.enthought.com/enstaller/eggs/source/unstable/ enthought.etsconfig enthought.util enthought.debug
+
 svn co https://svn.enthought.com/svn/enthought/branches/enthought.traits_2.0 enthought_traits
 
 cd enthought_traits/
- python setup.py install --prefix=~/dev
+ sudo python setup.py install 
 
 
 """
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <jd...@us...> - 2007年07月19日 17:04:22
Revision: 3576
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3576&view=rev
Author: jdh2358
Date: 2007年07月19日 10:04:19 -0700 (2007年7月19日)
Log Message:
-----------
working draft
Modified Paths:
--------------
 trunk/matplotlib/mpl1/DESIGN_GOALS
 trunk/matplotlib/mpl1/mpl1.py
 trunk/matplotlib/mpl1/mtraits.py
 trunk/matplotlib/mpl1/scratch.py
 trunk/matplotlib/mpl1/test.py
Modified: trunk/matplotlib/mpl1/DESIGN_GOALS
===================================================================
--- trunk/matplotlib/mpl1/DESIGN_GOALS	2007年07月19日 16:53:36 UTC (rev 3575)
+++ trunk/matplotlib/mpl1/DESIGN_GOALS	2007年07月19日 17:04:19 UTC (rev 3576)
@@ -24,7 +24,7 @@
 limits -> axes units (AxesCoords.affineview), the transformation from
 axes units to normalized figure units (AxesCoords.affineaxes), and the
 transformation from normalized figure units to display
-(Renderer.affine)
+(Renderer.affinerenderer)
 
 Do we want to use 3x3 or 4x4 to leave the door open for 3D developers?
 
Modified: trunk/matplotlib/mpl1/mpl1.py
===================================================================
--- trunk/matplotlib/mpl1/mpl1.py	2007年07月19日 16:53:36 UTC (rev 3575)
+++ trunk/matplotlib/mpl1/mpl1.py	2007年07月19日 17:04:19 UTC (rev 3576)
@@ -5,7 +5,115 @@
 import numpy as npy
 
 import mtraits # some handy traits for mpl
+ 
 
+class Renderer:
+ def __init__(self, width, height):
+ self.width, self.height = width, height
+
+ # almost all renderers assume 0,0 is left, upper, so we'll flip y here by default
+ self.affinerenderer = npy.array(
+ [[width, 0, 0], [0, -height, height], [0, 0, 1]], dtype=npy.float_)
+ self.pathd = dict() # dict mapping path id -> path instance
+ 
+
+ def add_path(self, pathid, path):
+ self.pathd[pathid] = path
+
+ def remove_path(self, pathid):
+ if pathid in self.pathd:
+ del self.pathd[pathid]
+
+ def render_path(self, pathid):
+ pass
+ 
+
+
+class RendererAgg(Renderer):
+ gray = agg.rgba8(128,128,128,255) 
+ white = agg.rgba8(255,255,255,255)
+ blue = agg.rgba8(0,0,255,255)
+ black = agg.rgba8(0,0,0,0)
+
+ def __init__(self, width, height):
+ Renderer.__init__(self, width, height)
+ 
+ stride = width*4
+ self.buf = buf = agg.buffer(width, height, stride)
+
+ self.rbuf = rbuf = agg.rendering_buffer()
+ rbuf.attachb(buf)
+
+ self.pf = pf = agg.pixel_format_rgba(rbuf)
+ self.rbase = rbase = agg.renderer_base_rgba(pf)
+ rbase.clear_rgba8(self.gray)
+
+ # the antialiased renderers
+ self.renderer = agg.renderer_scanline_aa_solid_rgba(rbase); 
+ self.rasterizer = agg.rasterizer_scanline_aa()
+ self.scanline = agg.scanline_p8()
+ self.trans = None
+
+ # the aliased renderers
+ self.rendererbin = agg.renderer_scanline_bin_solid_rgba(rbase);
+ self.scanlinebin = agg.scanline_bin()
+
+
+ def add_path(self, pathid, path):
+ self.pathd[pathid] = AggPath(path)
+
+ def render_path(self, pathid):
+
+
+ path = self.pathd[pathid]
+
+ if path.antialiased:
+ renderer = self.renderer
+ scanline = self.scanline
+ render_scanlines = agg.render_scanlines_rgba
+ else:
+ renderer = self.rendererbin
+ scanline = self.scanlinebin
+ render_scanlines = agg.render_scanlines_bin_rgba
+
+
+ affine = npy.dot(self.affinerenderer, path.affine)
+ #print 'display affine:\n', self.affinerenderer
+ #print 'path affine:\n', path.affine
+ #print 'product affine:\n', affine
+ a, b, tx = affine[0]
+ c, d, ty = affine[1]
+ aggaffine = agg.trans_affine(a,b,c,d,tx,ty)
+ transpath = agg.conv_transform_path(path.agg_path, aggaffine)
+
+ renderer.color_rgba8( path.agg_strokecolor )
+ if path.fillcolor is not None:
+ self.rasterizer.add_path(transpath)
+ renderer.color_rgba8( path.agg_fillcolor )
+ render_scanlines(self.rasterizer, scanline, renderer);
+
+ if path.strokecolor is not None:
+ stroke = agg.conv_stroke_transpath(transpath)
+ stroke.width(path.linewidth)
+ self.rasterizer.add_path(stroke)
+ renderer.color_rgba8( path.agg_strokecolor ) 
+ render_scanlines(self.rasterizer, scanline, renderer);
+
+
+ def show(self):
+ # we'll cheat a little and use pylab for display
+
+ X = npy.fromstring(self.buf.to_string(), npy.uint8)
+ X.shape = self.height, self.width, 4
+ if 1:
+ import pylab
+ fig = pylab.figure()
+ ax = fig.add_axes([0,0,1,1], xticks=[], yticks=[],
+ frameon=False, aspect='auto')
+ ax.imshow(X, aspect='auto')
+ pylab.show()
+
+
 class Func:
 def __call__(self, X):
 'transform the numpy array with shape N,2'
@@ -62,47 +170,67 @@
 """
 MOVETO, LINETO, CLOSEPOLY = range(3)
 
- strokecolor = mtraits.color('black')
- fillcolor = mtraits.color('blue')
- alpha = mtraits.alpha(1.0)
- linewidth = mtraits.linewidth(1.0)
- antialiased = mtraits.flexible_true_trait
- verts= mtraits.verts
- codes = mtraits.codes
+ strokecolor = mtraits.Color('black')
+ fillcolor = mtraits.Color('blue')
+ alpha = mtraits.Alpha(1.0)
+ linewidth = mtraits.Linewidth(1.0)
+ antialiased = mtraits.FlexibleTrueTrait
+ pathdata = mtraits.PathData
+ affine = mtraits.Affine
+ 
+mtraits.Path = traits.Trait(Path())
 
-mtraits.path = traits.Trait(Path())
+class AggPath(Path):
+
+ def __init__(self, path):
+ self.strokecolor = path.strokecolor
+ self.fillcolor = path.fillcolor
+ self.alpha = path.alpha
+ self.linewidth = path.linewidth
+ self.antialiased = path.antialiased
+ self.pathdata = path.pathdata
+ self.affine = path.affine
+
 
-class AggPath:
- def __init__(self, path):
- """
- Path stored with agg data structs 
- """
+ path.sync_trait('strokecolor', self)
+ path.sync_trait('fillcolor', self)
+ path.sync_trait('alpha', self)
+ path.sync_trait('linewidth', self)
+ path.sync_trait('antialiased', self)
+ path.sync_trait('pathdata', self)
+ path.sync_trait('affine', self)
+
+ def _pathdata_changed(self, olddata, newdata):
 MOVETO, LINETO, CLOSEPOLY = Path.MOVETO, Path.LINETO, Path.CLOSEPOLY
- aggpath = agg.path_storage()
- verts = path.verts
- codes = path.codes
- for i in range(len(verts)):
+ agg_path = agg.path_storage()
+ codes, verts = newdata
+ N = len(codes)
+ for i in range(N):
 x, y = verts[i]
 code = codes[i]
 if code==MOVETO:
- aggpath.move_to(x, y)
+ agg_path.move_to(x, y)
 elif code==LINETO:
- aggpath.line_to(x, y) 
+ agg_path.line_to(x, y) 
 elif code==CLOSEPOLY:
- aggpath.close_polygon()
+ agg_path.close_polygon()
+ 
+ self.agg_path = agg_path
+ 
+ def _fillcolor_changed(self, oldcolor, newcolor): 
+ self.agg_fillcolor = self.color_to_rgba8(newcolor)
 
- self.fillcolor = self.color_to_rgba8(path.fillcolor)
- self.strokecolor = self.color_to_rgba8(path.strokecolor)
+ def _strokecolor_changed(self, oldcolor, newcolor): 
 
- self.aggpath = aggpath
- self.alpha = float(path.alpha)
- self.linewidth = float(path.linewidth)
- self.antialiased = bool(path.antialiased)
+ c = self.color_to_rgba8(newcolor)
+ #print 'stroke change: old=%s, new=%s, agg=%s, ret=%s'%(
+ # oldcolor, newcolor, self.agg_strokecolor, c)
+ self.agg_strokecolor = c
 
+
 def color_to_rgba8(self, color):
 if color is None: return None
 rgba = [int(255*c) for c in color.r, color.g, color.b, color.a]
-
 return agg.rgba8(*rgba)
 
 # coordinates:
@@ -111,216 +239,84 @@
 # to a separable cartesian coordinate, eg for polar is takes r,
 # theta -> r*cos(theta), r*sin(theta)
 #
-# affineData : an affine 3x3 matrix that takes model output and
+# AxesCoords.affineview : an affine 3x3 matrix that takes model output and
 # transforms it to axes 0,1. We are kind of stuck with the
 # mpl/matlab convention that 0,0 is the bottom left of the axes,
 # even though it contradicts pretty much every GUI layout in the
 # world
 #
-# affineFigure: an affine 3x3 that transforms an axes.view into figure
+# AxesCoords.affineaxes: an affine 3x3 that transforms an axesview into figure
 # 0,1 
 #
-# affineDisplay : takes an affine 3x3 and puts figure view into display. 0,
+# Renderer.affinerenderer : takes an affine 3x3 and puts figure view into display. 0,
 # 0 is left, top, which is the typical coordinate system of most
 # graphics formats
 
-class Renderer:
- def __init__(self, width, height):
- self.width, self.height = width, height
 
- # almost all renderers assume 0,0 is left, upper, so we'll flip y here by default
- self.displayview = npy.array(
- [[width, 0, 0], [0, -height, height], [0, 0, 1]], dtype=npy.float_)
- self.pathd = dict() # dict mapping path id -> path instance
- 
- def push_affine(self, affine):
- 'set the current affine'
- self.affine = npy.dot(self.displayview, affine)
+class Rectangle(Path):
+ facecolor = mtraits.Color('Yellow')
+ edgecolor = mtraits.Color('Black')
+ edgewidth = mtraits.Linewidth(1.0)
+ 
+ def __init__(self, lbwh, **kwargs):
 
- def add_path(self, pathid, path):
- self.pathd[pathid] = path
+ # support some legacy names
+ self.sync_trait('facecolor', self, 'fillcolor', True)
+ self.sync_trait('edgecolor', self, 'strokecolor', True)
+ self.sync_trait('edgewidth', self, 'strokewidth', True)
 
- def remove_path(self, pathid):
- if pathid in self.pathd:
- del self.pathd[pathid]
+ for k,v in kwargs.items():
+ setattr(self, k, v)
 
- def render_path(self, pathid):
- pass
- 
+ l,b,w,h = lbwh
+ t = b+h
+ r = l+w
+ verts = npy.array([(l,b), (l,t), (r, t), (r, b), (0,0)], npy.float_)
+ codes = Path.LINETO*npy.ones(5, npy.uint8)
+ codes[0] = Path.MOVETO
+ codes[-1] = Path.CLOSEPOLY
 
+ self.pathdata = codes, verts
 
-class RendererAgg(Renderer):
- gray = agg.rgba8(128,128,128,255) 
- white = agg.rgba8(255,255,255,255)
- blue = agg.rgba8(0,0,255,255)
 
- def __init__(self, width, height):
- Renderer.__init__(self, width, height)
 
- self.aggpathd = dict() # map path ids to AggPaths
- stride = width*4
- self.buf = buf = agg.buffer(width, height, stride)
+def Alias(name):
+ return Property(lambda obj: getattr(obj, name),
+ lambda obj, val: setattr(obj, name, val))
 
- self.rbuf = rbuf = agg.rendering_buffer()
- rbuf.attachb(buf)
+class Line(Path):
+ # aliases for matplotlib compat
+ color = mtraits.Color('blue')
+ linewidth = mtraits.Linewidth(1.0)
 
- self.pf = pf = agg.pixel_format_rgba(rbuf)
- self.rbase = rbase = agg.renderer_base_rgba(pf)
- rbase.clear_rgba8(self.gray)
+ 
+ def __init__(self, x, y, model=identity, **kwargs):
+ """
+ The model is a function taking Nx2->Nx2. This is where the
+ nonlinear transformation can be used
+ """
 
- # the antialiased renderers
- self.renderer = agg.renderer_scanline_aa_solid_rgba(rbase); 
- self.rasterizer = agg.rasterizer_scanline_aa()
- self.scanline = agg.scanline_p8()
- self.trans = None
+ self.sync_trait('color', self, 'strokecolor', True)
+ self.sync_trait('linewidth', self, 'strokewidth', True)
 
- # the aliased renderers
- self.rendererbin = agg.renderer_scanline_bin_solid_rgba(rbase);
- self.scanlinebin = agg.scanline_bin()
+ # probably a better way to do this with traits
+ for k,v in kwargs.items():
+ setattr(self, k, v)
 
- def add_path(self, pathid, path):
- Renderer.add_path(self, pathid, path)
- self.aggpathd[pathid] = AggPath(path)
+ X = npy.array([x,y]).T
+ numrows, numcols = X.shape
 
- def remove_path(self, pathid):
- Renderer.remove_path(self, pathid)
- if pathid in self.aggpathd:
- del self.aggpathd[pathid]
+ codes = Path.LINETO*npy.ones(numrows, npy.uint8)
+ codes[0] = Path.MOVETO
 
- def push_affine(self, affine):
- 'set the current affine'
- Renderer.push_affine(self, affine)
- a, b, tx = self.affine[0]
- c, d, ty = self.affine[1]
- self.trans = agg.trans_affine(a,b,c,d,tx,ty)
+ verts = model(X)
 
+ self.pathdata = codes, verts 
+ self.fillcolor = None
 
- def render_path(self, pathid):
- if self.trans is None:
- raise RuntimeError('you must first push_affine')
-
-
-
- aggpath = self.aggpathd[pathid]
-
- if aggpath.antialiased:
- renderer = self.renderer
- scanline = self.scanline
- render_scanlines = agg.render_scanlines_rgba
- else:
- renderer = self.rendererbin
- scanline = self.scanlinebin
- render_scanlines = agg.render_scanlines_bin_rgba
-
- renderer.color_rgba8( aggpath.strokecolor )
- transpath = agg.conv_transform_path(aggpath.aggpath, self.trans)
-
- if aggpath.fillcolor is not None:
- self.rasterizer.add_path(transpath)
- renderer.color_rgba8( aggpath.fillcolor )
- render_scanlines(self.rasterizer, scanline, renderer);
- 
- stroke = agg.conv_stroke_transpath(transpath)
- stroke.width(aggpath.linewidth)
- self.rasterizer.add_path(stroke)
- renderer.color_rgba8( aggpath.strokecolor ) 
- render_scanlines(self.rasterizer, scanline, renderer);
-
-
- def show(self):
- # we'll cheat a little and use pylab for display
-
- X = npy.fromstring(self.buf.to_string(), npy.uint8)
- X.shape = self.height, self.width, 4
- if 1:
- import pylab
- fig = pylab.figure()
- ax = fig.add_axes([0,0,1,1], xticks=[], yticks=[],
- frameon=False, aspect='auto')
- ax.imshow(X, aspect='auto')
- pylab.show()
-
-
-
-
-
-def rectangle(l, b, w, h, facecolor='yellow', edgecolor='black',
- edgewidth=1.0, alpha=1.0):
-
- t = b+h
- r = l+w
- verts = npy.array([(l,b), (l,t), (r, t), (r, b), (0,0)], npy.float_)
- codes = Path.LINETO*npy.ones(5, npy.uint8)
- codes[0] = Path.MOVETO
- codes[-1] = Path.CLOSEPOLY
-
- path = Path()
- part.verts = verts
- path.codes = codes
- path.strokecolor = edgecolor
- path.fillcolor = facecolor
- path.linewidth = edgewidth
- path.alpha = alpha
- return path
-
-def line(x, y, color='black', linewidth=1.0, alpha=1.0, antialiased=True,
- model=identity):
- X = npy.asarray([x,y]).T
- numrows, numcols = X.shape
-
- codes = Path.LINETO*npy.ones(numrows, npy.uint8)
- codes[0] = Path.MOVETO
-
- path = Path()
- path.verts = model(X)
- path.codes = codes 
- path.fillcolor = None
- path.strokecolor = color
- path.strokewidth = linewidth
- path.alpha = alpha
- path.antialiased = antialiased
- return path
- 
 
 
-class AxesCoords(traits.HasTraits):
- xviewlim = mtraits.interval
- yviewlim = mtraits.interval
- affineview = mtraits.affine
- affineaxes = mtraits.affine 
- affine = mtraits.affine 
 
- 
- def _affineview_changed(self, old, new):
- print 'affine view changed'
- self.affine = npy.dot(self.affineaxes, new)
-
- def _affineaxes_changed(self, old, new):
- print 'affine axes changed'
- self.affine = npy.dot(new, self.affineview)
-
- 
- def _xviewlim_changed(self, old, new):
- print 'xviewlim changed'
- xmin, xmax = new
- scale = 1./(xmax-xmin)
- tx = -xmin*scale
- self.affineview[0][0] = scale
- self.affineview[0][-1] = tx
- self.affine = npy.dot(self.affineaxes, self.affineview)
- print '\t', self.affine
- 
- def _yviewlim_changed(self, old, new):
- print 'yviewlim changed'
- ymin, ymax = new
- scale = 1./(ymax-ymin)
- ty = -ymin*scale
- self.affineview[1][1] = scale
- self.affineview[1][-1] = ty
- self.affine = npy.dot(self.affineaxes, self.affineview)
- print '\t', self.affine
- 
-
 class Figure:
 def __init__(self):
 self.renderer = None
@@ -343,9 +339,7 @@
 if self.renderer is None:
 raise RuntimeError('call set_renderer renderer first')
 
- for pathid, path in self.pathd.items():
- print 'path', pathid, path.affine
- renderer.push_affine(path.affine)
+ for pathid in self.pathd:
 renderer.render_path(pathid)
 
 
@@ -384,43 +378,94 @@
 dtype=npy.float_)
 
 
-coords1 = AxesCoords()
-coords1.affineaxes = affine_axes([0.55, 0.55, 0.4, 0.4]) # upper right quadrant
+class AxesCoords(traits.HasTraits):
+ xviewlim = mtraits.Interval
+ yviewlim = mtraits.Interval
+ affineview = mtraits.Affine
+ affineaxes = mtraits.Affine 
+ affine = mtraits.Affine 
 
+ 
+ def _affineview_changed(self, old, new):
+ #print 'affineview changed before:\n', self.affine
+ self.affine = npy.dot(self.affineaxes, new)
+ #print 'affineview changed after:\n', self.affine
 
+ def _affineaxes_changed(self, old, new):
+ #print 'affineaxes changed before:\n', self.affine
+ self.affine = npy.dot(new, self.affineview)
+ #print 'affineaxes changed after:\n', self.affine
+ 
+ def _xviewlim_changed(self, old, new):
 
-fig = Figure()
+ #print 'xviewlim changed before:\n', self.affine
+ xmin, xmax = new
+ scale = 1./(xmax-xmin)
+ tx = -xmin*scale
+ self.affineview[0][0] = scale
+ self.affineview[0][-1] = tx
+ self.affine = npy.dot(self.affineaxes, self.affineview)
+ #print 'xviewlim changed after:\n', self.affine
+ 
+ def _yviewlim_changed(self, old, new):
+ #print 'yviewlim changed before:\n', self.affine
+ ymin, ymax = new
+ scale = 1./(ymax-ymin)
+ ty = -ymin*scale
+ self.affineview[1][1] = scale
+ self.affineview[1][-1] = ty
+ self.affine = npy.dot(self.affineaxes, self.affineview)
+ #print 'yviewlim changed after:\n', self.affine
+ 
 
 x = npy.arange(0, 10, 0.01)
 y1 = npy.cos(2*npy.pi*x)
 y2 = 10*npy.exp(-x)
 
-line1 = line(x, y1, color='blue', linewidth=2.0)
-line1.sync_trait('affine', coords1)
+# the axes rectangle
+axrect1 = [0.1, 0.1, 0.4, 0.4]
+coords1 = AxesCoords()
+coords1.affineaxes = affine_axes(axrect1)
 
+fig = Figure()
+
+line1 = Line(x, y1, color='blue', linewidth=2.0)
+rect1 = Rectangle([0,0,1,1], facecolor='white')
+coords1.sync_trait('affine', line1)
+coords1.sync_trait('affineaxes', rect1, 'affine')
+
+fig.add_path(rect1)
 fig.add_path(line1)
 
-print 'before', line1.affine
 # update the view limits, all the affines should be automagically updated
 coords1.xviewlim = 0, 10
 coords1.yviewlim = -1.1, 1.1
 
-print 'after', line1.affine
 
+# the axes rectangle
+axrect2 = [0.55, 0.55, 0.4, 0.4]
+coords2 = AxesCoords()
+coords2.affineaxes = affine_axes(axrect2)
 
-if 0:
- coords2 = AxesCoords()
- coords2.xviewlim = coords1.xviewlim # share the x axis
- coords2.affineaxes = affine_axes([0.1, 0.1, 0.4, 0.4]) # lower left quadrant
 
+r = npy.arange(0.0, 1.0, 0.01)
+theta = r*4*npy.pi
 
- line2 = line(x, y2, color='red', linewidth=2.0)
- line2.affine = coords2.affine
- coords2.yviewlim = 0, 10
- fig.add_path(line2)
+line2 = Line(r, theta, model=Polar(), color='#ee8d18', linewidth=2.0)
+rect2 = Rectangle([0,0,1,1], facecolor='#d5de9c')
+coords2.sync_trait('affine', line2)
+coords2.sync_trait('affineaxes', rect2, 'affine')
 
+fig.add_path(rect2)
+fig.add_path(line2)
 
-if 0:
+# update the view limits, all the affines should be automagically updated
+coords2.xviewlim = -1.1, 1.1
+coords2.yviewlim = -1.1, 1.1
+
+
+
+if 1:
 renderer = RendererAgg(600,400)
 fig.set_renderer(renderer)
 fig.draw()
Modified: trunk/matplotlib/mpl1/mtraits.py
===================================================================
--- trunk/matplotlib/mpl1/mtraits.py	2007年07月19日 16:53:36 UTC (rev 3575)
+++ trunk/matplotlib/mpl1/mtraits.py	2007年07月19日 17:04:19 UTC (rev 3576)
@@ -32,12 +32,12 @@
 import numpy as npy
 
 doprint = True
-flexible_true_trait = traits.Trait(
+FlexibleTrueTrait = traits.Trait(
 True,
 { 'true': True, 't': True, 'yes': True, 'y': True, 'on': True, True: True,
 'false': False, 'f': False, 'no': False, 'n': False, 'off': False, False: False
 } )
-flexible_false_trait = traits.Trait( False, flexible_true_trait )
+FlexibleFalseTrait = traits.Trait( False, FlexibleTrueTrait )
 
 colors = mcolors.cnames
 
@@ -56,9 +56,9 @@
 self.g = g
 self.b = b
 self.a = a
+
 def __repr__(self):
- return 'r,g,b,a = (%1.2f, %1.2f, %1.2f, %1.2f)'%\
- (self.r, self.g, self.b, self.a)
+ return '(%1.2f, %1.2f, %1.2f, %1.2f)'%(self.r, self.g, self.b, self.a)
 
 def tuple_to_rgba(ob, name, val):
 tup = [float(x) for x in val]
@@ -117,17 +117,18 @@
 )
 
 
-linewidth = traits.Float(0.5)
-linestyle = traits.Trait(*linestyles)
-color = Color
-marker = traits.Trait(*linemarkers)
-markersize = traits.Float(6)
-antialiased = flexible_true_trait
-alpha = traits.Range(0., 1., 0.)
-interval = traits.Array('d', (2,), npy.array([0.0, 1.0], npy.float_))
-affine = traits.Array('d', (3,3),
+Alpha = traits.Float(1.0)
+Linewidth = traits.Float(0.5)
+Linestyle = traits.Trait(*linestyles)
+Color = Color
+Marker = traits.Trait(*linemarkers)
+Markersize = traits.Float(6)
+Antialiased = FlexibleTrueTrait
+Alpha = traits.Range(0., 1., 0.)
+Interval = traits.Array('d', (2,), npy.array([0.0, 1.0], npy.float_))
+Affine = traits.Array('d', (3,3),
 npy.array([[1,0,0],[0,1,0],[0,0,1]], npy.float_))
-verts = traits.Array('d', value=npy.array([[0,0],[0,0]], npy.float_))
-codes = traits.Array('b', value=npy.array([0,0], dtype=npy.uint8))
+Verts = traits.Array('d', value=npy.array([[0,0],[0,0]], npy.float_))
+Codes = traits.Array('b', value=npy.array([0,0], dtype=npy.uint8))
+PathData = traits.Tuple(Codes, Verts)
 
-
Modified: trunk/matplotlib/mpl1/scratch.py
===================================================================
--- trunk/matplotlib/mpl1/scratch.py	2007年07月19日 16:53:36 UTC (rev 3575)
+++ trunk/matplotlib/mpl1/scratch.py	2007年07月19日 17:04:19 UTC (rev 3576)
@@ -1,4 +1,64 @@
 
+class AggPath(Path):
+
+ agg_fillcolor = mtraits.ColorAgg(RendererAgg.blue)
+ agg_strokecolor = mtraits.ColorAgg(RendererAgg.black)
+ agg_path = mtraits.PathAgg 
+
+
+ def __init__(self, path):
+ self.strokecolor = path.strokecolor
+ self.fillcolor = path.fillcolor
+ self.alpha = path.alpha
+ self.linewidth = path.linewidth
+ self.antialiased = path.antialiased
+ self.pathdata = path.pathdata
+ self.affine = path.affine
+
+ 
+ path.sync_trait('strokecolor', self)
+ path.sync_trait('fillcolor', self)
+ path.sync_trait('alpha', self)
+ path.sync_trait('linewidth', self)
+ path.sync_trait('antialiased', self)
+ path.sync_trait('pathdata', self)
+ path.sync_trait('affine', self)
+
+ def _pathdata_changed(self, olddata, newdata):
+ print 'pathdata changed'
+ MOVETO, LINETO, CLOSEPOLY = Path.MOVETO, Path.LINETO, Path.CLOSEPOLY
+ agg_path = agg.path_storage()
+ codes, verts = newdata
+ N = len(codes)
+ for i in range(N):
+ x, y = verts[i]
+ code = codes[i]
+ if code==MOVETO:
+ agg_path.move_to(x, y)
+ elif code==LINETO:
+ agg_path.line_to(x, y) 
+ elif code==CLOSEPOLY:
+ agg_path.close_polygon()
+ 
+ self.agg_path = agg_path
+ 
+ def _fillcolor_changed(self, oldcolor, newcolor): 
+ self.agg_fillcolor = self.color_to_rgba8(newcolor)
+
+ def _strokecolor_changed(self, oldcolor, newcolor): 
+
+ c = self.color_to_rgba8(newcolor)
+ print 'stroke change: old=%s, new=%s, agg=%s, ret=%s'%(
+ oldcolor, newcolor, self.agg_strokecolor, c)
+ self.agg_strokecolor = c
+
+
+ def color_to_rgba8(self, color):
+ if color is None: return None
+ rgba = [int(255*c) for c in color.r, color.g, color.b, color.a]
+ return agg.rgba8(*rgba)
+
+
 class Axis(Artist):
 tickcolor = mtraits.color('black')
 axiscolor = mtraits.color('black')
Modified: trunk/matplotlib/mpl1/test.py
===================================================================
--- trunk/matplotlib/mpl1/test.py	2007年07月19日 16:53:36 UTC (rev 3575)
+++ trunk/matplotlib/mpl1/test.py	2007年07月19日 17:04:19 UTC (rev 3576)
@@ -1,36 +1,50 @@
-import numpy
-from enthought.traits.api import HasTraits, Array, Delegate, Trait
+import numpy as npy
+import enthought.traits.api as traits
 
-Affine = Array('d', (3,3),
- value=numpy.array([[1,0,0], [0,1,0], [0,0,1]], numpy.float_))
 
-class C(HasTraits):
- affine1 = Affine
- affine2 = Affine 
- affine = Affine
+class C(traits.HasTraits):
+ x = traits.Float(0.0)
+ y = traits.Float(1.0)
 
- def _affine1_changed(self, old, new):
- self.affine = numpy.dot(new, self.affine2)
+class MyC(C):
+ xy = traits.Float(0.0)
 
- def _affine2_changed(self, old, new):
- self.affine = numpy.dot(self.affine1, new)
+ def __init__(self, c):
+ self.x = c.x
+ self.y = c.y
 
+ c.sync_trait('x', self)
+ c.sync_trait('y', self)
 
-class D(HasTraits):
- affine = Delegate('c')
- c = Trait(C)
+ def _x_changed(self, old, new):
+ self.xy = self.x * self.y
 
- 
+ def _y_changed(self, old, new):
+ self.xy = self.x * self.y
+
+
+# C objects are created at top level
 c = C()
-d = D()
-d.affine = c.affine
+c.x = 1
+c.y = 1
 
 
-print 'before c', type(c.affine), c.affine
-print 'before d', type(d.affine), d.affine
 
-c.affine1 = numpy.random.rand(3,3)
-print 'after c', type(c.affine), c.affine
-print 'after d', type(d.affine), d.affine
 
 
+class Backend:
+ 
+ def register_c(self, c):
+ # only gets C objects after creation
+ self.myc = MyC(c)
+
+backend = Backend()
+
+backend.register_c(c)
+
+c.x = 4
+
+print backend.myc.xy
+
+
+ 
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
From: <jd...@us...> - 2007年07月20日 13:44:13
Revision: 3586
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3586&view=rev
Author: jdh2358
Date: 2007年07月20日 06:44:10 -0700 (2007年7月20日)
Log Message:
-----------
traits cleanup
Modified Paths:
--------------
 trunk/matplotlib/mpl1/mpl1.py
 trunk/matplotlib/mpl1/test.py
Removed Paths:
-------------
 trunk/matplotlib/mpl1/mtraits.py
Modified: trunk/matplotlib/mpl1/mpl1.py
===================================================================
--- trunk/matplotlib/mpl1/mpl1.py	2007年07月20日 13:21:42 UTC (rev 3585)
+++ trunk/matplotlib/mpl1/mpl1.py	2007年07月20日 13:44:10 UTC (rev 3586)
@@ -2,9 +2,57 @@
 import enthought.traits.api as traits
 
 from matplotlib import agg
+from matplotlib import colors as mcolors
 import numpy as npy
 
-import mtraits # some handy traits for mpl
+
+class ColorHandler(traits.TraitHandler):
+ is_mapped = True
+
+ def post_setattr(self, object, name, value):
+ object.__dict__[ name + '_' ] = self.mapped_value( value )
+
+ def mapped_value(self, value ):
+ if value is None: return None
+ return mcolors.colorConverter.to_rgba(value)
+ 
+ 
+ def validate(self, object, name, value):
+ try:
+ self.mapped_value(value)
+ except ValueError:
+ return self.error(object, name, value)
+ else: 
+ return value
+
+ def info(self):
+ return """\
+any valid matplotlib color, eg an abbreviation like 'r' for red, a full
+name like 'orange', a hex color like '#efefef', a grayscale intensity
+like '0.5', or an RGBA tuple (1,0,0,1)"""
+
+class MTraitsNamespace:
+ DPI = traits.Float(72.)
+ Affine = traits.Array('d', (3,3), npy.array([[1,0,0],[0,1,0],[0,0,1]], npy.float_))
+ Alpha = traits.Range(0., 1., 0.)
+ AntiAliased = traits.true
+ Codes = traits.Array('b', value=npy.array([0,0], dtype=npy.uint8))
+ Color = traits.Trait('black', ColorHandler())
+ DPI = traits.Float(72.)
+ Interval = traits.Array('d', (2,), npy.array([0.0, 1.0], npy.float_))
+ LineStyle = traits.Trait('-', '--', '-.', ':', 'steps', None)
+ LineWidth = traits.Float(1.0)
+ Marker = traits.Trait(None, '.', ',', 'o', '^', 'v', '<', '>', 's',
+ '+', 'x', 'd', 'D', '|', '_', 'h', 'H',
+ 'p', '1', '2', '3', '4')
+ MarkerSize = traits.Float(6)
+ Verts = traits.Array('d', value=npy.array([[0,0],[0,0]], npy.float_))
+ PathData = traits.Tuple(Codes, Verts)
+ Visible = traits.true
+
+
+mtraits = MTraitsNamespace()
+
 
 def affine_axes(rect):
 'make an affine for a typical l,b,w,h axes rectangle'
@@ -35,7 +83,7 @@
 dtype=npy.float_)
 
 
-class Renderer:
+class Renderer(traits.HasTraits):
 dpi = traits.Float(72.)
 
 def __init__(self, width, height):
@@ -161,7 +209,7 @@
 Locs = npy.dot(affineverts, Locs)
 
 
- dpiscale = 1.0 # self.dpi/72. # for some reason this is broken 
+ dpiscale = self.dpi/72. # for some reason this is broken 
 # this will need to be highly optimized and hooked into some
 # extension code using cached marker rasters as we now do in
 # _backend_agg
@@ -210,15 +258,16 @@
 class Func(traits.HasTraits):
 def __call__(self, X):
 'transform the numpy array with shape N,2'
- raise NotImplementedError
+ return X
 
 def invert(self, x, y):
 'invert the point x, y'
- raise NotImplementedError
+ return x, y
 
 def point(self, x, y):
 'transform the point x, y'
- raise NotImplementedError
+ return x, y
+ 
 
 class Identity(Func):
 def __call__(self, X):
@@ -252,7 +301,7 @@
 raise NotImplementedError
 
 
-mtraits.Model = traits.Trait(None, Identity, Polar)
+mtraits.Model = traits.Instance(Func, ())
 
 
 
@@ -268,7 +317,7 @@
 fillcolor = mtraits.Color('blue')
 alpha = mtraits.Alpha(1.0)
 linewidth = mtraits.LineWidth(1.0)
- antialiased = mtraits.FlexibleTrueTrait()
+ antialiased = mtraits.AntiAliased
 pathdata = mtraits.PathData()
 affine = mtraits.Affine()
 
@@ -309,8 +358,8 @@
 # hmm, I would have thought these would be called by the attr
 # setting above
 self._pathdata_changed(None, self.pathdata)
- self._fillcolor_changed(None, self.fillcolor)
- self._strokecolor_changed(None, self.strokecolor) 
+ self._fillcolor__changed(None, self.fillcolor_)
+ self._strokecolor__changed(None, self.strokecolor_) 
 
 
 @staticmethod
@@ -334,10 +383,10 @@
 self.agg_path = AggPath.make_agg_path(newdata)
 
 
- def _fillcolor_changed(self, oldcolor, newcolor): 
+ def _fillcolor__changed(self, oldcolor, newcolor): 
 self.agg_fillcolor = self.color_to_rgba8(newcolor)
 
- def _strokecolor_changed(self, oldcolor, newcolor): 
+ def _strokecolor__changed(self, oldcolor, newcolor): 
 
 c = self.color_to_rgba8(newcolor)
 self.agg_strokecolor = c
@@ -345,7 +394,7 @@
 
 def color_to_rgba8(self, color):
 if color is None: return None
- rgba = [int(255*c) for c in color.r, color.g, color.b, color.a]
+ rgba = [int(255*c) for c in color]
 return agg.rgba8(*rgba)
 
 class Markers(traits.HasTraits):
@@ -405,8 +454,8 @@
 
 class Artist(traits.HasTraits):
 zorder = traits.Float(1.0)
- alpha = mtraits.Alpha(1.0)
- visible = mtraits.FlexibleTrueTrait()
+ alpha = mtraits.Alpha()
+ visible = mtraits.Visible()
 affine = mtraits.Affine()
 
 def __init__(self):
@@ -427,7 +476,7 @@
 class Line(Artist):
 
 linestyle = mtraits.LineStyle('-')
- antialiased = mtraits.FlexibleTrueTrait(True)
+ antialiased = mtraits.AntiAliased()
 color = mtraits.Color('blue')
 linewidth = mtraits.LineWidth(1.0) 
 marker = mtraits.Marker(None)
Deleted: trunk/matplotlib/mpl1/mtraits.py
===================================================================
--- trunk/matplotlib/mpl1/mtraits.py	2007年07月20日 13:21:42 UTC (rev 3585)
+++ trunk/matplotlib/mpl1/mtraits.py	2007年07月20日 13:44:10 UTC (rev 3586)
@@ -1,135 +0,0 @@
-"""
-Install instructions for traits 2.0
-
- # blow away old enthought
- rm -rf ~/dev/lib/python2.4/site-packages/enthought.*
-
- # get easy_install, if necessary
- wget http://peak.telecommunity.com/dist/ez_setup.py
- sudo python sez_setup.py
-
- sudo easy_install -f http://code.enthought.com/enstaller/eggs/source/unstable "enthought.etsconfig < 3.0a" "enthought.util <3.0a" "enthought.debug <3.0a"
-
- svn co https://svn.enthought.com/svn/enthought/branches/enthought.traits_2.0 enthought_traits
-
- cd enthought_traits/
- sudo python setup.py install 
-
-
-"""
-# Here is some example code showing how to define some representative
-# rc properties and construct a matplotlib artist using traits.
-# Because matplotlib ships with enthought traits already, you can run
-# this script with just matplotlib. Unfortunately, we do not ship the
-# ex UI component so you can't test that part. I'm a bit of a traits
-# newbie so there are probably better ways to do what I have done
-# below.
-
-import sys, os, re
-import enthought.traits.api as traits
-from matplotlib.cbook import is_string_like
-from matplotlib import colors as mcolors
-import numpy as npy
-
-doprint = True
-FlexibleTrueTrait = traits.Trait(
- True,
- { 'true': True, 't': True, 'yes': True, 'y': True, 'on': True, True: True,
- 'false': False, 'f': False, 'no': False, 'n': False, 'off': False, False: False
- } )
-FlexibleFalseTrait = traits.Trait( False, FlexibleTrueTrait )
-
-colors = mcolors.cnames
-
-def hex2color(s):
- "Convert hex string (like html uses, eg, #efefef) to a r,g,b tuple"
- return tuple([int(n, 16)/255.0 for n in (s[1:3], s[3:5], s[5:7])])
-
-def color_converter(x):
- return mcolors.colorConverter(x)
-class RGBA(traits.HasTraits):
- # r,g,b,a in the range 0-1 with default color 0,0,0,1 (black)
- r = traits.Range(0., 1., 0.)
- g = traits.Range(0., 1., 0.)
- b = traits.Range(0., 1., 0.)
- a = traits.Range(0., 1., 1.)
- def __init__(self, r=0., g=0., b=0., a=1.):
- self.r = r
- self.g = g
- self.b = b
- self.a = a
-
- def __repr__(self):
- return '(%1.2f, %1.2f, %1.2f, %1.2f)'%(self.r, self.g, self.b, self.a)
-
-def tuple_to_rgba(ob, name, val):
- tup = [float(x) for x in val]
- if len(tup)==3:
- r,g,b = tup
- return RGBA(r,g,b)
- elif len(tup)==4:
- r,g,b,a = tup
- return RGBA(r,g,b,a)
- else:
- raise ValueError
-tuple_to_rgba.info = 'a RGB or RGBA tuple of floats'
-
-def hex_to_rgba(ob, name, val):
- rgx = re.compile('^#[0-9A-Fa-f]{6}$')
-
- if not is_string_like(val):
- raise TypeError
- if rgx.match(val) is None:
- raise ValueError
- r,g,b = hex2color(val)
- return RGBA(r,g,b,1.0)
-hex_to_rgba.info = 'a hex color string'
-
-def colorname_to_rgba(ob, name, val):
- hex = colors[val.lower()]
- r,g,b = hex2color(hex)
- return RGBA(r,g,b,1.0)
-colorname_to_rgba.info = 'a named color'
-
-def float_to_rgba(ob, name, val):
- val = float(val)
- return RGBA(val, val, val, 1.)
-float_to_rgba.info = 'a grayscale intensity'
-
-
-
-def file_exists(ob, name, val):
- fh = file(val, 'r')
- return val
-
-def path_exists(ob, name, val):
- os.path.exists(val)
-linestyles = ('-', '--', '-.', ':', 'steps', None)
-TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN = range(4)
-linemarkers = (None, '.', ',', 'o', '^', 'v', '<', '>', 's',
- '+', 'x', 'd', 'D', '|', '_', 'h', 'H',
- 'p', '1', '2', '3', '4',
- TICKLEFT,
- TICKRIGHT,
- TICKUP,
- TICKDOWN,
- )
- 
-colorfuncs = RGBA(), float_to_rgba, colorname_to_rgba, RGBA, hex_to_rgba, tuple_to_rgba, None
-
-Affine = traits.Array('d', (3,3), npy.array([[1,0,0],[0,1,0],[0,0,1]], npy.float_))
-Alpha = traits.Float(1.0)
-Alpha = traits.Range(0., 1., 0.)
-Antialiased = FlexibleTrueTrait
-Codes = traits.Array('b', value=npy.array([0,0], dtype=npy.uint8))
-Color = traits.Trait(*colorfuncs)
-DPI = traits.Float(72.)
-Interval = traits.Array('d', (2,), npy.array([0.0, 1.0], npy.float_))
-LineStyle = traits.Trait(*linestyles)
-LineWidth = traits.Float(0.5)
-Marker = traits.Trait(*linemarkers)
-MarkerSize = traits.Float(6)
-Verts = traits.Array('d', value=npy.array([[0,0],[0,0]], npy.float_))
-PathData = traits.Tuple(Codes, Verts)
-
-
Modified: trunk/matplotlib/mpl1/test.py
===================================================================
--- trunk/matplotlib/mpl1/test.py	2007年07月20日 13:21:42 UTC (rev 3585)
+++ trunk/matplotlib/mpl1/test.py	2007年07月20日 13:44:10 UTC (rev 3586)
@@ -1,50 +1,19 @@
-import numpy as npy
-import enthought.traits.api as traits
+from enthought.traits.api import *
 
+def Alias(name):
+ return Property(lambda obj: getattr(obj, name),
+ lambda obj, val: setattr(obj, name, val))
 
-class C(traits.HasTraits):
- x = traits.Float(0.0)
- y = traits.Float(1.0)
+class Path(HasTraits):
+ strokecolor = Color()
 
-class MyC(C):
- xy = traits.Float(0.0)
 
- def __init__(self, c):
- self.x = c.x
- self.y = c.y
+class Line(Path):
+ color = Alias('strokecolor')
 
- c.sync_trait('x', self)
- c.sync_trait('y', self)
-
- def _x_changed(self, old, new):
- self.xy = self.x * self.y
-
- def _y_changed(self, old, new):
- self.xy = self.x * self.y
-
-
-# C objects are created at top level
-c = C()
-c.x = 1
-c.y = 1
-
-
-
-
-
-class Backend:
- 
- def register_c(self, c):
- # only gets C objects after creation
- self.myc = MyC(c)
-
-backend = Backend()
-
-backend.register_c(c)
-
-c.x = 4
-
-print backend.myc.xy
-
-
- 
+ def __init__(self, x, color='red'):
+ self.x = x
+ self.color = color
+ 
+line = Line(1)
+print line.strokecolor
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /