Revision: 3932
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3932&view=rev
Author: mdboom
Date: 2007-10-10 06:37:28 -0700 (Wed, 10 Oct 2007)
Log Message:
-----------
Lots more work on making examples work. Details, details, details...
Modified Paths:
--------------
branches/transforms/lib/matplotlib/axes.py
branches/transforms/lib/matplotlib/axis.py
branches/transforms/lib/matplotlib/backend_bases.py
branches/transforms/lib/matplotlib/backends/backend_agg.py
branches/transforms/lib/matplotlib/cbook.py
branches/transforms/lib/matplotlib/collections.py
branches/transforms/lib/matplotlib/colorbar.py
branches/transforms/lib/matplotlib/dates.py
branches/transforms/lib/matplotlib/figure.py
branches/transforms/lib/matplotlib/lines.py
branches/transforms/lib/matplotlib/scale.py
branches/transforms/lib/matplotlib/text.py
branches/transforms/lib/matplotlib/ticker.py
branches/transforms/lib/matplotlib/transforms.py
branches/transforms/src/_backend_agg.cpp
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py 2007-10-09 15:58:36 UTC (rev
3931)
+++ branches/transforms/lib/matplotlib/axes.py 2007-10-10 13:37:28 UTC (rev
3932)
@@ -477,7 +477,11 @@
""" % {'scale': ' | '.join([repr(x) for x in
mscale.get_scale_names()])}
martist.Artist.__init__(self)
- self._position = mtransforms.Bbox.from_lbwh(*rect)
+ if isinstance(rect, mtransforms.Bbox):
+ self._position = rect
+ else:
+ warnings.warn("Passing non-bbox as rect to Axes")
+ mtransforms.Bbox.from_lbwh(*rect)
self._originalPosition = self._position.frozen()
self.set_axes(self)
self.set_aspect('auto')
@@ -564,16 +568,16 @@
# It is assumed that this part will have non-linear components
self.transScale =
mtransforms.TransformWrapper(mtransforms.IdentityTransform())
- # A (possibly non-linear) projection on the (already scaled) data
- self.transProjection = mtransforms.IdentityTransform()
-
# An affine transformation on the data, generally to limit the
# range of the axes
self.transLimits = mtransforms.BboxTransform(
mtransforms.TransformedBbox(self.viewLim, self.transScale),
mtransforms.Bbox.unit())
-
- self.transData = self.transScale + self.transProjection +
self.transLimits + self.transAxes
+ # The parentheses are important for efficiency here -- they
+ # group the last two (which are usually affines) separately
+ # from the first (which, with log-scaling can be non-affine).
+ self.transData = self.transScale + (self.transLimits + self.transAxes)
+
self._xaxis_transform = mtransforms.blended_transform_factory(
self.axes.transData, self.axes.transAxes)
self._yaxis_transform = mtransforms.blended_transform_factory(
@@ -807,9 +811,9 @@
', '.join(mtransforms.BBox.coefs.keys()))
def get_data_ratio(self):
- xmin,xmax = self.get_xlim()
+ xmin,xmax = self.get_xbound()
xsize = max(math.fabs(xmax-xmin), 1e-30)
- ymin,ymax = self.get_ylim()
+ ymin,ymax = self.get_ybound()
ysize = max(math.fabs(ymax-ymin), 1e-30)
return ysize/xsize
@@ -819,7 +823,7 @@
axes box or the view limits.
'''
#MGDTODO: Numpify
-
+
if self._aspect == 'auto':
self.set_position( self._originalPosition , 'active')
return
@@ -843,7 +847,6 @@
self.set_position(pb1.anchored(self._anchor, pb), 'active')
return
-
xmin,xmax = self.get_xbound()
xsize = max(math.fabs(xmax-xmin), 1e-30)
ymin,ymax = self.get_ybound()
@@ -1519,7 +1522,9 @@
if xmin is None: xmin = old_xmin
if xmax is None: xmax = old_xmax
- xmax, xmin = mtransforms.nonsingular(xmax, xmin, increasing=False)
+ xmin, xmax = mtransforms.nonsingular(xmin, xmax)
+ xmin, xmax = self.xaxis.limit_range_for_scale(xmin, xmax)
+
self.viewLim.intervalx = (xmin, xmax)
if emit:
@@ -1678,6 +1683,7 @@
if ymax is None: ymax = old_ymax
ymin, ymax = mtransforms.nonsingular(ymin, ymax, increasing=False)
+ ymin, ymax = self.yaxis.limit_range_for_scale(ymin, ymax)
self.viewLim.intervaly = (ymin, ymax)
if emit:
@@ -1884,10 +1890,12 @@
.transformed(p.trans_inverse)
elif button == 3:
try:
- # MGDTODO: This is broken with log scales
- dx, dy = format_deltas(key, dx, dy)
dx = -dx / float(self.bbox.width)
dy = -dy / float(self.bbox.height)
+ dx, dy = format_deltas(key, dx, dy)
+ if self.get_aspect() != 'auto':
+ dx = 0.5 * (dx + dy)
+ dy = dx
xmin, ymin, xmax, ymax = p.lim.lbrt
alpha = npy.power(10.0, (dx, dy))
@@ -2375,7 +2383,7 @@
axvspan.__doc__ = cbook.dedent(axvspan.__doc__) % martist.kwdocd
- def hlines(self, y, xmin, xmax, colors='k', linestyle='solid',
+ def hlines(self, y, xmin, xmax, colors='k', linestyles='solid',
label='', **kwargs):
"""
HLINES(y, xmin, xmax, colors='k', linestyle='solid', **kwargs)
@@ -2417,7 +2425,7 @@
verts = [ ((thisxmin, thisy), (thisxmax, thisy))
for thisxmin, thisxmax, thisy in zip(xmin, xmax,
y)]
coll = mcoll.LineCollection(verts, colors=colors,
- linestyle=linestyle, label=label)
+ linestyles=linestyles, label=label)
self.add_collection(coll)
coll.update(kwargs)
@@ -4896,7 +4904,7 @@
self.set_xlabel('Frequency')
self.set_ylabel('Cross Spectrum Magnitude (dB)')
self.grid(True)
- vmin, vmax = self.viewLim.intervaly().get_bounds()
+ vmin, vmax = self.viewLim.intervaly
intv = vmax-vmin
step = 10*int(npy.log10(intv))
@@ -5177,8 +5185,7 @@
self.update_params()
# _axes_class is set in the subplot_class_factory
- self._axes_class.__init__(self, fig, [self.figLeft, self.figBottom,
- self.figW, self.figH], **kwargs)
+ self._axes_class.__init__(self, fig, self.figbox, **kwargs)
def get_geometry(self):
'get the subplot geometry, eg 2,2,3'
@@ -5190,7 +5197,7 @@
self._cols = numcols
self._num = num-1
self.update_params()
- self.set_position([self.figLeft, self.figBottom, self.figW,
self.figH])
+ self.set_position(self.figbox)
def update_params(self):
'update the subplot position from fig.subplotpars'
@@ -5220,10 +5227,7 @@
figBottom = top - (rowNum+1)*figH - rowNum*sepH
figLeft = left + colNum*(figW + sepW)
- self.figBottom = figBottom
- self.figLeft = figLeft
- self.figW = figW
- self.figH = figH
+ self.figbox = mtransforms.Bbox.from_lbwh(figLeft, figBottom, figW,
figH)
self.rowNum = rowNum
self.colNum = colNum
self.numRows = rows
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py 2007-10-09 15:58:36 UTC (rev
3931)
+++ branches/transforms/lib/matplotlib/axis.py 2007-10-10 13:37:28 UTC (rev
3932)
@@ -524,7 +524,10 @@
def set_scale(self, value, **kwargs):
self._scale = scale_factory(value, self, **kwargs)
self._scale.set_default_locators_and_formatters(self)
-
+
+ def limit_range_for_scale(self, vmin, vmax):
+ return self._scale.limit_range_for_scale(vmin, vmax, self.get_minpos())
+
def get_children(self):
children = [self.label]
majorticks = self.get_major_ticks()
@@ -580,6 +583,10 @@
'return the Interval instance for this axis data limits'
raise NotImplementedError('Derived must override')
+ def set_data_interval(self):
+ 'Set the axis data limits'
+ raise NotImplementedError('Derived must override')
+
def _set_artist_props(self, a):
if a is None: return
a.set_figure(self.figure)
@@ -887,7 +894,7 @@
ACCEPTS: A Formatter instance
"""
self.major.formatter = formatter
- self.major.formatter.set_axis(self)
+ formatter.set_axis(self)
def set_minor_formatter(self, formatter):
@@ -897,7 +904,7 @@
ACCEPTS: A Formatter instance
"""
self.minor.formatter = formatter
- self.minor.formatter.set_axis(self)
+ formatter.set_axis(self)
def set_major_locator(self, locator):
@@ -907,7 +914,7 @@
ACCEPTS: a Locator instance
"""
self.major.locator = locator
- self.major.locator.set_axis(self)
+ locator.set_axis(self)
def set_minor_locator(self, locator):
@@ -917,7 +924,7 @@
ACCEPTS: a Locator instance
"""
self.minor.locator = locator
- self.minor.locator.set_axis(self)
+ locator.set_axis(self)
def set_pickradius(self, pickradius):
"""
@@ -1180,7 +1187,15 @@
'return the Interval instance for this axis data limits'
return self.axes.dataLim.intervalx
+ def set_data_interval(self, vmin, vmax, ignore=False):
+ 'return the Interval instance for this axis data limits'
+ if ignore:
+ self.axes.dataLim.intervalx = vmin, vmax
+ else:
+ Vmin, Vmax = self.get_data_interval()
+ self.axes.dataLim.intervalx = min(vmin, Vmin), max(vmax, Vmax)
+
class YAxis(Axis):
__name__ = 'yaxis'
axis_name = 'y'
@@ -1395,5 +1410,12 @@
'return the Interval instance for this axis data limits'
return self.axes.dataLim.intervaly
+ def set_data_interval(self, vmin, vmax, ignore=False):
+ 'return the Interval instance for this axis data limits'
+ if ignore:
+ self.axes.dataLim.intervaly = vmin, vmax
+ else:
+ Vmin, Vmax = self.get_data_interval()
+ self.axes.dataLim.intervaly = min(vmin, Vmin), max(vmax, Vmax)
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py 2007-10-09 15:58:36 UTC
(rev 3931)
+++ branches/transforms/lib/matplotlib/backend_bases.py 2007-10-10 13:37:28 UTC
(rev 3932)
@@ -1598,7 +1598,7 @@
for a, ind in self._xypress:
a.end_pan()
if not self._xypress: return
- self._xypress = None
+ self._xypress = []
self._button_pressed=None
self.push_current()
self.release(event)
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-10-09
15:58:36 UTC (rev 3931)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-10-10
13:37:28 UTC (rev 3932)
@@ -381,11 +381,11 @@
return 'png'
def print_raw(self, filename, *args, **kwargs):
- self.draw()
+ FigureCanvasAgg.draw(self)
self.get_renderer()._renderer.write_rgba(str(filename))
print_rgba = print_raw
def print_png(self, filename, *args, **kwargs):
- self.draw()
- self.get_renderer()._renderer.write_png(str(filename),
self.figure.dpi.get())
+ FigureCanvasAgg.draw(self)
+ self.get_renderer()._renderer.write_png(str(filename), self.figure.dpi)
Modified: branches/transforms/lib/matplotlib/cbook.py
===================================================================
--- branches/transforms/lib/matplotlib/cbook.py 2007-10-09 15:58:36 UTC (rev
3931)
+++ branches/transforms/lib/matplotlib/cbook.py 2007-10-10 13:37:28 UTC (rev
3932)
@@ -1051,7 +1051,6 @@
a1 = a[1: ]
delta = ((a1 - a0) / steps)
- # MGDTODO: Could use linspace here?
for i in range(1, int(steps)):
result[i::steps] = delta * i + a0
result[steps::steps] = a1
Modified: branches/transforms/lib/matplotlib/collections.py
===================================================================
--- branches/transforms/lib/matplotlib/collections.py 2007-10-09 15:58:36 UTC
(rev 3931)
+++ branches/transforms/lib/matplotlib/collections.py 2007-10-10 13:37:28 UTC
(rev 3932)
@@ -59,12 +59,6 @@
_offsets = npy.zeros((1, 2))
_transOffset = transforms.IdentityTransform()
- _facecolors = [None]
- _edgecolors = [None]
- _lw = [1.0]
- _ls = [None]
- _aa = [True]
- _pickradius = 5.0
_transforms = [None]
zorder = 1
@@ -107,9 +101,8 @@
self._uniform_offsets = None
self._offsets = npy.zeros((1, 2))
if offsets is not None:
- offsets = npy.asarray(offsets)
- if len(offsets.shape) == 1:
- offsets = offsets[npy.newaxis,:] # Make it Nx2.
+# if len(offsets.shape) == 1:
+# offsets = offsets[npy.newaxis,:] # Make it Nx2.
if transOffset is not None:
Affine2D = transforms.Affine2D
self._offsets = offsets
@@ -152,29 +145,37 @@
transform = self.get_transform()
transOffset = self._transOffset
offsets = self._offsets
+ paths = self.get_paths()
- # MGDTODO: Transform the paths (since we don't keep track of segments
anymore
+ # MGDTODO: Test me
if self.have_units():
- segments = []
- for segment in self._segments:
+ paths = []
+ for path in self._paths:
+ vertices = path.vertices
xs, ys = zip(*segment)
xs = self.convert_xunits(xs)
ys = self.convert_yunits(ys)
- segments.append(zip(xs, ys))
-# if self._offsets is not None:
-# xs = self.convert_xunits(self._offsets[:0])
-# ys = self.convert_yunits(self._offsets[:1])
-# offsets = zip(xs, ys)
+ paths.append(path.Path(zip(xs, ys), path.codes))
+ if self._offsets is not None:
+ xs = self.convert_xunits(self._offsets[:0])
+ ys = self.convert_yunits(self._offsets[:1])
+ offsets = zip(xs, ys)
self.update_scalarmappable()
#print 'calling renderer draw line collection'
clippath, clippath_trans = self.get_transformed_clip_path_and_affine()
+ if not transform.is_affine:
+ paths = [transform.transform_path_non_affine(path) for path in
paths]
+ transform = transform.get_affine()
+
renderer.draw_path_collection(
transform, self.clipbox, clippath, clippath_trans,
- self.get_paths(), self.get_transforms(), offsets, transOffset,
- self._facecolors, self._edgecolors, self._lw, self._ls, self._aa)
+ paths, self.get_transforms(),
+ npy.asarray(offsets, npy.float_), transOffset,
+ self._facecolors, self._edgecolors, self._linewidths,
+ self._linestyles, self._antialiaseds)
renderer.close_group(self.__class__.__name__)
def contains(self, mouseevent):
@@ -190,7 +191,7 @@
self._offsetTrans, self._facecolors)
return len(ind)>0,dict(ind=ind)
- # MGDTODO
+ # MGDTODO: Update
def get_transformed_patches(self):
"""
get a sequence of the polygons in the collection in display
(transformed) space
@@ -272,7 +273,7 @@
except ValueError:
raise ValueError('Do not know how to convert %s to dashes'%ls)
- self._ls = dashes
+ self._linestyles = dashes
def set_color(self, c):
"""
@@ -328,13 +329,13 @@
self._edgecolors = [(r,g,b,alpha) for r,g,b,a in
self._edgecolors]
def get_linewidth(self):
- return self._lw
-
+ return self._linewidths
+
def get_linestyle(self):
- return self._ls
+ return self._linestyles
def get_dashes(self):
- return self._ls
+ return self._linestyles
def update_scalarmappable(self):
"""
@@ -509,14 +510,20 @@
self._sizes = sizes
self._dpi = dpi
self._paths = [path.Path.unit_regular_polygon(numsides)]
- self._transforms = [transforms.Affine2D().scale(x) for x in sizes]
+ # sizes is the area of the circle circumscribing the polygon
+ # in points^2
+ self._transforms = [
+ transforms.Affine2D().rotate(rotation).scale(
+ (math.sqrt(x) * self._dpi / 72.0) * (1.0 / math.sqrt(math.pi)))
+ for x in sizes]
+ self.set_transform(transforms.IdentityTransform())
__init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
def get_paths(self):
return self._paths
- # MGDTODO
+ # MGDTODO: Update
def get_transformed_patches(self):
# Shouldn't need all these calls to asarray;
# the variables should be converted when stored.
Modified: branches/transforms/lib/matplotlib/colorbar.py
===================================================================
--- branches/transforms/lib/matplotlib/colorbar.py 2007-10-09 15:58:36 UTC
(rev 3931)
+++ branches/transforms/lib/matplotlib/colorbar.py 2007-10-10 13:37:28 UTC
(rev 3932)
@@ -317,12 +317,13 @@
intv = transforms.Interval(transforms.Value(self._values[0]),
transforms.Value(self._values[-1]))
else:
- intv = transforms.Interval(transforms.Value(self.vmin),
- transforms.Value(self.vmax))
- locator.set_view_interval(intv)
- locator.set_data_interval(intv)
- formatter.set_view_interval(intv)
- formatter.set_data_interval(intv)
+ intv = self.vmin, self.vmax
+ locator.create_dummy_axis()
+ locator.set_view_interval(*intv)
+ locator.set_data_interval(*intv)
+ formatter.create_dummy_axis()
+ formatter.set_view_interval(*intv)
+ formatter.set_data_interval(*intv)
b = npy.array(locator())
b, ticks = self._locate(b)
formatter.set_locs(b)
Modified: branches/transforms/lib/matplotlib/dates.py
===================================================================
--- branches/transforms/lib/matplotlib/dates.py 2007-10-09 15:58:36 UTC (rev
3931)
+++ branches/transforms/lib/matplotlib/dates.py 2007-10-10 13:37:28 UTC (rev
3932)
@@ -429,13 +429,11 @@
self.tz = tz
def datalim_to_dt(self):
- self.verify_intervals()
- dmin, dmax = self.dataInterval.get_bounds()
+ dmin, dmax = self.axis.get_data_interval()
return num2date(dmin, self.tz), num2date(dmax, self.tz)
def viewlim_to_dt(self):
- self.verify_intervals()
- vmin, vmax = self.viewInterval.get_bounds()
+ vmin, vmax = self.axis.get_view_interval()
return num2date(vmin, self.tz), num2date(vmax, self.tz)
def _get_unit(self):
@@ -459,8 +457,6 @@
self.rule = o
def __call__(self):
- self.verify_intervals()
-
# if no data have been set, this will tank with a ValueError
try: dmin, dmax = self.viewlim_to_dt()
except ValueError: return []
@@ -500,7 +496,6 @@
"""
Set the view limits to include the data range
"""
- self.verify_intervals()
dmin, dmax = self.datalim_to_dt()
if dmin>dmax:
dmax, dmin = dmin, dmax
@@ -537,6 +532,10 @@
self.refresh()
return self._locator()
+ def set_axis(self, axis):
+ DateLocator.set_axis(self, axis)
+ self._locator.set_axis(axis)
+
def refresh(self):
'refresh internal information based on current lim'
dmin, dmax = self.viewlim_to_dt()
@@ -563,8 +562,6 @@
def autoscale(self):
'Try to choose the view limits intelligently'
-
- self.verify_intervals()
dmin, dmax = self.datalim_to_dt()
self._locator = self.get_locator(dmin, dmax)
return self._locator.autoscale()
@@ -667,9 +664,10 @@
bysecond=bysecond )
locator = RRuleLocator(rrule, self.tz)
-
- locator.set_view_interval(self.viewInterval)
- locator.set_data_interval(self.dataInterval)
+ locator.set_axis(self.axis)
+
+ locator.set_view_interval(*self.axis.get_view_interval())
+ locator.set_data_interval(*self.axis.get_data_interval())
return locator
@@ -710,8 +708,6 @@
return 365
def __call__(self):
- self.verify_intervals()
-
dmin, dmax = self.viewlim_to_dt()
ymin = self.base.le(dmin.year)
ymax = self.base.ge(dmax.year)
@@ -728,7 +724,6 @@
"""
Set the view limits to include the data range
"""
- self.verify_intervals()
dmin, dmax = self.datalim_to_dt()
ymin = self.base.le(dmin.year)
Modified: branches/transforms/lib/matplotlib/figure.py
===================================================================
--- branches/transforms/lib/matplotlib/figure.py 2007-10-09 15:58:36 UTC
(rev 3931)
+++ branches/transforms/lib/matplotlib/figure.py 2007-10-10 13:37:28 UTC
(rev 3932)
@@ -818,17 +818,17 @@
self.subplotpars.update(*args, **kwargs)
import matplotlib.axes
for ax in self.axes:
- if not isinstance(ax, matplotlib.axes.Subplot):
+ if not isinstance(ax, matplotlib.axes.SubplotBase):
# Check if sharing a subplots axis
- if ax._sharex is not None and isinstance(ax._sharex,
matplotlib.axes.Subplot):
+ if ax._sharex is not None and isinstance(ax._sharex,
matplotlib.axes.SubplotBase):
ax._sharex.update_params()
- ax.set_position([ax._sharex.figLeft, ax._sharex.figBottom,
ax._sharex.figW, ax._sharex.figH])
- elif ax._sharey is not None and isinstance(ax._sharey,
matplotlib.axes.Subplot):
+ ax.set_position(ax._sharex.figbox)
+ elif ax._sharey is not None and isinstance(ax._sharey,
matplotlib.axes.SubplotBase):
ax._sharey.update_params()
- ax.set_position([ax._sharey.figLeft, ax._sharey.figBottom,
ax._sharey.figW, ax._sharey.figH])
+ ax.set_position(ax._sharey.figbox)
else:
ax.update_params()
- ax.set_position([ax.figLeft, ax.figBottom, ax.figW, ax.figH])
+ ax.set_position(ax.figbox)
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py 2007-10-09 15:58:36 UTC (rev
3931)
+++ branches/transforms/lib/matplotlib/lines.py 2007-10-10 13:37:28 UTC (rev
3932)
@@ -300,18 +300,19 @@
raise ValueError,"pick radius should be a distance"
# transform in backend
- x = self._x
- y = self._y
- if len(x)==0: return False,{}
+ if len(self._xy)==0: return False,{}
- xt, yt = self.get_transform().numerix_x_y(x, y)
-
+ xyt = self.get_transform().transform(self._xy)
+ xt = xyt[:, 0]
+ yt = xyt[:, 1]
+
if self.figure == None:
print str(self),' has no figure set'
pixels = self.pickradius
else:
- pixels = self.figure.dpi.get()/72. * self.pickradius
-
+ pixels = self.figure.dpi/72. * self.pickradius
+
+ path, transform =
self._transformed_path.get_transformed_path_and_affine()
if self._linestyle == 'None':
# If no line, return the nearby point(s)
d = npy.sqrt((xt-mouseevent.x)**2 + (yt-mouseevent.y)**2)
@@ -384,11 +385,17 @@
def recache(self):
#if self.axes is None: print 'recache no axes'
#else: print 'recache units', self.axes.xaxis.units,
self.axes.yaxis.units
- x = ma.asarray(self.convert_xunits(self._xorig), float)
- y = ma.asarray(self.convert_yunits(self._yorig), float)
-
- x = ma.ravel(x)
- y = ma.ravel(y)
+ if ma.isMaskedArray(self._xorig) or ma.isMaskedArray(self._yorig):
+ x = ma.asarray(self.convert_xunits(self._xorig), float)
+ y = ma.asarray(self.convert_yunits(self._yorig), float)
+ x = ma.ravel(x)
+ y = ma.ravel(y)
+ else:
+ x = npy.asarray(self.convert_xunits(self._xorig), float)
+ y = npy.asarray(self.convert_yunits(self._yorig), float)
+ x = npy.ravel(x)
+ y = npy.ravel(y)
+
if len(x)==1 and len(y)>1:
x = x * npy.ones(y.shape, float)
if len(y)==1 and len(x)>1:
@@ -399,8 +406,11 @@
x = x.reshape((len(x), 1))
y = y.reshape((len(y), 1))
-
- self._xy = ma.concatenate((x, y), 1)
+
+ if ma.isMaskedArray(x) or ma.isMaskedArray(y):
+ self._xy = ma.concatenate((x, y), 1)
+ else:
+ self._xy = npy.concatenate((x, y), 1)
self._x = self._xy[:, 0] # just a view
self._y = self._xy[:, 1] # just a view
self._logcache = None
Modified: branches/transforms/lib/matplotlib/scale.py
===================================================================
--- branches/transforms/lib/matplotlib/scale.py 2007-10-09 15:58:36 UTC (rev
3931)
+++ branches/transforms/lib/matplotlib/scale.py 2007-10-10 13:37:28 UTC (rev
3932)
@@ -14,7 +14,10 @@
class ScaleBase(object):
def set_default_locators_and_formatters(self, axis):
raise NotImplementedError
-
+
+ def limit_range_for_scale(self, vmin, vmax, minpos):
+ return vmin, vmax
+
class LinearScale(ScaleBase):
name = 'linear'
@@ -39,6 +42,9 @@
is_separable = True
def transform(self, a):
+ # MGDTODO: Remove me
+ if len(a) > 10:
+ print "log transforming"
return ma.log10(ma.masked_where(a <= 0.0, a * 10.0))
def inverted(self):
@@ -159,6 +165,9 @@
def get_transform(self):
return self._transform
+ def limit_range_for_scale(self, vmin, vmax, minpos):
+ return (vmin <= 0.0 and minpos or vmin,
+ vmax <= 0.0 and minpos or vmax)
_scale_mapping = {
'linear' : LinearScale,
Modified: branches/transforms/lib/matplotlib/text.py
===================================================================
--- branches/transforms/lib/matplotlib/text.py 2007-10-09 15:58:36 UTC (rev
3931)
+++ branches/transforms/lib/matplotlib/text.py 2007-10-10 13:37:28 UTC (rev
3932)
@@ -179,14 +179,17 @@
key = self.get_prop_tup()
if self.cached.has_key(key): return self.cached[key]
horizLayout = []
- thisx, thisy = self._get_xy_display()
+ transform = self.get_transform()
+ x, y = self.get_position()
+ thisx, thisy = transform.transform_point((x, y))
+ tx, ty = thisx, thisy
+
width = 0
height = 0
xmin, ymin = thisx, thisy
lines = self._text.split('\n')
- # MGDTODO: whs could be a numpy.array
whs = []
# Find full vertical extent of font,
# including ascenders and descenders:
@@ -267,11 +270,10 @@
# now rotate the positions around the first x,y position
xys = M.transform(offsetLayout)
- xys[:, 0] += offsetx
- xys[:, 1] += offsety
+ xys += (offsetx, offsety)
# now inverse transform back to data coords
- inverse_transform = self.get_transform().inverted()
+ inverse_transform = transform.inverted()
xys = inverse_transform.transform(xys)
xs, ys = xys[:, 0], xys[:, 1]
@@ -781,13 +783,14 @@
# Compute the dash end points
# The 'c' prefix is for canvas coordinates
- cxy = npy.array(transform.xy_tup((dashx, dashy)))
+ cxy = transform.transform_point((dashx, dashy))
cd = npy.array([cos_theta, sin_theta])
c1 = cxy+dashpush*cd
c2 = cxy+(dashpush+dashlength)*cd
- (x1, y1) = transform.inverse_xy_tup(tuple(c1))
- (x2, y2) = transform.inverse_xy_tup(tuple(c2))
+ inverse = transform.inverted()
+ (x1, y1) = inverse.transform_point(tuple(c1))
+ (x2, y2) = inverse.transform_point(tuple(c2))
self.dashline.set_data((x1, x2), (y1, y2))
# We now need to extend this vector out to
@@ -805,7 +808,7 @@
# but I don't grok the transformation stuff
# well enough yet.
we = Text.get_window_extent(self, renderer=renderer)
- w, h = we.width(), we.height()
+ w, h = we.width, we.height
# Watch for zeros
if sin_theta == 0.0:
dx = w
@@ -824,13 +827,13 @@
cwd *= 1+dashpad/npy.sqrt(npy.dot(cwd,cwd))
cw = c2+(dashdirection*2-1)*cwd
- self._x, self._y = transform.inverse_xy_tup(tuple(cw))
+ self._x, self._y = inverse.transform_point(tuple(cw))
# Now set the window extent
# I'm not at all sure this is the right way to do this.
we = Text.get_window_extent(self, renderer=renderer)
- self._twd_window_extent = we.deepcopy()
- self._twd_window_extent.update(((c1[0], c1[1]),), False)
+ self._twd_window_extent = we.frozen()
+ self._twd_window_extent.update_from_data_xy(npy.array([c1]), False)
# Finally, make text align center
Text.set_horizontalalignment(self, 'center')
Modified: branches/transforms/lib/matplotlib/ticker.py
===================================================================
--- branches/transforms/lib/matplotlib/ticker.py 2007-10-09 15:58:36 UTC
(rev 3931)
+++ branches/transforms/lib/matplotlib/ticker.py 2007-10-10 13:37:28 UTC
(rev 3932)
@@ -116,10 +116,35 @@
class TickHelper:
axis = None
+ class DummyAxis:
+ def __init__(self):
+ self.dataLim = mtransforms.Bbox
+ self.viewLim = mtransforms.Bbox
+
+ def get_view_interval(self):
+ return self.viewLim.intervalx
+
+ def set_view_interval(self, vmin, vmax):
+ self.viewLim.intervalx = vmin, vmax
+
+ def get_data_interval(self):
+ return self.dataLim.intervalx
+
+ def set_data_interval(self, vmin, vmax):
+ self.dataLim.intervalx = vmin, vmax
+
def set_axis(self, axis):
self.axis = axis
+ def create_dummy_axis(self):
+ self.axis = self.DummyAxis()
+
+ def set_view_interval(self, vmin, vmax):
+ self.axis.set_view_interval(vmin, vmax)
+ def set_data_interval(self, vmin, vmax):
+ self.axis.set_data_interval(vmin, vmax)
+
class Formatter(TickHelper):
"""
Convert the tick location to a string
@@ -900,6 +925,9 @@
vmin, vmax = self.axis.get_view_interval()
if vmin <= 0.0:
vmin = self.axis.get_minpos()
+ if vmin <= 0.0:
+ raise ValueError(
+ "Data has no positive values, and therefore can not be
log-scaled.")
vmin = math.log(vmin)/math.log(b)
vmax = math.log(vmax)/math.log(b)
@@ -936,7 +964,8 @@
minpos = self.axis.get_minpos()
if minpos<=0:
- raise RuntimeError('No positive data to plot')
+ raise ValueError(
+ "Data has no positive values, and therefore can not be
log-scaled.")
if vmin <= minpos:
vmin = minpos
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py 2007-10-09 15:58:36 UTC
(rev 3931)
+++ branches/transforms/lib/matplotlib/transforms.py 2007-10-10 13:37:28 UTC
(rev 3932)
@@ -32,7 +32,7 @@
import cbook
from path import Path
-DEBUG = False
+DEBUG = True
class TransformNode(object):
"""
@@ -403,7 +403,6 @@
if len(x) == 0 or len(y) == 0:
return
- # MGDTODO: All getters of minpos should be aware that is is sometimes
-inf
if ma.isMaskedArray(x) or ma.isMaskedArray(y):
xpos = ma.where(x > 0.0, x, npy.inf)
ypos = ma.where(y > 0.0, y, npy.inf)
@@ -616,26 +615,28 @@
[EMAIL PROTECTED]
def union(bboxes):
"""
- Return a Bbox that bounds all the given bboxes.
+ Return a Bbox that contains all of the given bboxes.
"""
- # MGDTODO: There's got to be a way to utilize numpy here
- # to make this faster...
assert(len(bboxes))
if len(bboxes) == 1:
return bboxes[0]
-
- bbox = bboxes[0]
- xmin0, ymin0, xmax0, ymax0 = bbox.lbrt
- for bbox in bboxes[1:]:
- xmin, ymin, xmax, ymax = bbox.lbrt
- xmin0 = min(xmin0, xmin)
- ymin0 = min(ymin0, ymin)
- xmax0 = max(xmax0, xmax)
- ymax0 = max(ymax0, ymax)
+ xmin = npy.inf
+ ymin = npy.inf
+ xmax = -npy.inf
+ ymax = -npy.inf
- return Bbox.from_lbrt(xmin0, ymin0, xmax0, ymax0)
+ for bbox in bboxes:
+ points = bbox.get_points()
+ xs = points[:, 0]
+ ys = points[:, 1]
+ xmin = min(xmin, npy.min(xs))
+ ymin = min(ymin, npy.min(ys))
+ xmax = max(xmax, npy.max(xs))
+ ymax = max(ymax, npy.max(ys))
+
+ return Bbox.from_lbrt(xmin, ymin, xmax, ymax)
union = staticmethod(union)
@@ -1243,22 +1244,18 @@
# MGDTODO: The major speed trap here is just converting to
# the points to an array in the first place. If we can use
# more arrays upstream, that should help here.
- if DEBUG and not isinstance(values, npy.ndarray):
+ if DEBUG and not ma.isMaskedArray(points) and not isinstance(points,
npy.ndarray):
import traceback
print '-' * 60
- print 'A non-numpy array of type %s was passed in for
transformation.' % type(values)
+ print 'A non-numpy array of type %s was passed in for
transformation.' % type(points)
print 'Please correct this.'
print "".join(traceback.format_stack())
mtx = self.get_matrix()
if ma.isMaskedArray(points):
- points = points.transpose()
- points = ma.dot(mtx[0:2, 0:2], points)
- points = points + mtx[0:2, 2:]
+ points = ma.dot(mtx[0:2, 0:2], points.transpose()) + mtx[0:2, 2:]
else:
- points = npy.asarray(points, npy.float_)
- points = points.transpose()
- points = npy.dot(mtx[0:2, 0:2], points)
- points = points + mtx[0:2, 2:]
+ # points = npy.asarray(points, npy.float_)
+ points = npy.dot(mtx[0:2, 0:2], points.transpose()) + mtx[0:2, 2:]
return points.transpose()
transform.__doc__ = AffineBase.transform.__doc__
@@ -1558,7 +1555,10 @@
y_points = y.transform(points[:, 1])
y_points = y_points.reshape((len(y_points), 1))
- return ma.concatenate((x_points, y_points), 1)
+ if ma.isMaskedArray(x_points) or ma.isMaskedArray(y_points):
+ return ma.concatenate((x_points, y_points), 1)
+ else:
+ return npy.concatenate((x_points, y_points), 1)
transform.__doc__ = Transform.transform.__doc__
transform_non_affine = transform
@@ -1741,14 +1741,6 @@
return "CompositeGenericTransform(%s, %s)" % (self._a, self._b)
__str__ = __repr__
- # MGDTODO: Remove
-# def get_matrix(self):
-# if self._invalid:
-# assert self._a.is_affine and self._b.is_affine
-# self._mtx = npy.dot(self._b.get_matrix(), self._a.get_matrix())
-# self._invalid = 0
-# return self._mtx
-
def transform(self, points):
return self._b.transform(
self._a.transform(points))
@@ -1927,18 +1919,18 @@
the transform already applied, along with the affine part of
the path necessary to complete the transformation.
"""
- if (self._invalid != self.INVALID_AFFINE or
+ if (self._invalid & self.INVALID_NON_AFFINE or
self._transformed_path is None):
self._transformed_path = \
self._transform.transform_path_non_affine(self._path)
- self._invalid = 0
+ self._invalid = 0
return self._transformed_path, self._transform.get_affine()
def get_fully_transformed_path(self):
"""
Return a fully-transformed copy of the child path.
"""
- if (self._invalid != self.INVALID_AFFINE
+ if (self._invalid & self.INVALID_NON_AFFINE
or self._transformed_path is None):
self._transformed_path = \
self._transform.transform_path_non_affine(self._path)
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp 2007-10-09 15:58:36 UTC (rev
3931)
+++ branches/transforms/src/_backend_agg.cpp 2007-10-10 13:37:28 UTC (rev
3932)
@@ -527,10 +527,8 @@
RendererAgg::draw_markers(const Py::Tuple& args) {
typedef agg::conv_transform<PathIterator> transformed_path_t;
typedef conv_quantize<transformed_path_t> quantize_t;
- typedef agg::conv_curve<transformed_path_t> curve_t;
+ typedef agg::conv_curve<transformed_path_t> curve_t;
typedef agg::conv_stroke<curve_t> stroke_t;
- typedef agg::conv_dash<curve_t> dash_t;
- typedef agg::conv_stroke<dash_t> stroke_dash_t;
typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
typedef agg::renderer_base<pixfmt_amask_type>
amask_ren_type;
typedef agg::renderer_scanline_aa_solid<amask_ren_type>
amask_aa_renderer_type;
@@ -836,16 +834,30 @@
// Render face
if (face.first) {
- if (has_clippath) {
- pixfmt_amask_type pfa(*pixFmt, *alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
- ren.color(face.second);
- agg::render_scanlines(*theRasterizer, *slineP8, ren);
+ if (gc.isaa) {
+ if (has_clippath) {
+ pixfmt_amask_type pfa(*pixFmt, *alphaMask);
+ amask_ren_type r(pfa);
+ amask_aa_renderer_type ren(r);
+ ren.color(face.second);
+ agg::render_scanlines(*theRasterizer, *slineP8, ren);
+ } else {
+ rendererAA->color(face.second);
+ theRasterizer->add_path(curve);
+ agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
+ }
} else {
- rendererAA->color(face.second);
- theRasterizer->add_path(curve);
- agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA);
+ if (has_clippath) {
+ pixfmt_amask_type pfa(*pixFmt, *alphaMask);
+ amask_ren_type r(pfa);
+ amask_bin_renderer_type ren(r);
+ ren.color(face.second);
+ agg::render_scanlines(*theRasterizer, *slineP8, ren);
+ } else {
+ rendererBin->color(face.second);
+ theRasterizer->add_path(curve);
+ agg::render_scanlines(*theRasterizer, *slineP8, *rendererBin);
+ }
}
}
@@ -959,7 +971,7 @@
size_t Naa = antialiaseds.length();
size_t i = 0;
-
+
// Convert all of the transforms up front
typedef std::vector<agg::trans_affine> transforms_t;
transforms_t transforms;
@@ -1028,6 +1040,8 @@
bool has_clippath = render_clippath(clippath, clippath_trans);
for (i = 0; i < N; ++i) {
+ PathIterator path(paths[i % Npaths]);
+ bool snap = (path.total_vertices() == 2);
double xo = *(double*)PyArray_GETPTR2(offsets, i %
Noffsets, 0);
double yo = *(double*)PyArray_GETPTR2(offsets, i %
Noffsets, 1);
offset_trans.transform(&xo, &yo);
@@ -1039,8 +1053,6 @@
gc.dashes = dashes[i % Nlinestyles].second;
gc.dashOffset = dashes[i % Nlinestyles].first;
gc.isaa = bool(Py::Int(antialiaseds[i % Naa]));
- PathIterator path(paths[i % Npaths]);
- bool snap = (path.total_vertices() == 2);
_draw_path(path, trans * transOffset, snap, has_clippath, face, gc);
}
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: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins