You can subscribe to this list here.
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
| 2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
| 2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
| 2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <md...@us...> - 2007-09-24 17:33:08
|
Revision: 3886
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3886&view=rev
Author: mdboom
Date: 2007-09-24 10:33:03 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
Fixed log scaling again.
Modified Paths:
--------------
branches/transforms/lib/matplotlib/scale.py
branches/transforms/lib/matplotlib/ticker.py
branches/transforms/lib/matplotlib/transforms.py
Modified: branches/transforms/lib/matplotlib/scale.py
===================================================================
--- branches/transforms/lib/matplotlib/scale.py 2007-09-24 16:54:37 UTC (rev 3885)
+++ branches/transforms/lib/matplotlib/scale.py 2007-09-24 17:33:03 UTC (rev 3886)
@@ -23,6 +23,7 @@
self._base = base
self._viewLim = viewLim
self._direction = direction
+ self.set_children(['_viewLim'])
def transform(self, a):
a, affine = self.transform_without_affine(a)
@@ -31,13 +32,9 @@
def transform_without_affine(self, a):
# MGDTODO: Support different bases
base = self._base
- marray = ma.masked_where(a <= 0.0, a)
+ marray = ma.masked_where(a <= 0.0, a * 10.0)
marray = npy.log10(marray)
- minimum, maximum = getattr(self._viewLim, self._direction)
- minimum, maximum = npy.log10([minimum, maximum])
- print marray
- print Affine1D.from_values(maximum - minimum, minimum).inverted()
- print minimum, maximum
+ minimum, maximum = npy.log10(getattr(self._viewLim, self._direction) * 10.0)
return marray, Affine1D.from_values(maximum - minimum, minimum).inverted()
def inverted(self):
@@ -51,11 +48,12 @@
self._base = base
self._viewLim = viewLim
self._direction = direction
-
+ self.set_children(['_viewLim'])
+
def transform(self, a):
- minimum, maximum = getattr(self._viewLim, self._direction)
- Affine1D.from_values(maximum - minimum, minimum).transform(a)
- return ma.power(10.0, a)
+ minimum, maximum = npy.log10(getattr(self._viewLim, self._direction) * 10.0)
+ a = Affine1D.from_values(maximum - minimum, minimum).transform(a)
+ return ma.power(10.0, a) / 10.0
def inverted(self):
return LogScale.LogTransform(self._viewLim, self._direction, self._base)
Modified: branches/transforms/lib/matplotlib/ticker.py
===================================================================
--- branches/transforms/lib/matplotlib/ticker.py 2007-09-24 16:54:37 UTC (rev 3885)
+++ branches/transforms/lib/matplotlib/ticker.py 2007-09-24 17:33:03 UTC (rev 3886)
@@ -928,15 +928,19 @@
# if minpos<=0:
# raise RuntimeError('No positive data to plot')
- minpos = max(vmin, 0.00001) #MGDTODO
- if vmin<=0:
- vmin = minpos
+ # MGDTODO: Find a good way to track minpos
+ if vmin <= 0.0:
+ vmin = 0.1
+
if not is_decade(vmin,self._base): vmin = decade_down(vmin,self._base)
if not is_decade(vmax,self._base): vmax = decade_up(vmax,self._base)
if vmin==vmax:
vmin = decade_down(vmin,self._base)
vmax = decade_up(vmax,self._base)
- return mtransforms.nonsingular(vmin, vmax)
+ print vmin, vmax
+ result = mtransforms.nonsingular(vmin, vmax)
+ print result
+ return result
class AutoLocator(MaxNLocator):
def __init__(self):
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py 2007-09-24 16:54:37 UTC (rev 3885)
+++ branches/transforms/lib/matplotlib/transforms.py 2007-09-24 17:33:03 UTC (rev 3886)
@@ -181,7 +181,7 @@
def __init__(self, points):
BboxBase.__init__(self)
self._points = npy.asarray(points, npy.float_)
-
+
#@staticmethod
def unit():
return Bbox.from_lbrt(0., 0., 1., 1.)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-24 16:54:40
|
Revision: 3885
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3885&view=rev
Author: mdboom
Date: 2007-09-24 09:54:37 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
Merged revisions 3873-3884 via svnmerge from
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
r3874 | jouni | 2007-09-22 02:48:49 -0400 (Sat, 22 Sep 2007) | 3 lines
Replace some generator expressions by list comprehensions for
Python 2.3 compatibility
........
r3879 | dsdale | 2007-09-24 08:56:38 -0400 (Mon, 24 Sep 2007) | 2 lines
fix backend_qt* bug with multiple plot windows and show()
........
r3880 | dsdale | 2007-09-24 09:00:12 -0400 (Mon, 24 Sep 2007) | 2 lines
backend_qt* bugfix for multiple plot windows and show()
........
r3881 | dsdale | 2007-09-24 09:01:17 -0400 (Mon, 24 Sep 2007) | 2 lines
fix backend_wxagg reference in new config module
........
r3882 | dsdale | 2007-09-24 09:03:01 -0400 (Mon, 24 Sep 2007) | 3 lines
modifed embedding_in_qt* examples so they can be run from ipython with
-q*thread
........
r3883 | dsdale | 2007-09-24 11:11:58 -0400 (Mon, 24 Sep 2007) | 2 lines
fix bug in improved support for multiple windows in backend_qt4
........
Modified Paths:
--------------
branches/transforms/CHANGELOG
branches/transforms/examples/embedding_in_qt.py
branches/transforms/examples/embedding_in_qt4.py
branches/transforms/lib/matplotlib/backends/backend_pdf.py
branches/transforms/lib/matplotlib/backends/backend_qt.py
branches/transforms/lib/matplotlib/backends/backend_qt4.py
branches/transforms/lib/matplotlib/config/mpltraits.py
branches/transforms/lib/matplotlib/dviread.py
Property Changed:
----------------
branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
- /trunk/matplotlib:1-3872
+ /trunk/matplotlib:1-3884
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG 2007-09-24 16:53:38 UTC (rev 3884)
+++ branches/transforms/CHANGELOG 2007-09-24 16:54:37 UTC (rev 3885)
@@ -1,3 +1,7 @@
+2007-09-24 Applied Eike Welk's patch reported on mpl-dev on 2007-09-22
+ Fixes a bug with multiple plot windows in the qt backend,
+ ported the changes to backend_qt4 as well - DSD
+
2007-09-21 Changed cbook.reversed to yield the same result as the
python reversed builtin - DSD
Modified: branches/transforms/examples/embedding_in_qt.py
===================================================================
--- branches/transforms/examples/embedding_in_qt.py 2007-09-24 16:53:38 UTC (rev 3884)
+++ branches/transforms/examples/embedding_in_qt.py 2007-09-24 16:54:37 UTC (rev 3885)
@@ -25,7 +25,7 @@
# Note: color-intensive applications may require a different color allocation
# strategy.
-QApplication.setColorSpec(QApplication.NormalColor)
+#QApplication.setColorSpec(QApplication.NormalColor)
app = QApplication(sys.argv)
class MyMplCanvas(FigureCanvas):
@@ -129,12 +129,8 @@
% {"prog": progname, "version": progversion})
-def main():
- aw = ApplicationWindow()
- aw.setCaption("%s" % progname)
- qApp.setMainWidget(aw)
- aw.show()
- sys.exit(qApp.exec_loop())
-
-
-if __name__ == "__main__": main()
+aw = ApplicationWindow()
+aw.setCaption("%s" % progname)
+qApp.setMainWidget(aw)
+aw.show()
+sys.exit(qApp.exec_loop())
Modified: branches/transforms/examples/embedding_in_qt4.py
===================================================================
--- branches/transforms/examples/embedding_in_qt4.py 2007-09-24 16:53:38 UTC (rev 3884)
+++ branches/transforms/examples/embedding_in_qt4.py 2007-09-24 16:54:37 UTC (rev 3885)
@@ -122,17 +122,10 @@
% {"prog": progname, "version": progversion})
-def main():
- # Note: color-intensive applications may require a different color
- # allocation strategy.
- QtGui.QApplication.setColorSpec(QtGui.QApplication.NormalColor)
- qApp = QtGui.QApplication(sys.argv)
+qApp = QtGui.QApplication(sys.argv)
- aw = ApplicationWindow()
- aw.setWindowTitle("%s" % progname)
- aw.show()
-# sys.exit(qApp.exec_())
- qApp.exec_()
-
-
-if __name__ == "__main__": main()
+aw = ApplicationWindow()
+aw.setWindowTitle("%s" % progname)
+aw.show()
+sys.exit(qApp.exec_())
+#qApp.exec_()
Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-09-24 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-09-24 16:54:37 UTC (rev 3885)
@@ -541,10 +541,10 @@
widths[ch] = afmdata.get_width_char(ch, isord=True)
except KeyError:
pass
- not_None = (ch for ch in range(256)
- if widths[ch] is not None)
- firstchar = not_None.next()
- lastchar = max(not_None)
+ not_None = [ch for ch in range(256)
+ if widths[ch] is not None]
+ firstchar = not_None[0]
+ lastchar = not_None[-1]
widths = widths[firstchar:lastchar+1]
for i,w in enumerate(widths):
if w is None: widths[i] = 0
Modified: branches/transforms/lib/matplotlib/backends/backend_qt.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_qt.py 2007-09-24 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/backends/backend_qt.py 2007-09-24 16:54:37 UTC (rev 3885)
@@ -46,11 +46,11 @@
qApp = qt.QApplication( [" "] )
qt.QObject.connect( qApp, qt.SIGNAL( "lastWindowClosed()" ),
qApp, qt.SLOT( "quit()" ) )
- else:
- # someone else aready created the qApp and
- # we let them handle the event-loop control.
- show._needmain = False
+ #remember that matplotlib created the qApp - will be used by show()
+ _create_qApp.qAppCreatedHere = True
+_create_qApp.qAppCreatedHere = False
+
def show():
"""
Show all the figures and enter the qt main loop
@@ -65,13 +65,10 @@
if figManager != None:
figManager.canvas.draw()
- if ( show._needmain ):
- qt.qApp.exec_loop()
- show._needmain = False
+ if _create_qApp.qAppCreatedHere:
+ qt.qApp.exec_loop()
-show._needmain = True
-
def new_figure_manager( num, *args, **kwargs ):
"""
Create a new figure manager instance
Modified: branches/transforms/lib/matplotlib/backends/backend_qt4.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_qt4.py 2007-09-24 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/backends/backend_qt4.py 2007-09-24 16:54:37 UTC (rev 3885)
@@ -46,11 +46,11 @@
qApp = QtGui.QApplication( [" "] )
QtCore.QObject.connect( qApp, QtCore.SIGNAL( "lastWindowClosed()" ),
qApp, QtCore.SLOT( "quit()" ) )
- else:
- # someone else aready created the qApp and
- # we let them handle the event-loop control.
- show._needmain = False
+ #remember that matplotlib created the qApp - will be used by show()
+ _create_qApp.qAppCreatedHere = True
+_create_qApp.qAppCreatedHere = False
+
def show():
"""
Show all the figures and enter the qt main loop
@@ -65,13 +65,10 @@
if figManager != None:
figManager.canvas.draw()
- if ( show._needmain ):
- qApp.exec_()
- show._needmain = False
+ if _create_qApp.qAppCreatedHere:
+ QtGui.qApp.exec_()
-show._needmain = True
-
def new_figure_manager( num, *args, **kwargs ):
"""
Create a new figure manager instance
Modified: branches/transforms/lib/matplotlib/config/mpltraits.py
===================================================================
--- branches/transforms/lib/matplotlib/config/mpltraits.py 2007-09-24 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/config/mpltraits.py 2007-09-24 16:54:37 UTC (rev 3885)
@@ -29,7 +29,7 @@
'gtkcairo': 'GTKCairo',
'qt4agg': 'Qt4Agg',
'qtagg': 'QtAgg',
- 'wxagg': 'WxAgg',
+ 'wxagg': 'WXAgg',
'agg': 'Agg',
'cairo': 'Cairo',
'ps': 'PS',
Modified: branches/transforms/lib/matplotlib/dviread.py
===================================================================
--- branches/transforms/lib/matplotlib/dviread.py 2007-09-24 16:53:38 UTC (rev 3884)
+++ branches/transforms/lib/matplotlib/dviread.py 2007-09-24 16:54:37 UTC (rev 3885)
@@ -350,9 +350,9 @@
def _xxx(self, special):
matplotlib.verbose.report(
'Dvi._xxx: encountered special: %s'
- % ''.join((32 <= ord(ch) < 127) and ch
- or '<%02x>' % ord(ch)
- for ch in special),
+ % ''.join([(32 <= ord(ch) < 127) and ch
+ or '<%02x>' % ord(ch)
+ for ch in special]),
'debug')
def _fnt_def(self, k, c, s, d, a, l, n):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-24 16:53:40
|
Revision: 3884
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3884&view=rev
Author: mdboom
Date: 2007-09-24 09:53:38 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
More progress. (Kind of a broken mess at the moment.)
Modified Paths:
--------------
branches/transforms/lib/matplotlib/axes.py
branches/transforms/lib/matplotlib/axis.py
branches/transforms/lib/matplotlib/ticker.py
branches/transforms/lib/matplotlib/transforms.py
Added Paths:
-----------
branches/transforms/lib/matplotlib/scale.py
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py 2007-09-24 15:11:58 UTC (rev 3883)
+++ branches/transforms/lib/matplotlib/axes.py 2007-09-24 16:53:38 UTC (rev 3884)
@@ -25,6 +25,7 @@
from matplotlib import patches as mpatches
from matplotlib import pbox as mpbox
from matplotlib import quiver as mquiver
+from matplotlib import scale as mscale
from matplotlib import table as mtable
from matplotlib import text as mtext
from matplotlib import ticker as mticker
@@ -449,7 +450,6 @@
**kwargs
):
"""
-
Build an Axes instance in Figure with
rect=[left, bottom, width,height in Figure coords
@@ -467,8 +467,8 @@
navigate: True|False
navigate_mode: the navigation toolbar button status: 'PAN', 'ZOOM', or None
position: [left, bottom, width,height in Figure coords
- sharex : an Axes instance to share the x-axis with
- sharey : an Axes instance to share the y-axis with
+ sharex: an Axes instance to share the x-axis with
+ sharey: an Axes instance to share the y-axis with
title: the title string
visible: a boolean - whether the axes is visible
xlabel: the xlabel
@@ -491,7 +491,7 @@
self.set_adjustable('box')
self.set_anchor('C')
- # must be set before set_figure
+ # MGDTODO: Check that the axes being shared are scalable
self._sharex = sharex
self._sharey = sharey
if sharex is not None:
@@ -508,7 +508,7 @@
# this call may differ for non-sep axes, eg polar
self._init_axis()
-
+
if axisbg is None: axisbg = rcParams['axes.facecolor']
self._axisbg = axisbg
self._frameon = frameon
@@ -545,8 +545,8 @@
"move this out of __init__ because non-separable axes don't use it"
self.xaxis = maxis.XAxis(self)
self.yaxis = maxis.YAxis(self)
+ self._update_transAxisXY()
-
def sharex_foreign(self, axforeign):
"""
You can share your x-axis view limits with another Axes in the
@@ -627,26 +627,17 @@
set the dataLim and viewLim BBox attributes and the
transData and transAxes Transformation attributes
"""
- self.viewLim = mtransforms.Bbox.unit()
self.dataLim = mtransforms.Bbox.unit()
-
+ self.viewLim = mtransforms.Bbox.unit()
self.transAxes = mtransforms.BboxTransform(
mtransforms.Bbox.unit(), self.bbox)
- # self.set_transform(self.transAxes)
-# self.transData = mtransforms.BboxTransform(
-# self.viewLim, self.bbox)
- self.preDataTransform = mtransforms.BboxTransform(
- self.viewLim, mtransforms.Bbox.unit())
-# self.dataTransform = mtransforms.TestPolarTransform()
-# self.dataTransform = mtransforms.blended_transform_factory(
-# mtransforms.TestLogTransform(),
-# mtransforms.Affine2D())
- self.dataTransform = mtransforms.Affine2D()
- self.transData = self.preDataTransform + self.dataTransform + mtransforms.BboxTransform(
- mtransforms.Bbox.unit(), self.bbox)
- self.transData.make_graphviz(open("trans.dot", "w"))
+ self.transAxisXY = mtransforms.TransformWrapper()
+ self.transData = self.transAxisXY + self.transAxes
+
+ def _update_transAxisXY(self):
+ self.transAxisXY.set(mtransforms.blended_transform_factory(
+ self.xaxis.get_transform(), self.yaxis.get_transform()))
-
def get_position(self, original=False):
'Return the axes rectangle left, bottom, width, height'
if original:
@@ -1525,11 +1516,9 @@
def get_xscale(self):
'return the xaxis scale string: log or linear'
- # MGDTODO
- # return self.scaled[self.transData.get_funcx().get_type()]
- return 'log'
+ return self.xaxis.get_scale()
- def set_xscale(self, value, basex = 10, subsx=None):
+ def set_xscale(self, value, **kwargs):
"""
SET_XSCALE(value, basex=10, subsx=None)
@@ -1547,27 +1536,9 @@
ACCEPTS: ['log' | 'linear' ]
"""
-
- #if subsx is None: subsx = range(2, basex)
- assert(value.lower() in ('log', 'linear', ))
- if value == 'log':
- # MGDTODO
-# self.xaxis.set_major_locator(mticker.LogLocator(basex))
-# self.xaxis.set_major_formatter(mticker.LogFormatterMathtext(basex))
-# self.xaxis.set_minor_locator(mticker.LogLocator(basex,subsx))
-# self.transData.get_funcx().set_type(mtrans.LOG10)
-# minx, maxx = self.get_xlim()
-# if min(minx, maxx)<=0:
-# self.autoscale_view()
- pass
- elif value == 'linear':
- self.xaxis.set_major_locator(mticker.AutoLocator())
- self.xaxis.set_major_formatter(mticker.ScalarFormatter())
- self.xaxis.set_minor_locator(mticker.NullLocator())
- self.xaxis.set_minor_formatter(mticker.NullFormatter())
- # self.transData.get_funcx().set_type( mtrans.IDENTITY )
- self.transData.get_funcx().set_type( 0 ) # MGDTODO
-
+ self.xaxis.set_scale(value, **kwargs)
+ self._update_transAxisXY()
+
def get_xticks(self):
'Return the x ticks as a list of locations'
return self.xaxis.get_ticklocs()
@@ -1655,9 +1626,8 @@
def get_yscale(self):
'return the yaxis scale string: log or linear'
- # return self.scaled[self.transData.get_funcy().get_type()]
- return 'linear'
-
+ return self.yaxis.get_scale()
+
def set_yscale(self, value, basey=10, subsy=None):
"""
SET_YSCALE(value, basey=10, subsy=None)
@@ -1676,29 +1646,9 @@
ACCEPTS: ['log' | 'linear']
"""
-
- #if subsy is None: subsy = range(2, basey)
- assert(value.lower() in ('log', 'linear', ))
-
- if value == 'log':
- # MGDTODO
-# self.yaxis.set_major_locator(mticker.LogLocator(basey))
-# self.yaxis.set_major_formatter(mticker.LogFormatterMathtext(basey))
-# self.yaxis.set_minor_locator(mticker.LogLocator(basey,subsy))
-# self.transData.get_funcy().set_type(mtrans.LOG10)
-# miny, maxy = self.get_ylim()
-# if min(miny, maxy)<=0:
-# self.autoscale_view()
- pass
-
- elif value == 'linear':
- self.yaxis.set_major_locator(mticker.AutoLocator())
- self.yaxis.set_major_formatter(mticker.ScalarFormatter())
- self.yaxis.set_minor_locator(mticker.NullLocator())
- self.yaxis.set_minor_formatter(mticker.NullFormatter())
- # self.transData.get_funcy().set_type( mtrans.IDENTITY ) MGDTODO
- self.transData.get_funcy().set_type( 0 )
-
+ self.yaxis.set_scale(value, basey, subsy)
+ self._update_transAxisXY()
+
def get_yticks(self):
'Return the y ticks as a list of locations'
return self.yaxis.get_ticklocs()
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py 2007-09-24 15:11:58 UTC (rev 3883)
+++ branches/transforms/lib/matplotlib/axis.py 2007-09-24 16:53:38 UTC (rev 3884)
@@ -12,14 +12,15 @@
from lines import Line2D, TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN
from matplotlib import rcParams
from patches import bbox_artist
-from ticker import NullFormatter, FixedFormatter, ScalarFormatter, LogFormatter
+from ticker import NullFormatter, FixedFormatter, ScalarFormatter, LogFormatter, LogFormatterMathtext
from ticker import NullLocator, FixedLocator, LinearLocator, LogLocator, AutoLocator
from font_manager import FontProperties
from text import Text, TextWithDash, _process_text_args
from transforms import Affine2D, Bbox, blended_transform_factory, interval_contains, \
- interval_contains_open
+ interval_contains_open, IntervalTransform
from patches import bbox_artist
+from scale import LinearScale, LogScale
import matplotlib.units as units
#import pdb
@@ -479,7 +480,7 @@
"""
LABELPAD = 5
OFFSETTEXTPAD = 3
-
+
def __str__(self):
return str(self.__class__).split('.')[-1] \
+ "(%d,%d)"%self.axes.transAxes.xy_tup((0,0))
@@ -507,9 +508,38 @@
self.majorTicks = []
self.minorTicks = []
self.pickradius = pickradius
-
+ self._transform = LinearScale(self.axes.viewLim, self.axis).get_transform()
+ self._scale = 'linear'
+
self.cla()
+ def get_transform(self):
+ return self._transform
+
+ def get_scale(self):
+ return self._scale
+
+ def set_scale(self, value, base=10, subs=None):
+ # MGDTODO: Move these settings (ticker etc.) into the scale class itself
+ value = value.lower()
+ assert value.lower() in ('log', 'linear')
+ if value == 'linear':
+ self.set_major_locator(AutoLocator())
+ self.set_major_formatter(ScalarFormatter())
+ self.set_minor_locator(NullLocator())
+ self.set_minor_formatter(NullFormatter())
+ self._transform = LinearScale(self.axes.viewLim, self.axis).get_transform()
+ elif value == 'log':
+ self.set_major_locator(LogLocator(base))
+ self.set_major_formatter(LogFormatterMathtext(base))
+ self.set_minor_locator(LogLocator(base,subs))
+ # MGDTODO: Pass base along
+ self._transform = LogScale(self.axes.viewLim, self.axis).get_transform()
+ miny, maxy = getattr(self.axes.viewLim, 'interval' + self.axis)
+ if min(miny, maxy)<=0:
+ self.axes.autoscale_view()
+ self._scale = value
+
def get_children(self):
children = [self.label]
children.extend(self.majorTicks)
@@ -595,7 +625,7 @@
for tick, loc, label in zip(minorTicks, minorLocs, minorLabels):
if tick is None: continue
- if not interval.contains(loc): continue
+ if not interval_contains(interval, loc): continue
#if seen.has_key(loc): continue
tick.update_position(loc)
tick.set_label1(label)
@@ -952,7 +982,8 @@
class XAxis(Axis):
__name__ = 'xaxis'
-
+ axis = 'x'
+
def contains(self,mouseevent):
"""Test whether the mouse event occured in the x axis.
"""
@@ -1134,7 +1165,8 @@
class YAxis(Axis):
__name__ = 'yaxis'
-
+ axis = 'y'
+
def contains(self,mouseevent):
"""Test whether the mouse event occurred in the y axis.
Added: branches/transforms/lib/matplotlib/scale.py
===================================================================
--- branches/transforms/lib/matplotlib/scale.py (rev 0)
+++ branches/transforms/lib/matplotlib/scale.py 2007-09-24 16:53:38 UTC (rev 3884)
@@ -0,0 +1,78 @@
+import numpy as npy
+from numpy import ma
+
+from transforms import Affine1D, IntervalTransform, Transform
+
+class ScaleBase(object):
+ pass
+
+class LinearScale(ScaleBase):
+ def __init__(self, viewLim, direction):
+ direction = 'interval' + direction
+ self._transform = IntervalTransform(viewLim, direction)
+
+ def get_transform(self):
+ return self._transform
+
+class LogScale(ScaleBase):
+ class LogTransform(Transform):
+ input_dims = 1
+ output_dims = 1
+ def __init__(self, viewLim, direction, base):
+ Transform.__init__(self)
+ self._base = base
+ self._viewLim = viewLim
+ self._direction = direction
+
+ def transform(self, a):
+ a, affine = self.transform_without_affine(a)
+ return affine.transform(a)
+
+ def transform_without_affine(self, a):
+ # MGDTODO: Support different bases
+ base = self._base
+ marray = ma.masked_where(a <= 0.0, a)
+ marray = npy.log10(marray)
+ minimum, maximum = getattr(self._viewLim, self._direction)
+ minimum, maximum = npy.log10([minimum, maximum])
+ print marray
+ print Affine1D.from_values(maximum - minimum, minimum).inverted()
+ print minimum, maximum
+ return marray, Affine1D.from_values(maximum - minimum, minimum).inverted()
+
+ def inverted(self):
+ return LogScale.InvertedLogTransform(self._viewLim, self._direction, self._base)
+
+ class InvertedLogTransform(Transform):
+ input_dims = 1
+ output_dims = 1
+ def __init__(self, viewLim, direction, base):
+ Transform.__init__(self)
+ self._base = base
+ self._viewLim = viewLim
+ self._direction = direction
+
+ def transform(self, a):
+ minimum, maximum = getattr(self._viewLim, self._direction)
+ Affine1D.from_values(maximum - minimum, minimum).transform(a)
+ return ma.power(10.0, a)
+
+ def inverted(self):
+ return LogScale.LogTransform(self._viewLim, self._direction, self._base)
+
+ def __init__(self, viewLim, direction, base=10):
+ direction = 'interval' + direction
+ self._transform = self.LogTransform(viewLim, direction, base)
+
+ def get_transform(self):
+ return self._transform
+
+
+_scale_mapping = {
+ 'linear': LinearScale,
+ 'log': LogScale
+ }
+def scale_factory(scale, viewLim, direction):
+ if scale is None:
+ scale = 'linear'
+ return _scale_mapping[scale](viewLim, direction)
Modified: branches/transforms/lib/matplotlib/ticker.py
===================================================================
--- branches/transforms/lib/matplotlib/ticker.py 2007-09-24 15:11:58 UTC (rev 3883)
+++ branches/transforms/lib/matplotlib/ticker.py 2007-09-24 16:53:38 UTC (rev 3884)
@@ -500,8 +500,6 @@
def __call__(self, x, pos=None):
'Return the format for tick val x at position pos'
- self.verify_intervals()
-
b = self._base
# only label the decades
fx = math.log(x)/math.log(b)
@@ -890,10 +888,9 @@
def __call__(self):
'Return the locations of the ticks'
- self.verify_intervals()
b=self._base
- vmin, vmax = self.viewInterval.get_bounds()
+ vmin, vmax = self.axis.get_view_interval()
vmin = math.log(vmin)/math.log(b)
vmax = math.log(vmax)/math.log(b)
@@ -922,16 +919,16 @@
def autoscale(self):
'Try to choose the view limits intelligently'
- self.verify_intervals()
-
- vmin, vmax = self.dataInterval.get_bounds()
+ vmin, vmax = self.axis.get_view_interval()
if vmax<vmin:
vmin, vmax = vmax, vmin
- minpos = self.dataInterval.minpos()
+# minpos = self.dataInterval.minpos()
- if minpos<=0:
- raise RuntimeError('No positive data to plot')
+# if minpos<=0:
+# raise RuntimeError('No positive data to plot')
+
+ minpos = max(vmin, 0.00001) #MGDTODO
if vmin<=0:
vmin = minpos
if not is_decade(vmin,self._base): vmin = decade_down(vmin,self._base)
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py 2007-09-24 15:11:58 UTC (rev 3883)
+++ branches/transforms/lib/matplotlib/transforms.py 2007-09-24 16:53:38 UTC (rev 3884)
@@ -9,7 +9,7 @@
from numpy.linalg import inv
from sets import Set
-DEBUG = True
+DEBUG = False
# MGDTODO: This creates a ton of cyclical references. We may want to
# consider using weak references
@@ -61,8 +61,8 @@
def is_bbox(self):
return isinstance(self, BboxBase)
+
-
class BboxBase(TransformNode):
'''
This is the read-only part of a bounding-box
@@ -378,11 +378,30 @@
def is_separable(self):
return False
-
-class Affine2DBase(Transform):
+
+class TransformWrapper(Transform):
input_dims = 2
output_dims = 2
+
+ def set(self, child):
+ self.child = child
+ self.child._parents.add(self)
+ self.invalidate()
+ def transform(self, points):
+ return self.child.transform(points)
+
+ def transform_without_affine(points):
+ return self.child.transform_without_affine(points)
+
+ def inverted(self):
+ return self.child.inverted()
+
+ def is_separable(self):
+ return self.child.is_separable()
+
+
+class AffineBase(Transform):
def __init__(self):
Transform.__init__(self)
self._inverted = None
@@ -400,11 +419,173 @@
#@staticmethod
def concat(a, b):
- return Affine2D(Affine2D._concat(a.get_matrix(), b.get_matrix()))
+ return Affine1D(Affine1D._concat(a.get_matrix(), b.get_matrix()))
concat = staticmethod(concat)
+
+ def get_matrix(self):
+ raise NotImplementedError()
+
+ def transform_without_affine(self, points):
+ # MGDTODO: Should we copy the points here? I'd like to avoid it,
+ # if possible
+ return points, self
+
+class Affine1DBase(AffineBase):
+ input_dims = 1
+ output_dims = 1
+
+ def __init__(self):
+ AffineBase.__init__(self)
+
+ def __array__(self, *args, **kwargs):
+ return self.get_matrix()
+
def to_values(self):
mtx = self.get_matrix()
+ return tuple(mtx[0])
+
+ #@staticmethod
+ def matrix_from_values(a, b):
+ affine = npy.zeros((2, 2), npy.float_)
+ affine[0, :] = (a, b)
+ affine[1, 1] = 1
+ return affine
+ matrix_from_values = staticmethod(matrix_from_values)
+
+ def transform(self, values):
+ """
+ Applies the transformation to an array of values and
+ returns the result.
+ """
+ # 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 not isinstance(points, npy.ndarray):
+# import traceback
+# print '-' * 60
+# print 'A non-numpy array was passed in for transformation. Please '
+# print 'correct this.'
+# print "".join(traceback.format_stack())
+# print points
+ mtx = self.get_matrix()
+ points = ma.asarray(values, npy.float_)
+ return points * mtx[0,0] + mtx[0,1]
+
+ def is_separable(self):
+ return True
+
+ def inverted(self):
+ if self._inverted is None:
+ mtx = self.get_matrix()
+ self._inverted = Affine1D(inv(mtx))
+ return self._inverted
+
+
+class Affine1D(Affine1DBase):
+ def __init__(self, matrix = None):
+ """
+ Initialize an Affine transform from a 2x2 numpy float array.
+
+ a b
+ 0 1
+ """
+ Affine1DBase.__init__(self)
+ if matrix is None:
+ matrix = npy.identity(2)
+ else:
+ matrix = npy.asarray(matrix, npy.float_)
+ assert matrix.shape == (2, 2)
+ self._mtx = matrix
+
+ def __repr__(self):
+ return "Affine1D(%s)" % repr(self._mtx)
+ __str__ = __repr__
+
+ def __cmp__(self, other):
+ if (isinstance(other, Affine1D) and
+ (self.get_matrix() == other.get_matrix()).all()):
+ return 0
+ return -1
+
+ #@staticmethod
+ def from_values(a, b):
+ return Affine1D(Affine1D.matrix_from_values(a, b))
+ from_values = staticmethod(from_values)
+
+ def get_matrix(self):
+ return self._mtx
+
+ def set_matrix(self, mtx):
+ self._mtx = mtx
+ self.invalidate()
+
+ def set(self, other):
+ self._mtx = other.get_matrix()
+ self.invalidate()
+
+ #@staticmethod
+ def identity():
+ return Affine1D(npy.identity(2))
+ identity = staticmethod(identity)
+
+ def clear(self):
+ self._mtx = npy.identity(2)
+ self.invalidate()
+ return self
+
+ def translate(self, t):
+ self._mtx[0, 1] += t
+ self.invalidate()
+ return self
+
+ def scale(self, s):
+ self._mtx[0, 0] *= s
+ self.invalidate()
+ return self
+
+ def is_separable(self):
+ mtx = self.get_matrix()
+ return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
+
+
+class IntervalTransform(Affine1DBase):
+ def __init__(self, bbox, direction):
+ Affine1DBase.__init__(self)
+ self._bbox = bbox
+ self._direction = direction
+ self.set_children(['_bbox'])
+ self._mtx = None
+
+ def __repr__(self):
+ return "IntervalTransform(%s)" % (getattr(self._bbox, self._direction))
+ __str__ = __repr__
+
+ def _do_invalidation(self):
+ print "IntervalTransform.invalidation", self._bbox
+ self._mtx = None
+ Affine1DBase._do_invalidation(self)
+
+ def get_matrix(self):
+ if self._mtx is None:
+ min, max = getattr(self._bbox, self._direction)
+ self._mtx = inv(npy.array([[max - min, min],
+ [0.0, 1.0]], npy.float_))
+ return self._mtx
+
+
+class Affine2DBase(AffineBase):
+ input_dims = 2
+ output_dims = 2
+
+ def __init__(self):
+ AffineBase.__init__(self)
+
+ def __array__(self, *args, **kwargs):
+ return self.get_matrix()
+
+ def to_values(self):
+ mtx = self.get_matrix()
return tuple(mtx[:2].swapaxes(0, 1).flatten())
#@staticmethod
@@ -416,9 +597,6 @@
return affine
matrix_from_values = staticmethod(matrix_from_values)
- def get_matrix(self):
- raise NotImplementedError()
-
def transform(self, points):
"""
Applies the transformation to an array of 2D points and
@@ -444,11 +622,6 @@
points = points + mtx[0:2, 2:]
return points.transpose()
- def transform_without_affine(self, points):
- # MGDTODO: Should we copy the points here? I'd like to avoid it,
- # if possible
- return points, self
-
def inverted(self):
if self._inverted is None:
mtx = self.get_matrix()
@@ -476,7 +649,6 @@
matrix = npy.asarray(matrix, npy.float_)
assert matrix.shape == (3, 3)
self._mtx = matrix
- self._inverted = None
def __repr__(self):
return "Affine2D(%s)" % repr(self._mtx)
@@ -545,12 +717,6 @@
self.invalidate()
return self
- def inverted(self):
- if self._inverted is None:
- mtx = self.get_matrix()
- self._inverted = Affine2D(inv(mtx))
- return self._inverted
-
def is_separable(self):
mtx = self.get_matrix()
return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
@@ -602,12 +768,10 @@
__str__ = __repr__
def transform(self, points):
- # MGDTODO: Optimize the case where one of these is
- # an affine
x = self._x
y = self._y
if x == y and x.input_dims == 2:
- return self._x(points)
+ return self._x.transform(points)
if x.input_dims == 2:
x_points = x.transform(points)[:, 0:1]
@@ -623,13 +787,69 @@
return ma.concatenate((x_points, y_points), 1)
+ def transform_without_affine(self, points):
+ x = self._x
+ y = self._y
+ if x == y and x.input_dims == 2:
+ return self._x.transform_without_affine(points)
+
+ if x.input_dims == 2:
+ x_points, x_affine = x.transform_without_affine(points)
+ x_points = x_points[:, 0:1]
+ else:
+ x_points, x_affine = x.transform_without_affine(points[:, 0])
+ x_points = x_points.reshape((len(x_points), 1))
+
+ if y.input_dims == 2:
+ y_points, y_affine = y.transform_without_affine(points)
+ y_points = y_points[:, 1:]
+ else:
+ y_points, y_affine = y.transform_without_affine(points[:, 1])
+ y_points = y_points.reshape((len(y_points), 1))
+
+ return ma.concatenate((x_points, y_points), 1), blended_transform_factory(x_affine, y_affine)
+
def inverted(self):
return BlendedGenericTransform(self._x.inverted(), self._y.inverted())
def is_separable(self):
return True
+
+
+class BlendedAffine1D(Affine2DBase, Transform):
+ def __init__(self, x_transform, y_transform):
+ assert isinstance(x_transform, Affine1DBase)
+ assert isinstance(y_transform, Affine1DBase)
+
+ Transform.__init__(self)
+ self._x = x_transform
+ self._y = y_transform
+ self.set_children(['_x', '_y'])
+
+ Affine2DBase.__init__(self)
+ self._mtx = None
+
+ def __repr__(self):
+ return "BlendedAffine1D(%s,%s)" % (self._x, self._y)
+ __str__ = __repr__
+
+ def _do_invalidation(self):
+ self._mtx = None
+ Affine2DBase._do_invalidation(self)
+
+ def is_separable(self):
+ return True
+
+ def get_matrix(self):
+ if self._mtx is None:
+ x_mtx = self._x.get_matrix()
+ y_mtx = self._y.get_matrix()
+ self._mtx = npy.array([[x_mtx[0, 0], 0.0, x_mtx[0, 1]],
+ [0.0, y_mtx[0, 0], y_mtx[0, 1]],
+ [0.0, 0.0, 1.0]])
+ return self._mtx
+
-
class BlendedAffine2D(Affine2DBase, Transform):
def __init__(self, x_transform, y_transform):
assert x_transform.is_affine()
@@ -650,9 +870,8 @@
__str__ = __repr__
def _do_invalidation(self):
- if self._mtx is not None:
- self._mtx = None
- Affine2DBase._do_invalidation(self)
+ self._mtx = None
+ Affine2DBase._do_invalidation(self)
def is_separable(self):
return True
@@ -672,8 +891,10 @@
def blended_transform_factory(x_transform, y_transform):
- if x_transform.is_affine() and y_transform.is_affine():
+ if isinstance(x_transform, Affine2DBase) and isinstance(y_transform, Affine2DBase):
return BlendedAffine2D(x_transform, y_transform)
+ elif isinstance(x_transform, Affine1DBase) and isinstance(y_transform, Affine1DBase):
+ return BlendedAffine1D(x_transform, y_transform)
return BlendedGenericTransform(x_transform, y_transform)
@@ -726,7 +947,7 @@
def _do_invalidation(self):
self._mtx = None
- return Affine2DBase._do_invalidation(self)
+ Affine2DBase._do_invalidation(self)
def get_matrix(self):
if self._mtx is None:
@@ -754,8 +975,8 @@
class TestLogTransform(Transform):
input_dims = 1
output_dims = 1
- def transform(self, xy):
- marray = ma.masked_where(xy <= 0.0, xy * 10.0)
+ def transform(self, a):
+ marray = ma.masked_where(a <= 0.0, a * 10.0)
return (npy.log10(marray) * 0.5) + 0.5
def inverted(self):
@@ -768,8 +989,8 @@
class TestInvertLogTransform(Transform):
input_dims = 1
output_dims = 1
- def transform(self, xy):
- return ma.power(10, (xy - 0.5) * 2.0) / 10.0
+ def transform(self, a):
+ return ma.power(10, (a - 0.5) * 2.0) / 10.0
def inverted(self):
return TestLogTransform()
@@ -782,18 +1003,31 @@
input_dims = 2
output_dims = 2
+ def __init__(self, limits):
+ assert limits.is_bbox()
+
+ Transform.__init__(self)
+ self._limits = limits
+ self.set_children(['_limits'])
+
def transform(self, xy):
debug = len(xy) > 4
- x = xy[:, 0:1]
- y = xy[:, 1:]
- x, y = ((y * npy.cos(x)) + 1.0) * 0.5, ((y * npy.sin(x)) + 1.0) * 0.5
- if debug:
- print npy.min(xy[:, 0:1]), npy.max(xy[:, 0:1]), npy.min(xy[:, 1:]), npy.max(xy[:, 1:])
- print x.min(), x.max(), y.min(), y.max()
- return ma.concatenate((x, y), 1)
+ limmin, limmax = self._limits.intervaly
+ mask = (xy[:, 1:] < limmin) | (xy[:, 1:] > limmax)
+ mask = ma.concatenate((mask, mask), 1)
+ masked_xy = npy.ma.masked_where(mask, xy)
+ x = masked_xy[:, 0:1]
+ y = masked_xy[:, 1:2]
+ if x.shape == () or y.shape == ():
+ return masked_xy
+ y = (y - limmin) / (limmax - limmin)
+ x, y = y * ma.cos(x), y * ma.sin(x)
+ result = ma.concatenate((x, y), 1)
+ result = result * 0.5 + 0.5
+ return result
def inverted(self):
- return TestInvertPolarTransform()
+ return TestInvertPolarTransform(self._limits)
def is_separable(self):
return False
@@ -803,16 +1037,26 @@
input_dims = 2
output_dims = 2
+ def __init__(self, limits):
+ assert limits.is_bbox()
+
+ Transform.__init__(self)
+ self._limits = limits
+ self.set_children(['_limits'])
+
def transform(self, xy):
+ limmin, limmax = self._limits.intervaly
+ xy = (xy - 0.5) * 2.0
x = xy[:, 0:1]
y = xy[:, 1:]
r = ma.sqrt(ma.power(x, 2) + ma.power(y, 2))
theta = ma.arccos(x / r)
theta = ma.where(y < 0, 2 * npy.pi - theta, theta)
- return ma.concatenate((theta / (npy.pi * 2), r), 1)
+ r = r * (limmax - limmin) + limmin
+ return ma.concatenate((theta, r), 1)
def inverted(self):
- return TestInvertPolarTransform()
+ return TestInvertPolarTransform(self._limits)
def is_separable(self):
return False
@@ -835,9 +1079,8 @@
__str__ = __repr__
def _do_invalidation(self):
- if self._mtx is not None:
- self._mtx = None
- Affine2DBase._do_invalidation(self)
+ self._mtx = None
+ Affine2DBase._do_invalidation(self)
def is_separable(self):
return True
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ds...@us...> - 2007-09-24 15:12:15
|
Revision: 3883
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3883&view=rev
Author: dsdale
Date: 2007-09-24 08:11:58 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
fix bug in improved support for multiple windows in backend_qt4
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2007-09-24 13:03:01 UTC (rev 3882)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2007-09-24 15:11:58 UTC (rev 3883)
@@ -46,7 +46,7 @@
qApp = QtGui.QApplication( [" "] )
QtCore.QObject.connect( qApp, QtCore.SIGNAL( "lastWindowClosed()" ),
qApp, QtCore.SLOT( "quit()" ) )
- else:
+ #remember that matplotlib created the qApp - will be used by show()
_create_qApp.qAppCreatedHere = True
_create_qApp.qAppCreatedHere = False
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ds...@us...> - 2007-09-24 13:03:06
|
Revision: 3882
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3882&view=rev
Author: dsdale
Date: 2007-09-24 06:03:01 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
modifed embedding_in_qt* examples so they can be run from ipython with
-q*thread
Modified Paths:
--------------
trunk/matplotlib/examples/embedding_in_qt.py
trunk/matplotlib/examples/embedding_in_qt4.py
Modified: trunk/matplotlib/examples/embedding_in_qt.py
===================================================================
--- trunk/matplotlib/examples/embedding_in_qt.py 2007-09-24 13:01:17 UTC (rev 3881)
+++ trunk/matplotlib/examples/embedding_in_qt.py 2007-09-24 13:03:01 UTC (rev 3882)
@@ -25,7 +25,7 @@
# Note: color-intensive applications may require a different color allocation
# strategy.
-QApplication.setColorSpec(QApplication.NormalColor)
+#QApplication.setColorSpec(QApplication.NormalColor)
app = QApplication(sys.argv)
class MyMplCanvas(FigureCanvas):
@@ -129,12 +129,8 @@
% {"prog": progname, "version": progversion})
-def main():
- aw = ApplicationWindow()
- aw.setCaption("%s" % progname)
- qApp.setMainWidget(aw)
- aw.show()
- sys.exit(qApp.exec_loop())
-
-
-if __name__ == "__main__": main()
+aw = ApplicationWindow()
+aw.setCaption("%s" % progname)
+qApp.setMainWidget(aw)
+aw.show()
+sys.exit(qApp.exec_loop())
Modified: trunk/matplotlib/examples/embedding_in_qt4.py
===================================================================
--- trunk/matplotlib/examples/embedding_in_qt4.py 2007-09-24 13:01:17 UTC (rev 3881)
+++ trunk/matplotlib/examples/embedding_in_qt4.py 2007-09-24 13:03:01 UTC (rev 3882)
@@ -122,17 +122,10 @@
% {"prog": progname, "version": progversion})
-def main():
- # Note: color-intensive applications may require a different color
- # allocation strategy.
- QtGui.QApplication.setColorSpec(QtGui.QApplication.NormalColor)
- qApp = QtGui.QApplication(sys.argv)
+qApp = QtGui.QApplication(sys.argv)
- aw = ApplicationWindow()
- aw.setWindowTitle("%s" % progname)
- aw.show()
-# sys.exit(qApp.exec_())
- qApp.exec_()
-
-
-if __name__ == "__main__": main()
+aw = ApplicationWindow()
+aw.setWindowTitle("%s" % progname)
+aw.show()
+sys.exit(qApp.exec_())
+#qApp.exec_()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ds...@us...> - 2007-09-24 13:01:19
|
Revision: 3881
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3881&view=rev
Author: dsdale
Date: 2007-09-24 06:01:17 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
fix backend_wxagg reference in new config module
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/config/mpltraits.py
Modified: trunk/matplotlib/lib/matplotlib/config/mpltraits.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/config/mpltraits.py 2007-09-24 13:00:12 UTC (rev 3880)
+++ trunk/matplotlib/lib/matplotlib/config/mpltraits.py 2007-09-24 13:01:17 UTC (rev 3881)
@@ -29,7 +29,7 @@
'gtkcairo': 'GTKCairo',
'qt4agg': 'Qt4Agg',
'qtagg': 'QtAgg',
- 'wxagg': 'WxAgg',
+ 'wxagg': 'WXAgg',
'agg': 'Agg',
'cairo': 'Cairo',
'ps': 'PS',
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ds...@us...> - 2007-09-24 13:00:13
|
Revision: 3880
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3880&view=rev
Author: dsdale
Date: 2007-09-24 06:00:12 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
backend_qt* bugfix for multiple plot windows and show()
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2007-09-24 12:56:38 UTC (rev 3879)
+++ trunk/matplotlib/CHANGELOG 2007-09-24 13:00:12 UTC (rev 3880)
@@ -1,3 +1,7 @@
+2007-09-24 Applied Eike Welk's patch reported on mpl-dev on 2007-09-22
+ Fixes a bug with multiple plot windows in the qt backend,
+ ported the changes to backend_qt4 as well - DSD
+
2007-09-21 Changed cbook.reversed to yield the same result as the
python reversed builtin - DSD
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ds...@us...> - 2007-09-24 12:56:53
|
Revision: 3879
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3879&view=rev
Author: dsdale
Date: 2007-09-24 05:56:38 -0700 (Mon, 24 Sep 2007)
Log Message:
-----------
fix backend_qt* bug with multiple plot windows and show()
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backends/backend_qt.py
trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_qt.py 2007-09-23 13:50:01 UTC (rev 3878)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_qt.py 2007-09-24 12:56:38 UTC (rev 3879)
@@ -46,11 +46,11 @@
qApp = qt.QApplication( [" "] )
qt.QObject.connect( qApp, qt.SIGNAL( "lastWindowClosed()" ),
qApp, qt.SLOT( "quit()" ) )
- else:
- # someone else aready created the qApp and
- # we let them handle the event-loop control.
- show._needmain = False
+ #remember that matplotlib created the qApp - will be used by show()
+ _create_qApp.qAppCreatedHere = True
+_create_qApp.qAppCreatedHere = False
+
def show():
"""
Show all the figures and enter the qt main loop
@@ -65,13 +65,10 @@
if figManager != None:
figManager.canvas.draw()
- if ( show._needmain ):
- qt.qApp.exec_loop()
- show._needmain = False
+ if _create_qApp.qAppCreatedHere:
+ qt.qApp.exec_loop()
-show._needmain = True
-
def new_figure_manager( num, *args, **kwargs ):
"""
Create a new figure manager instance
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2007-09-23 13:50:01 UTC (rev 3878)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py 2007-09-24 12:56:38 UTC (rev 3879)
@@ -47,10 +47,10 @@
QtCore.QObject.connect( qApp, QtCore.SIGNAL( "lastWindowClosed()" ),
qApp, QtCore.SLOT( "quit()" ) )
else:
- # someone else aready created the qApp and
- # we let them handle the event-loop control.
- show._needmain = False
+ _create_qApp.qAppCreatedHere = True
+_create_qApp.qAppCreatedHere = False
+
def show():
"""
Show all the figures and enter the qt main loop
@@ -65,13 +65,10 @@
if figManager != None:
figManager.canvas.draw()
- if ( show._needmain ):
- qApp.exec_()
- show._needmain = False
+ if _create_qApp.qAppCreatedHere:
+ QtGui.qApp.exec_()
-show._needmain = True
-
def new_figure_manager( num, *args, **kwargs ):
"""
Create a new figure manager instance
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2007-09-23 13:50:04
|
Revision: 3878
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3878&view=rev
Author: jswhit
Date: 2007-09-23 06:50:01 -0700 (Sun, 23 Sep 2007)
Log Message:
-----------
update
Modified Paths:
--------------
trunk/toolkits/basemap/Changelog
Modified: trunk/toolkits/basemap/Changelog
===================================================================
--- trunk/toolkits/basemap/Changelog 2007-09-23 12:34:34 UTC (rev 3877)
+++ trunk/toolkits/basemap/Changelog 2007-09-23 13:50:01 UTC (rev 3878)
@@ -1,4 +1,4 @@
-version 0.9.6 (svn revision 3875)
+version 0.9.6 (svn revision 3878)
* labelling of meridians and parallels now works with
very small map regions (less than 0.2 degrees square).
* Subregions of the globe may be specified with llcrnrlat,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2007-09-23 12:34:36
|
Revision: 3877
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3877&view=rev
Author: jswhit
Date: 2007-09-23 05:34:34 -0700 (Sun, 23 Sep 2007)
Log Message:
-----------
changed opendap server (old one no longer works)
Modified Paths:
--------------
trunk/toolkits/basemap/examples/pnganim.py
Modified: trunk/toolkits/basemap/examples/pnganim.py
===================================================================
--- trunk/toolkits/basemap/examples/pnganim.py 2007-09-22 17:27:53 UTC (rev 3876)
+++ trunk/toolkits/basemap/examples/pnganim.py 2007-09-23 12:34:34 UTC (rev 3877)
@@ -47,10 +47,10 @@
raise ValueError,'dates must be in same year'
# set OpenDAP server URL.
-URLbase="http://www.cdc.noaa.gov/cgi-bin/nph-nc/Datasets/ncep.reanalysis/surface/"
-URL=URLbase+'slp.'+YYYY+'.nc'
-URLu=URLbase+'uwnd.sig995.'+YYYY+'.nc'
-URLv=URLbase+'vwnd.sig995.'+YYYY+'.nc'
+URLbase="http://nomad3.ncep.noaa.gov:9090/dods/reanalyses/reanalysis-2/6hr/pgb/"
+URL=URLbase+'pres'
+URLu=URLbase+'wind'
+URLv=URLbase+'wind'
print URL
print URLu
print URLv
@@ -71,7 +71,8 @@
# put times in YYYYMMDDHH format.
dates=[]
for t in times:
- fdate = hrs_since_day1CE_todate(int(t))
+ t = t*24
+ fdate = hrs_since_day1CE_todate(int(t))
dates.append(fdate.strftime('%Y%m%d%H'))
if YYYYMMDDHH1 not in dates or YYYYMMDDHH2 not in dates:
raise ValueError, 'date1 or date2 not a valid date (must be in form YYYYMMDDHH, where HH is 00,06,12 or 18)'
@@ -82,13 +83,13 @@
if ntime1 >= ntime2:
raise ValueError,'date2 must be greater than date1'
# get sea level pressure and 10-m wind data.
-slpdata = data['slp']
-udata = datau['uwnd']
-vdata = datav['vwnd']
+slpdata = data['presmsl']
+udata = datau['ugrdprs']
+vdata = datau['vgrdprs']
# mult slp by 0.01 to put in units of millibars.
-slpin = 0.01*(slpdata.scale_factor*p.squeeze(slpdata[ntime1:ntime2+1,:,:]) + slpdata.add_offset)
-uin = udata.scale_factor*p.squeeze(udata[ntime1:ntime2+1,:,:]) + udata.add_offset
-vin = vdata.scale_factor*p.squeeze(vdata[ntime1:ntime2+1,:,:]) + vdata.add_offset
+slpin = 0.01*p.squeeze(slpdata[ntime1:ntime2+1,:,:])
+uin = p.squeeze(udata[ntime1:ntime2+1,0,:,:])
+vin = p.squeeze(vdata[ntime1:ntime2+1,0,:,:])
datelabels = dates[ntime1:ntime2+1]
# add cyclic points
slp = p.zeros((slpin.shape[0],slpin.shape[1],slpin.shape[2]+1),p.Float64)
@@ -109,6 +110,12 @@
# make orthographic basemap.
m = Basemap(resolution='c',projection='ortho',lat_0=60.,lon_0=-60.)
p.ion() # interactive mode on.
+uin = p.squeeze(udata[ntime1:ntime2+1,0,:,:])
+vin = p.squeeze(vdata[ntime1:ntime2+1,0,:,:])
+datelabels = dates[ntime1:ntime2+1]
+# make orthographic basemap.
+m = Basemap(resolution='c',projection='ortho',lat_0=60.,lon_0=-60.)
+p.ion() # interactive mode on.
# create figure, add axes (leaving room for colorbar on right)
fig = p.figure()
ax = fig.add_axes([0.1,0.1,0.7,0.7])
@@ -135,12 +142,10 @@
# plot wind vectors on projection grid (looks better).
# first, shift grid so it goes from -180 to 180 (instead of 0 to 360
# in longitude). Otherwise, interpolation is messed up.
- # also reverse latitudes (since interpolation expects monotonically
- # increasing x and y).
- ugrid,newlons = shiftgrid(180.,u[nt,::-1,:],longitudes,start=False)
- vgrid,newlons = shiftgrid(180.,v[nt,::-1,:],longitudes,start=False)
+ ugrid,newlons = shiftgrid(180.,u[nt,:,:],longitudes,start=False)
+ vgrid,newlons = shiftgrid(180.,v[nt,:,:],longitudes,start=False)
# transform vectors to projection grid.
- urot,vrot,xx,yy = m.transform_vector(ugrid,vgrid,newlons,latitudes[::-1],51,51,returnxy=True,masked=True)
+ urot,vrot,xx,yy = m.transform_vector(ugrid,vgrid,newlons,latitudes,51,51,returnxy=True,masked=True)
# plot wind vectors over map.
Q = m.quiver(xx,yy,urot,vrot,scale=500)
# make quiver key.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2007-09-22 17:27:55
|
Revision: 3876
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3876&view=rev
Author: jswhit
Date: 2007-09-22 10:27:53 -0700 (Sat, 22 Sep 2007)
Log Message:
-----------
updated URL
Modified Paths:
--------------
trunk/toolkits/basemap/examples/fcstmaps.py
Modified: trunk/toolkits/basemap/examples/fcstmaps.py
===================================================================
--- trunk/toolkits/basemap/examples/fcstmaps.py 2007-09-22 15:10:00 UTC (rev 3875)
+++ trunk/toolkits/basemap/examples/fcstmaps.py 2007-09-22 17:27:53 UTC (rev 3876)
@@ -50,7 +50,7 @@
# set OpenDAP server URL.
HH='09'
URLbase="http://nomad3.ncep.noaa.gov:9090/dods/sref/sref"
-URL=URLbase+YYYYMMDD+"/sref_eta1_"+HH+"z.ctl"
+URL=URLbase+YYYYMMDD+"/sref_eta_ctl1_"+HH+"z"
print URL+'\n'
try:
data = client.open(URL)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2007-09-22 15:10:04
|
Revision: 3875
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3875&view=rev
Author: jswhit
Date: 2007-09-22 08:10:00 -0700 (Sat, 22 Sep 2007)
Log Message:
-----------
version 0.9.6 is finished
Modified Paths:
--------------
trunk/toolkits/basemap/Changelog
Modified: trunk/toolkits/basemap/Changelog
===================================================================
--- trunk/toolkits/basemap/Changelog 2007-09-22 06:48:49 UTC (rev 3874)
+++ trunk/toolkits/basemap/Changelog 2007-09-22 15:10:00 UTC (rev 3875)
@@ -1,4 +1,4 @@
-version 0.9.6 (not yet released)
+version 0.9.6 (svn revision 3875)
* labelling of meridians and parallels now works with
very small map regions (less than 0.2 degrees square).
* Subregions of the globe may be specified with llcrnrlat,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jo...@us...> - 2007-09-22 06:48:51
|
Revision: 3874
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3874&view=rev
Author: jouni
Date: 2007-09-21 23:48:49 -0700 (Fri, 21 Sep 2007)
Log Message:
-----------
Replace some generator expressions by list comprehensions for
Python 2.3 compatibility
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
trunk/matplotlib/lib/matplotlib/dviread.py
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-21 16:54:32 UTC (rev 3873)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-22 06:48:49 UTC (rev 3874)
@@ -541,10 +541,10 @@
widths[ch] = afmdata.get_width_char(ch, isord=True)
except KeyError:
pass
- not_None = (ch for ch in range(256)
- if widths[ch] is not None)
- firstchar = not_None.next()
- lastchar = max(not_None)
+ not_None = [ch for ch in range(256)
+ if widths[ch] is not None]
+ firstchar = not_None[0]
+ lastchar = not_None[-1]
widths = widths[firstchar:lastchar+1]
for i,w in enumerate(widths):
if w is None: widths[i] = 0
Modified: trunk/matplotlib/lib/matplotlib/dviread.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-21 16:54:32 UTC (rev 3873)
+++ trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-22 06:48:49 UTC (rev 3874)
@@ -350,9 +350,9 @@
def _xxx(self, special):
matplotlib.verbose.report(
'Dvi._xxx: encountered special: %s'
- % ''.join((32 <= ord(ch) < 127) and ch
- or '<%02x>' % ord(ch)
- for ch in special),
+ % ''.join([(32 <= ord(ch) < 127) and ch
+ or '<%02x>' % ord(ch)
+ for ch in special]),
'debug')
def _fnt_def(self, k, c, s, d, a, l, n):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-21 16:54:35
|
Revision: 3873
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3873&view=rev
Author: mdboom
Date: 2007-09-21 09:54:32 -0700 (Fri, 21 Sep 2007)
Log Message:
-----------
Merged revisions 3870-3872 via svnmerge from
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
r3871 | dsdale | 2007-09-21 11:33:18 -0400 (Fri, 21 Sep 2007) | 2 lines
changed cbooks reversed to agree with the python builtin
........
Modified Paths:
--------------
branches/transforms/API_CHANGES
branches/transforms/CHANGELOG
branches/transforms/lib/matplotlib/cbook.py
Property Changed:
----------------
branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
- /trunk/matplotlib:1-3869
+ /trunk/matplotlib:1-3872
Modified: branches/transforms/API_CHANGES
===================================================================
--- branches/transforms/API_CHANGES 2007-09-21 16:52:50 UTC (rev 3872)
+++ branches/transforms/API_CHANGES 2007-09-21 16:54:32 UTC (rev 3873)
@@ -1,3 +1,8 @@
+ Changed cbook.reversed so it yields a tuple rather than a
+ (index, tuple). This agrees with the python reversed builtin,
+ and cbook only defines reversed if python doesnt provide the
+ builtin.
+
Made skiprows=1 the default on csv2rec
The gd and paint backends have been deleted.
Modified: branches/transforms/CHANGELOG
===================================================================
--- branches/transforms/CHANGELOG 2007-09-21 16:52:50 UTC (rev 3872)
+++ branches/transforms/CHANGELOG 2007-09-21 16:54:32 UTC (rev 3873)
@@ -1,3 +1,6 @@
+2007-09-21 Changed cbook.reversed to yield the same result as the
+ python reversed builtin - DSD
+
2007-09-13 The usetex support in the pdf backend is more usable now,
so I am enabling it. - JKS
Modified: branches/transforms/lib/matplotlib/cbook.py
===================================================================
--- branches/transforms/lib/matplotlib/cbook.py 2007-09-21 16:52:50 UTC (rev 3872)
+++ branches/transforms/lib/matplotlib/cbook.py 2007-09-21 16:54:32 UTC (rev 3873)
@@ -482,7 +482,7 @@
enumerate() is new in Python 2.3
"""
for i in range(len(seq)-1,-1,-1):
- yield i, seq[i]
+ yield seq[i]
# use itertools.izip if available, else use python version
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-21 16:52:54
|
Revision: 3872
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3872&view=rev
Author: mdboom
Date: 2007-09-21 09:52:50 -0700 (Fri, 21 Sep 2007)
Log Message:
-----------
Further progress on arbitrary transformations -- zooming and panning
now works without any log-scale-specific hacks. (Though the
underlying model is slightly wrong.)
Added graphviz output support for debugging transformation trees.
Masked array handling much more robust.
Modified Paths:
--------------
branches/transforms/lib/matplotlib/axes.py
branches/transforms/lib/matplotlib/backend_bases.py
branches/transforms/lib/matplotlib/lines.py
branches/transforms/lib/matplotlib/path.py
branches/transforms/lib/matplotlib/transforms.py
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py 2007-09-21 15:33:18 UTC (rev 3871)
+++ branches/transforms/lib/matplotlib/axes.py 2007-09-21 16:52:50 UTC (rev 3872)
@@ -637,10 +637,14 @@
# self.viewLim, self.bbox)
self.preDataTransform = mtransforms.BboxTransform(
self.viewLim, mtransforms.Bbox.unit())
- self.dataTransform = mtransforms.TestLogTransform()
- # self.dataTransform = mtransforms.Affine2D().scale(1.5)
+# self.dataTransform = mtransforms.TestPolarTransform()
+# self.dataTransform = mtransforms.blended_transform_factory(
+# mtransforms.TestLogTransform(),
+# mtransforms.Affine2D())
+ self.dataTransform = mtransforms.Affine2D()
self.transData = self.preDataTransform + self.dataTransform + mtransforms.BboxTransform(
mtransforms.Bbox.unit(), self.bbox)
+ self.transData.make_graphviz(open("trans.dot", "w"))
def get_position(self, original=False):
@@ -1523,7 +1527,7 @@
'return the xaxis scale string: log or linear'
# MGDTODO
# return self.scaled[self.transData.get_funcx().get_type()]
- return 'linear'
+ return 'log'
def set_xscale(self, value, basex = 10, subsx=None):
"""
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py 2007-09-21 15:33:18 UTC (rev 3871)
+++ branches/transforms/lib/matplotlib/backend_bases.py 2007-09-21 16:52:50 UTC (rev 3872)
@@ -1655,60 +1655,30 @@
#multiple button can get pressed during motion...
if self._button_pressed==1:
inverse = trans.inverted()
- lastx, lasty = inverse.transform_point((lastx, lasty))
- x, y = inverse.transform_point( (event.x, event.y) )
- if a.get_xscale()=='log':
- dx=1-lastx/x
- else:
- dx=x-lastx
- if a.get_yscale()=='log':
- dy=1-lasty/y
- else:
- dy=y-lasty
-
- dx,dy=format_deltas(event,dx,dy)
-
- if a.get_xscale()=='log':
- xmin *= 1-dx
- xmax *= 1-dx
- else:
- xmin -= dx
- xmax -= dx
- if a.get_yscale()=='log':
- ymin *= 1-dy
- ymax *= 1-dy
- else:
- ymin -= dy
- ymax -= dy
+ dx, dy = event.x - lastx, event.y - lasty
+ dx, dy = format_deltas(event, dx, dy)
+ delta = npy.array([[dx, dy], [dx, dy]], npy.float_)
+ bbox = transforms.Bbox(a.bbox.get_points() - delta)
+ result = bbox.transformed(inverse)
elif self._button_pressed==3:
try:
+ inverse = trans.inverted()
dx=(lastx-event.x)/float(a.bbox.width)
dy=(lasty-event.y)/float(a.bbox.height)
- dx,dy=format_deltas(event,dx,dy)
- if a.get_aspect() != 'auto':
- dx = 0.5*(dx + dy)
- dy = dx
- alphax = pow(10.0,dx)
- alphay = pow(10.0,dy)#use logscaling, avoid singularities and smother scaling...
- inverse = trans.inverted()
- lastx, lasty = inverse.transform_point( (lastx, lasty) )
- if a.get_xscale()=='log':
- xmin = lastx*(xmin/lastx)**alphax
- xmax = lastx*(xmax/lastx)**alphax
- else:
- xmin = lastx+alphax*(xmin-lastx)
- xmax = lastx+alphax*(xmax-lastx)
- if a.get_yscale()=='log':
- ymin = lasty*(ymin/lasty)**alphay
- ymax = lasty*(ymax/lasty)**alphay
- else:
- ymin = lasty+alphay*(ymin-lasty)
- ymax = lasty+alphay*(ymax-lasty)
+ alphax = pow(10.0, dx)
+ alphay = pow(10.0, dy)
+ # MGDTODO: Make better use of numpy
+ lastx, lasty = inverse.transform_point((lastx, lasty))
+ xmin = (lastx + alphax * (xmin - lastx))
+ xmax = (lastx + alphax * (xmax - lastx))
+ ymin = (lasty + alphay * (ymin - lasty))
+ ymax = (lasty + alphay * (ymax - lasty))
+ result = transforms.Bbox.from_lbrt(xmin, ymin, xmax, ymax)
except OverflowError:
warnings.warn('Overflow while panning')
return
- a.set_xlim(xmin, xmax)
- a.set_ylim(ymin, ymax)
+ a.set_xlim(*result.intervalx)
+ a.set_ylim(*result.intervaly)
self.dynamic_update()
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py 2007-09-21 15:33:18 UTC (rev 3871)
+++ branches/transforms/lib/matplotlib/lines.py 2007-09-21 16:52:50 UTC (rev 3872)
@@ -25,6 +25,53 @@
(TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN,
CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN) = range(8)
+def unmasked_index_ranges(mask, compressed = True):
+ '''
+ Calculate the good data ranges in a masked 1-D npy.array, based on mask.
+
+ Returns Nx2 npy.array with each row the start and stop indices
+ for slices of the compressed npy.array corresponding to each of N
+ uninterrupted runs of unmasked values.
+ If optional argument compressed is False, it returns the
+ start and stop indices into the original npy.array, not the
+ compressed npy.array.
+ Returns None if there are no unmasked values.
+
+ Example:
+
+ y = ma.array(npy.arange(5), mask = [0,0,1,0,0])
+ #ii = unmasked_index_ranges(y.mask())
+ ii = unmasked_index_ranges(ma.getmask(y))
+ # returns [[0,2,] [2,4,]]
+
+ y.compressed().filled()[ii[1,0]:ii[1,1]]
+ # returns npy.array [3,4,]
+ # (The 'filled()' method converts the masked npy.array to a numerix npy.array.)
+
+ #i0, i1 = unmasked_index_ranges(y.mask(), compressed=False)
+ i0, i1 = unmasked_index_ranges(ma.getmask(y), compressed=False)
+ # returns [[0,3,] [2,5,]]
+
+ y.filled()[ii[1,0]:ii[1,1]]
+ # returns npy.array [3,4,]
+
+ '''
+ m = npy.concatenate(((1,), mask, (1,)))
+ indices = npy.arange(len(mask) + 1)
+ mdif = m[1:] - m[:-1]
+ i0 = npy.compress(mdif == -1, indices)
+ i1 = npy.compress(mdif == 1, indices)
+ assert len(i0) == len(i1)
+ if len(i1) == 0:
+ return None
+ if not compressed:
+ return npy.concatenate((i0[:, npy.newaxis], i1[:, npy.newaxis]), axis=1)
+ seglengths = i1 - i0
+ breakpoints = npy.cumsum(seglengths)
+ ic0 = npy.concatenate(((0,), breakpoints[:-1]))
+ ic1 = breakpoints
+ return npy.concatenate((ic0[:, npy.newaxis], ic1[:, npy.newaxis]), axis=1)
+
def segment_hits(cx,cy,x,y,radius):
"""Determine if any line segments are within radius of a point. Returns
the list of line segments that are within that radius.
@@ -302,7 +349,7 @@
self._picker = p
def get_window_extent(self, renderer):
- xy = self.get_transform()(self._xy)
+ xy = self.get_transform().transform(self._xy)
x = xy[:, 0]
y = xy[:, 1]
@@ -343,9 +390,6 @@
self._yorig = y
self.recache()
- # MGDTODO: Masked data arrays are broken
- _masked_array_to_path_code_mapping = npy.array(
- [Path.LINETO, Path.MOVETO, Path.MOVETO], Path.code_type)
def recache(self):
#if self.axes is None: print 'recache no axes'
#else: print 'recache units', self.axes.xaxis.units, self.axes.yaxis.units
@@ -363,24 +407,15 @@
if len(x) != len(y):
raise RuntimeError('xdata and ydata must be the same length')
- self._xy = npy.vstack((npy.asarray(x, npy.float_),
- npy.asarray(y, npy.float_))).transpose()
+ x = x.reshape((len(x), 1))
+ y = y.reshape((len(y), 1))
+
+ self._xy = ma.concatenate((x, y), 1)
self._x = self._xy[:, 0] # just a view
self._y = self._xy[:, 1] # just a view
self._logcache = None
-
- mx = ma.getmask(x)
- my = ma.getmask(y)
- mask = ma.mask_or(mx, my)
- codes = None
- if mask is not ma.nomask:
- m = npy.concatenate(((1,), mask, (1,)))
- mdif = m[1:] - m[:-1]
- mdif = npy.maximum((mdif[:-1] * -2), mask)
- codes = npy.take(
- self._masked_array_to_path_code_mapping,
- mdif)
- self._path = Path(self._xy, codes, closed=False)
+ # Masked arrays are now handled by the Path class itself
+ self._path = Path(self._xy, closed=False)
# MGDTODO: If _draw_steps is removed, remove the following line also
self._step_path = None
Modified: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py 2007-09-21 15:33:18 UTC (rev 3871)
+++ branches/transforms/lib/matplotlib/path.py 2007-09-21 16:52:50 UTC (rev 3872)
@@ -1,4 +1,5 @@
import numpy as npy
+from numpy import ma as ma
class Path(object):
# Path codes
@@ -21,10 +22,8 @@
code_type = npy.uint8
def __init__(self, vertices, codes=None, closed=True):
- vertices = npy.asarray(vertices, npy.float_)
- assert vertices.ndim == 2
- assert vertices.shape[1] == 2
-
+ vertices = ma.asarray(vertices, npy.float_)
+
if codes is None:
if closed:
codes = self.LINETO * npy.ones(
@@ -41,10 +40,27 @@
assert codes.ndim == 1
assert len(codes) == len(vertices)
+ # The path being passed in may have masked values. However,
+ # the backends are not expected to deal with masked arrays, so
+ # we must remove them from the array (using compressed), and
+ # add MOVETO commands to the codes array accordingly.
+ mask = ma.getmask(vertices)
+ if mask is not ma.nomask:
+ mask1d = ma.mask_or(mask[:, 0], mask[:, 1])
+ vertices = ma.compress(npy.invert(mask1d), vertices, 0)
+ codes = npy.where(npy.concatenate((mask1d[-1:], mask1d[:-1])),
+ self.MOVETO, codes)
+ codes = ma.masked_array(codes, mask=mask1d).compressed()
+ codes = npy.asarray(codes, self.code_type)
+
+ vertices = npy.asarray(vertices, npy.float_)
+
+ assert vertices.ndim == 2
+ assert vertices.shape[1] == 2
+ assert codes.ndim == 1
+
self._codes = codes
self._vertices = vertices
-
- assert self._codes.ndim == 1
def __repr__(self):
return "Path(%s, %s)" % (self.vertices, self.codes)
@@ -91,10 +107,11 @@
def unit_regular_polygon(cls, numVertices):
path = cls._unit_regular_polygons.get(numVertices)
if path is None:
- theta = 2*npy.pi/numVertices * npy.arange(numVertices)
- # This is to make sure the polygon always "points-up"
+ theta = 2*npy.pi/numVertices * npy.arange(numVertices).reshape((numVertices, 1))
+ # This initial rotation is to make sure the polygon always
+ # "points-up"
theta += npy.pi / 2.0
- verts = npy.vstack((npy.cos(theta), npy.sin(theta))).transpose()
+ verts = npy.concatenate((npy.cos(theta), npy.sin(theta)))
path = Path(verts)
cls._unit_regular_polygons[numVertices] = path
return path
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py 2007-09-21 15:33:18 UTC (rev 3871)
+++ branches/transforms/lib/matplotlib/transforms.py 2007-09-21 16:52:50 UTC (rev 3872)
@@ -5,6 +5,7 @@
"""
import numpy as npy
+from numpy import ma as ma
from numpy.linalg import inv
from sets import Set
@@ -19,6 +20,7 @@
class TransformNode(object):
def __init__(self):
self._parents = Set()
+ self._children = []
def invalidate(self):
self._do_invalidation()
@@ -33,7 +35,34 @@
getattr(self, child)._parents.add(self)
self._children = children
+ def make_graphviz(self, fobj):
+ def recurse(root):
+ fobj.write('%s [label="%s"];\n' %
+ (hash(root), root.__class__.__name__))
+ if isinstance(root, Affine2DBase):
+ fobj.write('%s [style=filled, color=".7 .7 .9"];\n' %
+ hash(root))
+ elif isinstance(root, BboxBase):
+ fobj.write('%s [style=filled, color=".9 .9 .7"];\n' %
+ hash(root))
+ for child_name in root._children:
+ child = getattr(root, child_name)
+ fobj.write("%s -> %s;\n" % (
+ hash(root),
+ hash(child)))
+ recurse(child)
+ fobj.write("digraph G {\n")
+ recurse(self)
+ fobj.write("}\n")
+
+ def is_affine(self):
+ return isinstance(self, Affine2DBase)
+
+ def is_bbox(self):
+ return isinstance(self, BboxBase)
+
+
class BboxBase(TransformNode):
'''
This is the read-only part of a bounding-box
@@ -169,12 +198,6 @@
return Bbox(points)
from_lbrt = staticmethod(from_lbrt)
- def __copy__(self):
- return Bbox(self._points.copy())
-
- def __deepcopy__(self, memo):
- return Bbox(self._points.copy())
-
def __cmp__(self, other):
# MGDTODO: Totally suboptimal
if isinstance(other, Bbox) and (self._points == other._points).all():
@@ -274,6 +297,8 @@
"""
Return the Bbox that bounds all bboxes
"""
+ # MGDTODO: There's got to be a way to utilize numpy here
+ # to make this faster...
assert(len(bboxes))
if len(bboxes) == 1:
@@ -297,7 +322,7 @@
class TransformedBbox(BboxBase):
def __init__(self, bbox, transform):
- assert isinstance(bbox, Bbox)
+ assert bbox.is_bbox()
assert isinstance(transform, Transform)
BboxBase.__init__(self)
@@ -353,9 +378,6 @@
def is_separable(self):
return False
- def is_affine(self):
- return False
-
class Affine2DBase(Transform):
input_dims = 2
@@ -416,9 +438,9 @@
# print "".join(traceback.format_stack())
# print points
mtx = self.get_matrix()
- points = npy.asarray(points, npy.float_)
+ points = ma.asarray(points, npy.float_)
points = points.transpose()
- points = npy.dot(mtx[0:2, 0:2], points)
+ points = ma.dot(mtx[0:2, 0:2], points)
points = points + mtx[0:2, 2:]
return points.transpose()
@@ -437,9 +459,6 @@
mtx = self.get_matrix()
return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
- def is_affine(self):
- return True
-
class Affine2D(Affine2DBase):
def __init__(self, matrix = None):
@@ -469,12 +488,6 @@
return 0
return -1
- def __copy__(self):
- return Affine2D(self._mtx.copy())
-
- def __deepcopy__(self, memo):
- return Affine2D(self._mtx.copy())
-
#@staticmethod
def from_values(a, b, c, d, e, f):
return Affine2D(Affine2D.matrix_from_values(a, b, c, d, e, f))
@@ -542,9 +555,31 @@
mtx = self.get_matrix()
return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
- def is_affine(self):
- return True
+class IdentityTransform(Affine2DBase):
+ """
+ A special class that does the identity transform quickly.
+ """
+ _mtx = npy.identity(3)
+
+ def __cmp__(self, other):
+ if (isinstance(other, Affine2D) and
+ (other == IDENTITY)):
+ return 0
+ return -1
+
+ def get_matrix(self):
+ return _mtx
+
+ def transform(self, points):
+ return points
+
+ def transform_without_affine(self, points):
+ return points, self
+
+ def inverted(self):
+ return self
+
IDENTITY = Affine2D()
class BlendedGenericTransform(Transform):
@@ -553,10 +588,9 @@
def __init__(self, x_transform, y_transform):
# Here we ask: "Does it blend?"
- assert x_transform.is_separable()
- assert y_transform.is_separable()
- assert x_transform.input_dims == x_transform.output_dims == 2
- assert y_transform.input_dims == y_transform.output_dims == 2
+ # MGDTODO: Turn these checks back on
+ # assert x_transform.is_separable()
+ # assert y_transform.is_separable()
Transform.__init__(self)
self._x = x_transform
@@ -576,16 +610,18 @@
return self._x(points)
if x.input_dims == 2:
- x_points = x.transform(points)[:, 0]
+ x_points = x.transform(points)[:, 0:1]
else:
x_points = x.transform(points[:, 0])
-
+ x_points = x_points.reshape((len(x_points), 1))
+
if y.input_dims == 2:
- y_points = y.transform(points)[:, 1]
+ y_points = y.transform(points)[:, 1:]
else:
y_points = y.transform(points[:, 1])
+ y_points = y_points.reshape((len(y_points), 1))
- return npy.vstack((x_points, y_points)).transpose()
+ return ma.concatenate((x_points, y_points), 1)
def inverted(self):
return BlendedGenericTransform(self._x.inverted(), self._y.inverted())
@@ -598,6 +634,9 @@
def __init__(self, x_transform, y_transform):
assert x_transform.is_affine()
assert y_transform.is_affine()
+ # MGDTODO: Turn these checks back on
+ # assert x_transform.is_separable()
+ # assert y_transform.is_separable()
Transform.__init__(self)
self._x = x_transform
self._y = y_transform
@@ -649,6 +688,8 @@
self._b = b
self.set_children(['_a', '_b'])
+ self.take_shortcut = b.is_affine()
+
def __repr__(self):
return "CompositeGenericTransform(%s, %s)" % (self._a, self._b)
__str__ = __repr__
@@ -656,11 +697,15 @@
def transform(self, points):
return self._b.transform(self._a.transform(points))
+ def transform_without_affine(self, points):
+ if self.take_shortcut:
+ return self._a.transform(points), self._b
+ return self.transform(points), IDENTITY
+
def inverted(self):
return CompositeGenericTransform(self._b.inverted(), self._a.inverted())
def is_separable(self):
- return True
return self._a.is_separable() and self._b.is_separable()
@@ -702,35 +747,81 @@
output_dims = 1
def transform(self, a):
- m = npy.ma.masked_where(a < 0, a)
+ m = ma.masked_where(a < 0, a)
return npy.log10(m)
class TestLogTransform(Transform):
- input_dims = 2
- output_dims = 2
+ input_dims = 1
+ output_dims = 1
def transform(self, xy):
- marray = npy.ma.masked_where(xy <= 0.0, xy * 10.0)
- return npy.log10(marray)
+ marray = ma.masked_where(xy <= 0.0, xy * 10.0)
+ return (npy.log10(marray) * 0.5) + 0.5
def inverted(self):
return TestInvertLogTransform()
+ def is_separable(self):
+ return True
+
class TestInvertLogTransform(Transform):
- input_dims = 2
- output_dims = 2
+ input_dims = 1
+ output_dims = 1
def transform(self, xy):
- return npy.power(10, xy) / 10.0
+ return ma.power(10, (xy - 0.5) * 2.0) / 10.0
def inverted(self):
return TestLogTransform()
+ def is_separable(self):
+ return True
+
+
+class TestPolarTransform(Transform):
+ input_dims = 2
+ output_dims = 2
+
+ def transform(self, xy):
+ debug = len(xy) > 4
+ x = xy[:, 0:1]
+ y = xy[:, 1:]
+ x, y = ((y * npy.cos(x)) + 1.0) * 0.5, ((y * npy.sin(x)) + 1.0) * 0.5
+ if debug:
+ print npy.min(xy[:, 0:1]), npy.max(xy[:, 0:1]), npy.min(xy[:, 1:]), npy.max(xy[:, 1:])
+ print x.min(), x.max(), y.min(), y.max()
+ return ma.concatenate((x, y), 1)
+
+ def inverted(self):
+ return TestInvertPolarTransform()
+ def is_separable(self):
+ return False
+
+
+class TestInvertPolarTransform(Transform):
+ input_dims = 2
+ output_dims = 2
+
+ def transform(self, xy):
+ x = xy[:, 0:1]
+ y = xy[:, 1:]
+ r = ma.sqrt(ma.power(x, 2) + ma.power(y, 2))
+ theta = ma.arccos(x / r)
+ theta = ma.where(y < 0, 2 * npy.pi - theta, theta)
+ return ma.concatenate((theta / (npy.pi * 2), r), 1)
+
+ def inverted(self):
+ return TestInvertPolarTransform()
+
+ def is_separable(self):
+ return False
+
+
class BboxTransform(Affine2DBase):
def __init__(self, boxin, boxout):
- assert isinstance(boxin, BboxBase)
- assert isinstance(boxout, BboxBase)
+ assert boxin.is_bbox()
+ assert boxout.is_bbox()
Affine2DBase.__init__(self)
self._boxin = boxin
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ds...@us...> - 2007-09-21 15:33:21
|
Revision: 3871
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3871&view=rev
Author: dsdale
Date: 2007-09-21 08:33:18 -0700 (Fri, 21 Sep 2007)
Log Message:
-----------
changed cbooks reversed to agree with the python builtin
Modified Paths:
--------------
trunk/matplotlib/API_CHANGES
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/cbook.py
Modified: trunk/matplotlib/API_CHANGES
===================================================================
--- trunk/matplotlib/API_CHANGES 2007-09-20 18:02:51 UTC (rev 3870)
+++ trunk/matplotlib/API_CHANGES 2007-09-21 15:33:18 UTC (rev 3871)
@@ -1,3 +1,8 @@
+ Changed cbook.reversed so it yields a tuple rather than a
+ (index, tuple). This agrees with the python reversed builtin,
+ and cbook only defines reversed if python doesnt provide the
+ builtin.
+
Made skiprows=1 the default on csv2rec
The gd and paint backends have been deleted.
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2007-09-20 18:02:51 UTC (rev 3870)
+++ trunk/matplotlib/CHANGELOG 2007-09-21 15:33:18 UTC (rev 3871)
@@ -1,3 +1,6 @@
+2007-09-21 Changed cbook.reversed to yield the same result as the
+ python reversed builtin - DSD
+
2007-09-13 The usetex support in the pdf backend is more usable now,
so I am enabling it. - JKS
Modified: trunk/matplotlib/lib/matplotlib/cbook.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/cbook.py 2007-09-20 18:02:51 UTC (rev 3870)
+++ trunk/matplotlib/lib/matplotlib/cbook.py 2007-09-21 15:33:18 UTC (rev 3871)
@@ -482,7 +482,7 @@
enumerate() is new in Python 2.3
"""
for i in range(len(seq)-1,-1,-1):
- yield i, seq[i]
+ yield seq[i]
# use itertools.izip if available, else use python version
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-20 18:03:02
|
Revision: 3870
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3870&view=rev
Author: mdboom
Date: 2007-09-20 11:02:51 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
Merged revisions 3866-3869 via svnmerge from
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
r3867 | jdh2358 | 2007-09-20 10:13:51 -0400 (Thu, 20 Sep 2007) | 1 line
committed rectangle selector lock patch
........
Modified Paths:
--------------
branches/transforms/lib/matplotlib/mlab.py
branches/transforms/lib/matplotlib/widgets.py
Property Changed:
----------------
branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
- /trunk/matplotlib:1-3865
+ /trunk/matplotlib:1-3869
Modified: branches/transforms/lib/matplotlib/mlab.py
===================================================================
--- branches/transforms/lib/matplotlib/mlab.py 2007-09-20 18:00:32 UTC (rev 3869)
+++ branches/transforms/lib/matplotlib/mlab.py 2007-09-20 18:02:51 UTC (rev 3870)
@@ -1255,7 +1255,7 @@
if unpack: return X.transpose()
else: return X
-def csv2rec(fname, comments='#', skiprows=1, checkrows=5, delimiter=',',
+def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',',
converterd=None, names=None, missing=None):
"""
Load data from comma/space/tab delimited file in fname into a
@@ -1314,6 +1314,14 @@
else: return get_func(item, funcmap[func]) # recurse
else: return func
+
+ # map column names that clash with builtins -- TODO - extend this list
+ itemd = {
+ 'return' : 'return_',
+ 'file' : 'file_',
+ 'print' : 'print_',
+ }
+
def get_converters(reader):
converters = None
@@ -1352,6 +1360,7 @@
if not len(item):
item = 'column%d'%i
+ item = itemd.get(item, item)
cnt = seen.get(item, 0)
if cnt>0:
names.append(item + '%d'%cnt)
Modified: branches/transforms/lib/matplotlib/widgets.py
===================================================================
--- branches/transforms/lib/matplotlib/widgets.py 2007-09-20 18:00:32 UTC (rev 3869)
+++ branches/transforms/lib/matplotlib/widgets.py 2007-09-20 18:02:51 UTC (rev 3870)
@@ -955,24 +955,40 @@
warnings.warn('Use SpanSelector instead!', DeprecationWarning)
SpanSelector.__init__(self, ax, onselect, 'horizontal', **kwargs)
+
class RectangleSelector:
"""
Select a min/max range of the x axes for a matplotlib Axes
Example usage:
- ax = subplot(111)
- ax.plot(x,y)
+ from matplotlib.widgets import RectangleSelector
+ from pylab import *
- def onselect(eclick, erelease):
+ def onselect(eclick, erelease):
'eclick and erelease are matplotlib events at press and release'
- print 'startposition : (%f,%f)'%(eclick.xdata, eclick.ydata)
- print 'endposition : (%f,%f)'%(erelease.xdata, erelease.ydata)
- print 'used button : ', eclick.button
+ print ' startposition : (%f, %f)' % (eclick.xdata, eclick.ydata)
+ print ' endposition : (%f, %f)' % (erelease.xdata, erelease.ydata)
+ print ' used button : ', eclick.button
- span = Selector(ax, onselect,drawtype='box')
- show()
+ def toggle_Selector(event):
+ print ' Key pressed.'
+ if event.key in ['Q', 'q'] and toggle_Selector.RS.active:
+ print ' RectangleSelector deactivated.'
+ toggle_Selector.RS.set_active(False)
+ if event.key in ['A', 'a'] and not toggle_Selector.RS.active:
+ print ' RectangleSelector activated.'
+ toggle_Selector.RS.set_active(True)
+ x = arange(100)/(99.0)
+ y = sin(x)
+ fig = figure
+ ax = subplot(111)
+ ax.plot(x,y)
+
+ toggle_Selector.RS = RectangleSelector(ax, onselect, drawtype='line')
+ connect('key_press_event', toggle_Selector)
+ show()
"""
def __init__(self, ax, onselect, drawtype='box',
minspanx=None, minspany=None, useblit=False,
@@ -1001,8 +1017,6 @@
Use type if you want the mouse to draw a line, a box or nothing
between click and actual position ny setting
drawtype = 'line', drawtype='box' or drawtype = 'none'.
-
-
"""
self.ax = ax
self.visible = True
@@ -1012,6 +1026,7 @@
self.canvas.mpl_connect('button_release_event', self.release)
self.canvas.mpl_connect('draw_event', self.update_background)
+ self.active = True # for activation / deactivation
self.to_draw = None
self.background = None
@@ -1052,6 +1067,14 @@
def ignore(self, event):
'return True if event should be ignored'
+ # If RectangleSelector is not active :
+ if not self.active:
+ return True
+
+ # If canvas was locked
+ if not self.canvas.widgetlock.available(self):
+ return True
+
# If no button was pressed yet ignore the event if it was out
# of the axes
if self.eventpress == None:
@@ -1142,6 +1165,17 @@
self.update()
return False
+ def set_active(self, active):
+ """ Use this to activate / deactivate the RectangleSelector
+
+ from your program with an boolean variable 'active'.
+ """
+ self.active = active
+
+ def get_active(self):
+ """ to get status of active mode (boolean variable)"""
+ return self.active
+
class Lasso(Widget):
def __init__(self, ax, xy, callback=None, useblit=True):
self.axes = ax
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-20 18:00:34
|
Revision: 3869
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3869&view=rev
Author: mdboom
Date: 2007-09-20 11:00:32 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
First baby step in getting arbitrary non-linear transformations into
the pipeline.
Modified Paths:
--------------
branches/transforms/lib/matplotlib/axes.py
branches/transforms/lib/matplotlib/axis.py
branches/transforms/lib/matplotlib/backends/backend_agg.py
branches/transforms/lib/matplotlib/lines.py
branches/transforms/lib/matplotlib/path.py
branches/transforms/lib/matplotlib/text.py
branches/transforms/lib/matplotlib/transforms.py
Modified: branches/transforms/lib/matplotlib/axes.py
===================================================================
--- branches/transforms/lib/matplotlib/axes.py 2007-09-20 14:26:27 UTC (rev 3868)
+++ branches/transforms/lib/matplotlib/axes.py 2007-09-20 18:00:32 UTC (rev 3869)
@@ -633,10 +633,16 @@
self.transAxes = mtransforms.BboxTransform(
mtransforms.Bbox.unit(), self.bbox)
# self.set_transform(self.transAxes)
- self.transData = mtransforms.BboxTransform(
- self.viewLim, self.bbox)
+# self.transData = mtransforms.BboxTransform(
+# self.viewLim, self.bbox)
+ self.preDataTransform = mtransforms.BboxTransform(
+ self.viewLim, mtransforms.Bbox.unit())
+ self.dataTransform = mtransforms.TestLogTransform()
+ # self.dataTransform = mtransforms.Affine2D().scale(1.5)
+ self.transData = self.preDataTransform + self.dataTransform + mtransforms.BboxTransform(
+ mtransforms.Bbox.unit(), self.bbox)
+
-
def get_position(self, original=False):
'Return the axes rectangle left, bottom, width, height'
if original:
Modified: branches/transforms/lib/matplotlib/axis.py
===================================================================
--- branches/transforms/lib/matplotlib/axis.py 2007-09-20 14:26:27 UTC (rev 3868)
+++ branches/transforms/lib/matplotlib/axis.py 2007-09-20 18:00:32 UTC (rev 3869)
@@ -1032,18 +1032,17 @@
else:
bbox = Bbox.union(bboxes)
bottom = bbox.ymin
-
- self.label.set_position( (x, bottom-self.LABELPAD*self.figure.dpi / 72.0))
-
+ self.label.set_position( (x, bottom - self.LABELPAD*self.figure.dpi / 72.0))
+
else:
if not len(bboxes2):
top = self.axes.bbox.ymax
else:
bbox = bbox_union(bboxes2)
top = bbox.ymax
+
+ self.label.set_position( (x, top+self.LABELPAD*self.figure.dpi / 72.0))
- self.label.set_position( (x, top+self.LABELPAD*self.figure.dpi.get()/72.0))
-
def _update_offset_text_position(self, bboxes, bboxes2):
"""
Update the offset_text position based on the sequence of bounding
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-09-20 14:26:27 UTC (rev 3868)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-09-20 18:00:32 UTC (rev 3869)
@@ -84,7 +84,8 @@
from matplotlib.font_manager import findfont
from matplotlib.ft2font import FT2Font, LOAD_DEFAULT
from matplotlib.mathtext import MathTextParser
-from matplotlib.transforms import Bbox
+from matplotlib.path import Path
+from matplotlib.transforms import Affine2D, Bbox
from _backend_agg import RendererAgg as _RendererAgg
@@ -117,8 +118,8 @@
debug=False)
if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
'debug-annoying')
- self.draw_path = self._renderer.draw_path
- self.draw_markers = self._renderer.draw_markers
+ #self.draw_path = self._renderer.draw_path
+ #self.draw_markers = self._renderer.draw_markers
self.draw_image = self._renderer.draw_image
self.copy_from_bbox = self._renderer.copy_from_bbox
self.restore_region = self._renderer.restore_region
@@ -129,6 +130,17 @@
if __debug__: verbose.report('RendererAgg.__init__ done',
'debug-annoying')
+ # MGDTODO: This is a hack for now to allow for arbitrary transformations
+ def draw_path(self, gc, path, trans, rgbFace=None):
+ new_path, affine = path.transformed_without_affine(trans)
+ self._renderer.draw_path(gc, new_path, affine, rgbFace)
+
+ # MGDTODO: This is a hack for now to allow for arbitrary transformations
+ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
+ assert marker_trans.is_affine()
+ new_path, affine = path.transformed_without_affine(trans)
+ self._renderer.draw_markers(gc, marker_path, marker_trans, new_path, affine, rgbFace)
+
def draw_mathtext(self, gc, x, y, s, prop, angle):
"""
Draw the math text using matplotlib.mathtext
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py 2007-09-20 14:26:27 UTC (rev 3868)
+++ branches/transforms/lib/matplotlib/lines.py 2007-09-20 18:00:32 UTC (rev 3869)
@@ -1102,12 +1102,14 @@
"""
return self._dashcapstyle
+
def get_solid_capstyle(self):
"""
Get the cap style for solid linestyles
"""
return self._solidcapstyle
+
def is_dashed(self):
'return True if line is dashstyle'
return self._linestyle in ('--', '-.', ':')
Modified: branches/transforms/lib/matplotlib/path.py
===================================================================
--- branches/transforms/lib/matplotlib/path.py 2007-09-20 14:26:27 UTC (rev 3868)
+++ branches/transforms/lib/matplotlib/path.py 2007-09-20 18:00:32 UTC (rev 3869)
@@ -70,6 +70,13 @@
yield vertices[i]
i += 1
+ def transformed(self, transform):
+ return Path(transform.transform(self.vertices), self.codes)
+
+ def transformed_without_affine(self, transform):
+ vertices, affine = transform.transform_without_affine(self.vertices)
+ return Path(vertices, self.codes), affine
+
_unit_rectangle = None
#@classmethod
def unit_rectangle(cls):
Modified: branches/transforms/lib/matplotlib/text.py
===================================================================
--- branches/transforms/lib/matplotlib/text.py 2007-09-20 14:26:27 UTC (rev 3868)
+++ branches/transforms/lib/matplotlib/text.py 2007-09-20 18:00:32 UTC (rev 3869)
@@ -185,7 +185,8 @@
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:
@@ -260,27 +261,21 @@
else: offsety = ty - ymin
xmin += offsetx
- xmax += offsetx
ymin += offsety
- ymax += offsety
bbox = Bbox.from_lbwh(xmin, ymin, width, height)
-
-
# now rotate the positions around the first x,y position
xys = M.transform(offsetLayout)
- tx = xys[:, 0]
- ty = xys[:, 1]
- tx += offsetx
- ty += offsety
+ xys[:, 0] += offsetx
+ xys[:, 1] += offsety
# now inverse transform back to data coords
inverse_transform = self.get_transform().inverted()
xys = inverse_transform.transform(xys)
- xs, ys = zip(*xys)
-
+ xs, ys = xys[:, 0], xys[:, 1]
+
ret = bbox, zip(lines, whs, xs, ys)
self.cached[key] = ret
return ret
@@ -331,15 +326,15 @@
for line, wh, x, y in info:
x, y = trans.transform_point((x, y))
-
+
if renderer.flipy():
canvasw, canvash = renderer.get_canvas_width_height()
y = canvash-y
-
+
renderer.draw_text(gc, x, y, line,
self._fontproperties, angle,
ismath=self.is_math_text(line))
-
+
def get_color(self):
"Return the color of the text"
return self._color
@@ -407,7 +402,9 @@
return (x, y, self._text, self._color,
self._verticalalignment, self._horizontalalignment,
hash(self._fontproperties), self._rotation,
- self.get_transform(),
+ # MGDTODO: Find a better way to determine if the
+ # transform as changed
+ str(self.get_transform())
)
def get_text(self):
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py 2007-09-20 14:26:27 UTC (rev 3868)
+++ branches/transforms/lib/matplotlib/transforms.py 2007-09-20 18:00:32 UTC (rev 3869)
@@ -256,10 +256,10 @@
self.invalidate()
def transformed(self, transform):
- return Bbox(transform(self._points))
+ return Bbox(transform.transform(self._points))
def inverse_transformed(self, transform):
- return Bbox(transform.inverted()(self._points))
+ return Bbox(transform.inverted().transform(self._points))
def expanded(self, sw, sh):
width = self.width
@@ -408,13 +408,13 @@
# 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 not isinstance(points, npy.ndarray):
- import traceback
- print '-' * 60
- print 'A non-numpy array was passed in for transformation. Please '
- print 'correct this.'
- print "".join(traceback.format_stack())
- print points
+# if not isinstance(points, npy.ndarray):
+# import traceback
+# print '-' * 60
+# print 'A non-numpy array was passed in for transformation. Please '
+# print 'correct this.'
+# print "".join(traceback.format_stack())
+# print points
mtx = self.get_matrix()
points = npy.asarray(points, npy.float_)
points = points.transpose()
@@ -563,6 +563,10 @@
self._y = y_transform
self.set_children(['_x', '_y'])
+ def __repr__(self):
+ return "BlendedGenericTransform(%s,%s)" % (self._x, self._y)
+ __str__ = __repr__
+
def transform(self, points):
# MGDTODO: Optimize the case where one of these is
# an affine
@@ -590,28 +594,6 @@
return True
-class BlendedSeparableTransform(Transform):
- input_dims = 2
- output_dims = 2
-
- def __init__(self, x_transform, y_transform):
- # Here we ask: "Does it blend?"
- assert x_transform.is_separable()
- assert y_transform.is_separable()
- assert x_transform.input_dims == x.transform.output_dims == 1
- assert y_transform.input_dims == y.transform.output_dims == 1
-
- Transform.__init__(self)
- self._x = x_transform
- self._y = y_transform
- self.set_children(['_x', '_y'])
-
- def transform(self, points):
- x_points = self._x(points[:, 0])
- y_points = self._y(points[:, 1])
- return npy.vstack((x_points[:, 0:1], y_points[:, 1:2])).transpose()
-
-
class BlendedAffine2D(Affine2DBase, Transform):
def __init__(self, x_transform, y_transform):
assert x_transform.is_affine()
@@ -666,6 +648,10 @@
self._a = a
self._b = b
self.set_children(['_a', '_b'])
+
+ def __repr__(self):
+ return "CompositeGenericTransform(%s, %s)" % (self._a, self._b)
+ __str__ = __repr__
def transform(self, points):
return self._b.transform(self._a.transform(points))
@@ -724,10 +710,21 @@
input_dims = 2
output_dims = 2
def transform(self, xy):
- return xy * 2
+ marray = npy.ma.masked_where(xy <= 0.0, xy * 10.0)
+ return npy.log10(marray)
+
+ def inverted(self):
+ return TestInvertLogTransform()
+
+class TestInvertLogTransform(Transform):
+ input_dims = 2
+ output_dims = 2
+ def transform(self, xy):
+ return npy.power(10, xy) / 10.0
+
def inverted(self):
- return self
+ return TestLogTransform()
class BboxTransform(Affine2DBase):
@@ -825,7 +822,7 @@
assert bbox.bounds == (10, 15, 10, 10)
- print npy.asarray(bbox)
+ assert tuple(npy.asarray(bbox).flatten()) == (10, 15, 20, 25)
bbox.intervalx = (11, 21)
bbox.intervaly = (16, 26)
@@ -859,29 +856,35 @@
scale = Affine2D().scale(10, 20)
assert scale.to_values() == (10, 0, 0, 20, 0, 0)
rotation = Affine2D().rotate_deg(30)
- print rotation.to_values() == (0.86602540378443871, 0.49999999999999994,
+ assert rotation.to_values() == (0.86602540378443871, 0.49999999999999994,
-0.49999999999999994, 0.86602540378443871,
0.0, 0.0)
points = npy.array([[1,2],[3,4],[5,6],[7,8]], npy.float_)
- translated_points = translation(points)
+ translated_points = translation.transform(points)
assert (translated_points == [[11., 22.], [13., 24.], [15., 26.], [17., 28.]]).all()
- scaled_points = scale(points)
+ scaled_points = scale.transform(points)
print scaled_points
- rotated_points = rotation(points)
+ rotated_points = rotation.transform(points)
print rotated_points
- tpoints1 = rotation(translation(scale(points)))
+ tpoints1 = rotation.transform(translation.transform(scale.transform(points)))
trans_sum = scale + translation + rotation
- tpoints2 = trans_sum(points)
- print tpoints1, tpoints2
- print tpoints1 == tpoints2
+ tpoints2 = trans_sum.transform(points)
# Need to do some sort of fuzzy comparison here?
- # assert (tpoints1 == tpoints2).all()
+ assert (tpoints1.round() == tpoints2.round()).all()
+ print points
+
+ comp = TestLogTransform() + Affine2D().rotate_deg(15)
+ tpoints = comp.transform(points)
+ itpoints = comp.inverted().transform(tpoints)
+ print tpoints, itpoints
+ assert (points.round() == itpoints.round()).all()
+
# Here are some timing tests
points = npy.asarray([(random(), random()) for i in xrange(10000)])
- t = timeit.Timer("trans_sum(points)", "from __main__ import trans_sum, points")
+ t = timeit.Timer("trans_sum.transform(points)", "from __main__ import trans_sum, points")
print "Time to transform 10000 x 10 points:", t.timeit(10)
__all__ = ['Transform', 'Affine2D']
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-20 14:26:32
|
Revision: 3868
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3868&view=rev
Author: mdboom
Date: 2007-09-20 07:26:27 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
Don't copy path array to a contiguous one.
Modified Paths:
--------------
branches/transforms/src/_backend_agg.cpp
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp 2007-09-20 14:13:51 UTC (rev 3867)
+++ branches/transforms/src/_backend_agg.cpp 2007-09-20 14:26:27 UTC (rev 3868)
@@ -100,17 +100,18 @@
Py::Object vertices_obj = path_obj.getAttr("vertices");
Py::Object codes_obj = path_obj.getAttr("codes");
- vertices = (PyArrayObject*)PyArray_ContiguousFromObject
+ vertices = (PyArrayObject*)PyArray_FromObject
(vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
throw Py::ValueError("Invalid vertices array.");
- codes = (PyArrayObject*)PyArray_ContiguousFromObject
+
+ codes = (PyArrayObject*)PyArray_FromObject
(codes_obj.ptr(), PyArray_UINT8, 1, 1);
if (!codes)
throw Py::ValueError("Invalid codes array.");
if (codes->dimensions[0] != vertices->dimensions[0])
- throw Py::ValueError("Vertices and codes array are not the same length.");
+ throw Py::ValueError("vertices and codes arrays are not the same length.");
m_total_vertices = codes->dimensions[0];
}
@@ -125,10 +126,9 @@
inline unsigned vertex(unsigned idx, double* x, double* y) {
if (idx > m_total_vertices)
throw Py::RuntimeError("Requested vertex past end");
- double* pv = (double*)(vertices->data + (idx * vertices->strides[0]));
- *x = *pv++;
- *y = *pv;
- return code_map[(unsigned int)*(codes->data + (idx * codes->strides[0]))];
+ *x = *(double*)PyArray_GETPTR2(vertices, idx, 0);
+ *y = *(double*)PyArray_GETPTR2(vertices, idx, 1);
+ return code_map[(int)*(char *)PyArray_GETPTR1(codes, idx)];
}
inline unsigned vertex(double* x, double* y) {
@@ -145,12 +145,14 @@
}
};
-const char PathIterator::code_map[] = {0,
- agg::path_cmd_move_to,
- agg::path_cmd_line_to,
- agg::path_cmd_curve3,
- agg::path_cmd_curve4,
- agg::path_cmd_end_poly | agg::path_flags_close};
+// Maps path codes on the Python side to agg path commands
+const char PathIterator::code_map[] =
+ {0,
+ agg::path_cmd_move_to,
+ agg::path_cmd_line_to,
+ agg::path_cmd_curve3,
+ agg::path_cmd_curve4,
+ agg::path_cmd_end_poly | agg::path_flags_close};
template<class VertexSource> class conv_quantize
{
@@ -160,19 +162,16 @@
void set_source(VertexSource& source) { m_source = &source; }
- void rewind(unsigned path_id)
- {
+ void rewind(unsigned path_id) {
m_source->rewind(path_id);
}
- unsigned vertex(double* x, double* y)
- {
+ unsigned vertex(double* x, double* y) {
unsigned cmd = m_source->vertex(x, y);
- if(m_quantize && agg::is_vertex(cmd))
- {
- *x = (int)(*x);
- *y = (int)(*y);
- }
+ if (m_quantize && agg::is_vertex(cmd)) {
+ *x = (int)(*x + 0.5);
+ *y = (int)(*y + 0.5);
+ }
return cmd;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2007-09-20 14:13:53
|
Revision: 3867
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3867&view=rev
Author: jdh2358
Date: 2007-09-20 07:13:51 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
committed rectangle selector lock patch
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/mlab.py
trunk/matplotlib/lib/matplotlib/widgets.py
Modified: trunk/matplotlib/lib/matplotlib/mlab.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mlab.py 2007-09-20 13:59:15 UTC (rev 3866)
+++ trunk/matplotlib/lib/matplotlib/mlab.py 2007-09-20 14:13:51 UTC (rev 3867)
@@ -1255,7 +1255,7 @@
if unpack: return X.transpose()
else: return X
-def csv2rec(fname, comments='#', skiprows=1, checkrows=5, delimiter=',',
+def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',',
converterd=None, names=None, missing=None):
"""
Load data from comma/space/tab delimited file in fname into a
@@ -1314,6 +1314,14 @@
else: return get_func(item, funcmap[func]) # recurse
else: return func
+
+ # map column names that clash with builtins -- TODO - extend this list
+ itemd = {
+ 'return' : 'return_',
+ 'file' : 'file_',
+ 'print' : 'print_',
+ }
+
def get_converters(reader):
converters = None
@@ -1352,6 +1360,7 @@
if not len(item):
item = 'column%d'%i
+ item = itemd.get(item, item)
cnt = seen.get(item, 0)
if cnt>0:
names.append(item + '%d'%cnt)
Modified: trunk/matplotlib/lib/matplotlib/widgets.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/widgets.py 2007-09-20 13:59:15 UTC (rev 3866)
+++ trunk/matplotlib/lib/matplotlib/widgets.py 2007-09-20 14:13:51 UTC (rev 3867)
@@ -955,24 +955,40 @@
warnings.warn('Use SpanSelector instead!', DeprecationWarning)
SpanSelector.__init__(self, ax, onselect, 'horizontal', **kwargs)
+
class RectangleSelector:
"""
Select a min/max range of the x axes for a matplotlib Axes
Example usage:
- ax = subplot(111)
- ax.plot(x,y)
+ from matplotlib.widgets import RectangleSelector
+ from pylab import *
- def onselect(eclick, erelease):
+ def onselect(eclick, erelease):
'eclick and erelease are matplotlib events at press and release'
- print 'startposition : (%f,%f)'%(eclick.xdata, eclick.ydata)
- print 'endposition : (%f,%f)'%(erelease.xdata, erelease.ydata)
- print 'used button : ', eclick.button
+ print ' startposition : (%f, %f)' % (eclick.xdata, eclick.ydata)
+ print ' endposition : (%f, %f)' % (erelease.xdata, erelease.ydata)
+ print ' used button : ', eclick.button
- span = Selector(ax, onselect,drawtype='box')
- show()
+ def toggle_Selector(event):
+ print ' Key pressed.'
+ if event.key in ['Q', 'q'] and toggle_Selector.RS.active:
+ print ' RectangleSelector deactivated.'
+ toggle_Selector.RS.set_active(False)
+ if event.key in ['A', 'a'] and not toggle_Selector.RS.active:
+ print ' RectangleSelector activated.'
+ toggle_Selector.RS.set_active(True)
+ x = arange(100)/(99.0)
+ y = sin(x)
+ fig = figure
+ ax = subplot(111)
+ ax.plot(x,y)
+
+ toggle_Selector.RS = RectangleSelector(ax, onselect, drawtype='line')
+ connect('key_press_event', toggle_Selector)
+ show()
"""
def __init__(self, ax, onselect, drawtype='box',
minspanx=None, minspany=None, useblit=False,
@@ -1001,8 +1017,6 @@
Use type if you want the mouse to draw a line, a box or nothing
between click and actual position ny setting
drawtype = 'line', drawtype='box' or drawtype = 'none'.
-
-
"""
self.ax = ax
self.visible = True
@@ -1012,6 +1026,7 @@
self.canvas.mpl_connect('button_release_event', self.release)
self.canvas.mpl_connect('draw_event', self.update_background)
+ self.active = True # for activation / deactivation
self.to_draw = None
self.background = None
@@ -1052,6 +1067,14 @@
def ignore(self, event):
'return True if event should be ignored'
+ # If RectangleSelector is not active :
+ if not self.active:
+ return True
+
+ # If canvas was locked
+ if not self.canvas.widgetlock.available(self):
+ return True
+
# If no button was pressed yet ignore the event if it was out
# of the axes
if self.eventpress == None:
@@ -1142,6 +1165,17 @@
self.update()
return False
+ def set_active(self, active):
+ """ Use this to activate / deactivate the RectangleSelector
+
+ from your program with an boolean variable 'active'.
+ """
+ self.active = active
+
+ def get_active(self):
+ """ to get status of active mode (boolean variable)"""
+ return self.active
+
class Lasso(Widget):
def __init__(self, ax, xy, callback=None, useblit=True):
self.axes = ax
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-20 13:59:16
|
Revision: 3866
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3866&view=rev
Author: mdboom
Date: 2007-09-20 06:59:15 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
Merged revisions 3847-3865 via svnmerge from
http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib
........
r3853 | jouni | 2007-09-15 00:01:56 -0400 (Sat, 15 Sep 2007) | 2 lines
Bugfix and doc fixes in type1font.py
........
r3861 | mdboom | 2007-09-20 08:31:26 -0400 (Thu, 20 Sep 2007) | 2 lines
Fix font.size from being saved in the fontManager.cache
........
r3862 | mdboom | 2007-09-20 08:40:41 -0400 (Thu, 20 Sep 2007) | 2 lines
Removing debugging output in last commit.
........
r3863 | jdh2358 | 2007-09-20 09:50:27 -0400 (Thu, 20 Sep 2007) | 1 line
added gradient bar example
........
Modified Paths:
--------------
branches/transforms/lib/matplotlib/font_manager.py
Added Paths:
-----------
branches/transforms/examples/gradient_bar.py
Property Changed:
----------------
branches/transforms/
Property changes on: branches/transforms
___________________________________________________________________
Name: svnmerge-integrated
- /trunk/matplotlib:1-3846
+ /trunk/matplotlib:1-3865
Copied: branches/transforms/examples/gradient_bar.py (from rev 3863, trunk/matplotlib/examples/gradient_bar.py)
===================================================================
--- branches/transforms/examples/gradient_bar.py (rev 0)
+++ branches/transforms/examples/gradient_bar.py 2007-09-20 13:59:15 UTC (rev 3866)
@@ -0,0 +1,26 @@
+from pylab import figure, show, nx, cm
+
+def gbar(ax, x, y, width=0.5, bottom=0):
+ X = [[.6, .6],[.7,.7]]
+ for left,top in zip(x, y):
+ right = left+width
+ ax.imshow(X, interpolation='bicubic', cmap=cm.Blues,
+ extent=(left, right, bottom, top), alpha=1)
+
+fig = figure()
+
+xmin, xmax = xlim = 0,10
+ymin, ymax = ylim = 0,1
+ax = fig.add_subplot(111, xlim=xlim, ylim=ylim,
+ autoscale_on=False)
+X = [[.6, .6],[.7,.7]]
+
+ax.imshow(X, interpolation='bicubic', cmap=cm.copper,
+ extent=(xmin, xmax, ymin, ymax), alpha=1)
+
+N = 10
+x = nx.arange(N)+0.25
+y = nx.mlab.rand(N)
+gbar(ax, x, y, width=0.7)
+ax.set_aspect('normal')
+show()
Modified: branches/transforms/lib/matplotlib/font_manager.py
===================================================================
--- branches/transforms/lib/matplotlib/font_manager.py 2007-09-20 13:57:59 UTC (rev 3865)
+++ branches/transforms/lib/matplotlib/font_manager.py 2007-09-20 13:59:15 UTC (rev 3866)
@@ -843,10 +843,9 @@
"""
def __init__(self, size=None, weight='normal'):
- if not size : size = rcParams['font.size']
- self.__default_size = size
self.__default_weight = weight
-
+ self.default_size = size
+
paths = [os.path.join(rcParams['datapath'],'fonts','ttf'),
os.path.join(rcParams['datapath'],'fonts','afm')]
@@ -899,7 +898,9 @@
def get_default_size(self):
"Return the default font size."
- return self.__default_size
+ if self.default_size is None:
+ return rcParams['font.size']
+ return self.default_size
def set_default_weight(self, weight):
"Set the default font weight. The initial value is 'normal'."
@@ -1085,6 +1086,7 @@
try:
fontManager = pickle_load(_fmcache)
+ fontManager.default_size = None
verbose.report("Using fontManager instance from %s" % _fmcache)
except:
_rebuild()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-20 13:58:01
|
Revision: 3865
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3865&view=rev
Author: mdboom
Date: 2007-09-20 06:57:59 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
Go all out with iterator (rather than copy) approach, as it is much faster.
Modified Paths:
--------------
branches/transforms/lib/matplotlib/backend_bases.py
branches/transforms/lib/matplotlib/backends/backend_agg.py
branches/transforms/lib/matplotlib/transforms.py
branches/transforms/src/_backend_agg.cpp
branches/transforms/src/_backend_agg.h
Modified: branches/transforms/lib/matplotlib/backend_bases.py
===================================================================
--- branches/transforms/lib/matplotlib/backend_bases.py 2007-09-20 13:57:32 UTC (rev 3864)
+++ branches/transforms/lib/matplotlib/backend_bases.py 2007-09-20 13:57:59 UTC (rev 3865)
@@ -17,11 +17,6 @@
class RendererBase:
"""An abstract base class to handle drawing/rendering operations
"""
- # This will cache paths across rendering instances
- # Each subclass of RenderBase should define this a weak-keyed
- # dictionary to hold native paths
- # _native_paths = weakref.WeakKeyDictionary()
-
def __init__(self):
self._texmanager = None
@@ -37,43 +32,16 @@
"""
pass
- def _get_cached_native_path(self, path):
- native_path = self._native_paths.get(path)
- if native_path is None:
- print "CACHE MISS", path
- native_path = self.convert_to_native_path(path)
- self._native_paths[path] = native_path
- return native_path
-
def draw_path(self, gc, path, transform, rgbFace=None):
"""
Handles the caching of the native path associated with the
given path and calls the underlying backend's _draw_path to
actually do the drawing.
"""
- native_path = self._get_cached_native_path(path)
- self._draw_native_path(gc, native_path, transform, rgbFace)
+ # MGDTODO: Update docstring
+ raise NotImplementedError
- def _draw_native_path(self, gc, native_path, transform, rgbFace):
- """
- Draw the native path object with the given GraphicsContext and
- transform. The transform passed in will always be affine.
- """
- raise NotImplementedError
-
- def convert_to_native_path(self, path):
- """
- Backends will normally will override this, but if they don't need any
- special optimizations, they can just have the generic path data
- passed to them in draw_path.
- """
- return path
-
def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
- native_marker_path = self._get_cached_native_path(marker_path)
- self._draw_native_markers(gc, native_marker_path, marker_trans, path, trans, rgbFace)
-
- def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
"""
This method is currently underscore hidden because the
draw_markers method is being used as a sentinel for newstyle
@@ -94,7 +62,11 @@
vec6 = transform.as_vec6_val()
...backend dependent affine...
"""
+ # MGDTODO: Update docstring
raise NotImplementedError
+
+ def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
+ raise NotImplementedError
def get_image_magnification(self):
"""
Modified: branches/transforms/lib/matplotlib/backends/backend_agg.py
===================================================================
--- branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-09-20 13:57:32 UTC (rev 3864)
+++ branches/transforms/lib/matplotlib/backends/backend_agg.py 2007-09-20 13:57:59 UTC (rev 3865)
@@ -117,8 +117,8 @@
debug=False)
if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
'debug-annoying')
-
- self.convert_to_native_path = self._renderer.convert_to_native_path
+ self.draw_path = self._renderer.draw_path
+ self.draw_markers = self._renderer.draw_markers
self.draw_image = self._renderer.draw_image
self.copy_from_bbox = self._renderer.copy_from_bbox
self.restore_region = self._renderer.restore_region
@@ -129,16 +129,6 @@
if __debug__: verbose.report('RendererAgg.__init__ done',
'debug-annoying')
- def _draw_native_path(self, gc, path, transform, rgbFace):
- return self._renderer.draw_path(gc, path, transform.get_matrix(), rgbFace)
-
- def _draw_native_markers(self, gc, native_marker_path, marker_trans, path, trans, rgbFace=None):
- return self._renderer.draw_markers(
- gc,
- native_marker_path, marker_trans.get_matrix(),
- path.vertices, path.codes, trans.get_matrix(),
- rgbFace)
-
def draw_mathtext(self, gc, x, y, s, prop, angle):
"""
Draw the math text using matplotlib.mathtext
Modified: branches/transforms/lib/matplotlib/transforms.py
===================================================================
--- branches/transforms/lib/matplotlib/transforms.py 2007-09-20 13:57:32 UTC (rev 3864)
+++ branches/transforms/lib/matplotlib/transforms.py 2007-09-20 13:57:59 UTC (rev 3865)
@@ -365,7 +365,7 @@
Transform.__init__(self)
self._inverted = None
- def __array__(self):
+ def __array__(self, *args, **kwargs):
return self.get_matrix()
def _do_invalidation(self):
Modified: branches/transforms/src/_backend_agg.cpp
===================================================================
--- branches/transforms/src/_backend_agg.cpp 2007-09-20 13:57:32 UTC (rev 3864)
+++ branches/transforms/src/_backend_agg.cpp 2007-09-20 13:57:59 UTC (rev 3865)
@@ -48,59 +48,42 @@
agg::trans_affine py_to_agg_transformation_matrix(const Py::Object& obj) {
PyArrayObject* matrix = NULL;
- double a = 1.0, b = 0.0, c = 0.0, d = 1.0, e = 0.0, f = 0.0;
-
try {
- matrix = (PyArrayObject*) PyArray_ContiguousFromObject(obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!matrix || matrix->nd != 2 || matrix->dimensions[0] != 3 || matrix->dimensions[1] != 3) {
- throw Py::ValueError("Invalid affine transformation matrix.");
+ matrix = (PyArrayObject*) PyArray_FromObject(obj.ptr(), PyArray_DOUBLE, 2, 2);
+ if (!matrix) {
+ throw Py::Exception();
}
-
- size_t stride0 = matrix->strides[0];
- size_t stride1 = matrix->strides[1];
- char* row0 = matrix->data;
- char* row1 = row0 + stride0;
-
- a = *(double*)(row0);
- row0 += stride1;
- c = *(double*)(row0);
- row0 += stride1;
- e = *(double*)(row0);
-
- b = *(double*)(row1);
- row1 += stride1;
- d = *(double*)(row1);
- row1 += stride1;
- f = *(double*)(row1);
+ if (matrix->nd == 2 || matrix->dimensions[0] == 3 || matrix->dimensions[1] == 3) {
+ size_t stride0 = matrix->strides[0];
+ size_t stride1 = matrix->strides[1];
+ char* row0 = matrix->data;
+ char* row1 = row0 + stride0;
+
+ double a = *(double*)(row0);
+ row0 += stride1;
+ double c = *(double*)(row0);
+ row0 += stride1;
+ double e = *(double*)(row0);
+
+ double b = *(double*)(row1);
+ row1 += stride1;
+ double d = *(double*)(row1);
+ row1 += stride1;
+ double f = *(double*)(row1);
+
+ Py_XDECREF(matrix);
+
+ return agg::trans_affine(a, b, c, d, e, f);
+ }
} catch (...) {
- Py_XDECREF(matrix);
+
}
Py_XDECREF(matrix);
-
- return agg::trans_affine(a, b, c, d, e, f);
+ throw Py::TypeError("Invalid affine transformation matrix");
}
-/** Helper function to get the next vertex in a Numpy array of vertices.
- * Will generally be used through the GET_NEXT_VERTEX macro.
- */
-inline void get_next_vertex(const char* & vertex_i, const char* vertex_end,
- double& x, double& y,
- size_t next_vertex_stride,
- size_t next_axis_stride,
- const char* & code_i, size_t code_stride) {
- if (vertex_i + next_axis_stride >= vertex_end)
- throw Py::ValueError("Error parsing path. Read past end of vertices");
- x = *(double*)vertex_i;
- y = *(double*)(vertex_i + next_axis_stride);
- vertex_i += next_vertex_stride;
- code_i += code_stride;
-}
-
-#define GET_NEXT_VERTEX(x, y) get_next_vertex(vertex_i, vertex_end, x, y, next_vertex_stride, next_axis_stride, code_i, code_stride)
-
Py::Object BufferRegion::to_string(const Py::Tuple &args) {
-
// owned=true to prevent memory leak
return Py::String(PyString_FromStringAndSize((const char*)aggbuf.data,aggbuf.height*aggbuf.stride), true);
}
@@ -145,7 +128,6 @@
double* pv = (double*)(vertices->data + (idx * vertices->strides[0]));
*x = *pv++;
*y = *pv;
- // MGDTODO: Range check
return code_map[(unsigned int)*(codes->data + (idx * codes->strides[0]))];
}
@@ -170,9 +152,43 @@
agg::path_cmd_curve4,
agg::path_cmd_end_poly | agg::path_flags_close};
+template<class VertexSource> class conv_quantize
+{
+public:
+ conv_quantize(VertexSource& source, bool quantize) :
+ m_source(&source), m_quantize(quantize) {}
+
+ void set_source(VertexSource& source) { m_source = &source; }
+
+ void rewind(unsigned path_id)
+ {
+ m_source->rewind(path_id);
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ unsigned cmd = m_source->vertex(x, y);
+ if(m_quantize && agg::is_vertex(cmd))
+ {
+ *x = (int)(*x);
+ *y = (int)(*y);
+ }
+ return cmd;
+ }
+
+ void activate(bool quantize) {
+ m_quantize = quantize;
+ }
+
+private:
+ VertexSource* m_source;
+ bool m_quantize;
+};
+
+
GCAgg::GCAgg(const Py::Object &gc, double dpi, bool snapto) :
dpi(dpi), snapto(snapto), isaa(true), linewidth(1.0), alpha(1.0),
- cliprect(NULL), clippath(NULL),
+ cliprect(NULL),
Ndash(0), dashOffset(0.0), dasha(NULL)
{
_VERBOSE("GCAgg::GCAgg");
@@ -316,15 +332,7 @@
_VERBOSE("GCAgg::_set_clip_path");
- Py_XINCREF(clippath);
- clippath = NULL;
-
- Py::Object o = gc.getAttr("_clippath");
- if (o.ptr()==Py_None) {
- return;
- }
-
- clippath = new PathAgg(o);
+ clippath = gc.getAttr("_clippath");
}
@@ -337,8 +345,7 @@
height(height),
dpi(dpi),
NUMBYTES(width*height*4),
- debug(debug),
- lastclippath(NULL)
+ debug(debug)
{
_VERBOSE("RendererAgg::RendererAgg");
unsigned stride(width*4);
@@ -599,7 +606,7 @@
Py::Object
RendererAgg::draw_markers(const Py::Tuple& args) {
- typedef agg::conv_transform<agg::path_storage> transformed_path_t;
+ typedef agg::conv_transform<PathIterator> transformed_path_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;
@@ -607,27 +614,29 @@
theRasterizer->reset_clipping();
- args.verify_length(7);
+ args.verify_length(5, 6);
GCAgg gc = GCAgg(args[0], dpi);
Py::Object marker_path_obj = args[1];
- if (!PathAgg::check(marker_path_obj))
- throw Py::TypeError("Native path object is not of correct type");
- PathAgg* marker_path = static_cast<PathAgg*>(marker_path_obj.ptr());
agg::trans_affine marker_trans = py_to_agg_transformation_matrix(args[2]);
- Py::Object vertices_obj = args[3];
- Py::Object codes_obj = args[4];
- agg::trans_affine trans = py_to_agg_transformation_matrix(args[5]);
- facepair_t face = _get_rgba_face(args[6], gc.alpha);
+ Py::Object path_obj = args[3];
+ agg::trans_affine trans = py_to_agg_transformation_matrix(args[4]);
+ Py::Object face_obj;
+ if (args.size() == 6)
+ face_obj = args[5];
+ facepair_t face = _get_rgba_face(face_obj, gc.alpha);
// Deal with the difference in y-axis direction
marker_trans *= agg::trans_affine_scaling(1.0, -1.0);
trans *= agg::trans_affine_scaling(1.0, -1.0);
trans *= agg::trans_affine_translation(0.0, (double)height);
- marker_path->rewind(0);
- transformed_path_t marker_path_transformed(*marker_path, marker_trans);
+ PathIterator marker_path(marker_path_obj);
+ transformed_path_t marker_path_transformed(marker_path, marker_trans);
curve_t marker_path_curve(marker_path_transformed);
+
+ PathIterator path(path_obj);
+ transformed_path_t path_transformed(path, trans);
//maxim's suggestions for cached scanlines
agg::scanline_storage_aa8 scanlines;
@@ -635,19 +644,8 @@
agg::int8u* fillCache = NULL;
agg::int8u* strokeCache = NULL;
- PyArrayObject* vertices = NULL;
- PyArrayObject* codes = NULL;
try {
- vertices = (PyArrayObject*)PyArray_ContiguousFromObject
- (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
- throw Py::ValueError("Invalid vertices array.");
- codes = (PyArrayObject*)PyArray_ContiguousFromObject
- (codes_obj.ptr(), PyArray_UINT8, 1, 1);
- if (!codes)
- throw Py::ValueError("Invalid codes array.");
-
unsigned fillSize = 0;
if (face.first) {
theRasterizer->add_path(marker_path_curve);
@@ -681,53 +679,29 @@
rendererBase->clip_box(l, height-(b+h),l+w, height-b);
}
- size_t next_vertex_stride = vertices->strides[0];
- size_t next_axis_stride = vertices->strides[1];
- size_t code_stride = codes->strides[0];
-
- const char* vertex_i = vertices->data;
- const char* code_i = codes->data;
- const char* vertex_end = vertex_i + (vertices->dimensions[0] * vertices->strides[0]);
-
- size_t N = codes->dimensions[0];
double x, y;
agg::serialized_scanlines_adaptor_aa8 sa;
agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
- for (size_t i=0; i < N; i++) {
- size_t num_vertices = NUM_VERTICES[(int)(*code_i)];
- if (num_vertices) {
- for (size_t j=0; j<num_vertices; ++j)
- GET_NEXT_VERTEX(x, y);
- if (*code_i == STOP || *code_i == CLOSEPOLY)
- continue;
-
- trans.transform(&x, &y);
-
- if (face.first) {
- //render the fill
- sa.init(fillCache, fillSize, x, y);
- rendererAA->color(face.second);
- agg::render_scanlines(sa, sl, *rendererAA);
- }
-
- //render the stroke
- sa.init(strokeCache, strokeSize, x, y);
- rendererAA->color(gc.color);
+ while (path_transformed.vertex(&x, &y) != agg::path_cmd_stop) {
+ if (face.first) {
+ //render the fill
+ sa.init(fillCache, fillSize, x, y);
+ rendererAA->color(face.second);
agg::render_scanlines(sa, sl, *rendererAA);
}
- code_i += code_stride;
+
+ //render the stroke
+ sa.init(strokeCache, strokeSize, x, y);
+ rendererAA->color(gc.color);
+ agg::render_scanlines(sa, sl, *rendererAA);
}
} catch(...) {
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
delete[] fillCache;
delete[] strokeCache;
}
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
delete [] fillCache;
delete [] strokeCache;
@@ -888,98 +862,12 @@
}
-Py::Object
-RendererAgg::convert_to_native_path(const Py::Tuple& args) {
- _VERBOSE("RendererAgg::draw_image");
- args.verify_length(1);
-
- Py::Object path = args[0];
- return Py::asObject(new PathAgg(path));
-}
-
-
-PathAgg::PathAgg(const Py::Object& path_obj) : curvy(false) {
- Py::Object vertices_obj = path_obj.getAttr("vertices");
- Py::Object codes_obj = path_obj.getAttr("codes");
-
- PyArrayObject* vertices = NULL;
- PyArrayObject* codes = NULL;
-
- try {
- vertices = (PyArrayObject*)PyArray_ContiguousFromObject
- (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
- if (!vertices || vertices->nd != 2 || vertices->dimensions[1] != 2)
- throw Py::ValueError("Invalid vertices array.");
- codes = (PyArrayObject*)PyArray_ContiguousFromObject
- (codes_obj.ptr(), PyArray_UINT8, 1, 1);
- if (!codes)
- throw Py::ValueError("Invalid codes array.");
-
- size_t next_vertex_stride = vertices->strides[0];
- size_t next_axis_stride = vertices->strides[1];
- size_t code_stride = codes->strides[0];
-
- const char* vertex_i = vertices->data;
- const char* code_i = codes->data;
- const char* vertex_end = vertex_i + (vertices->dimensions[0] * vertices->strides[0]);
-
- size_t N = codes->dimensions[0];
- double x0, y0, x1, y1, x2, y2;
-
- for (size_t i = 0; i < N; ++i) {
- switch (*(unsigned char*)(code_i)) {
- case STOP:
- GET_NEXT_VERTEX(x0, y0);
- _VERBOSE("STOP");
- // MGDTODO: If this isn't the end, we should raise an error
- break;
- case MOVETO:
- GET_NEXT_VERTEX(x0, y0);
- move_to(x0, y0);
- _VERBOSE("MOVETO");
- break;
- case LINETO:
- GET_NEXT_VERTEX(x0, y0);
- line_to(x0, y0);
- _VERBOSE("LINETO");
- break;
- case CURVE3:
- GET_NEXT_VERTEX(x0, y0);
- GET_NEXT_VERTEX(x1, y1);
- curve3(x0, y0, x1, y1);
- curvy = true;
- _VERBOSE("CURVE3");
- break;
- case CURVE4:
- GET_NEXT_VERTEX(x0, y0);
- GET_NEXT_VERTEX(x1, y1);
- GET_NEXT_VERTEX(x2, y2);
- curve4(x0, y0, x1, y1, x2, y2);
- curvy = true;
- _VERBOSE("CURVE4");
- break;
- case CLOSEPOLY:
- close_polygon();
- GET_NEXT_VERTEX(x0, y0);
- _VERBOSE("CLOSEPOLY");
- break;
- }
- }
- } catch(...) {
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
- throw;
- }
-
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
-}
-
Py::Object
RendererAgg::draw_path(const Py::Tuple& args) {
typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef agg::conv_curve<transformed_path_t> curve_t;
+ typedef conv_quantize<transformed_path_t> quantize_t;
+ typedef agg::conv_curve<quantize_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;
@@ -991,61 +879,59 @@
theRasterizer->reset_clipping();
_VERBOSE("RendererAgg::draw_path");
- args.verify_length(4);
+ args.verify_length(3, 4);
- GCAgg gc = GCAgg(args[0], dpi);
+ Py::Object gc_obj = args[0];
Py::Object path_obj = args[1];
-// if (!PathAgg::check(path_obj))
-// throw Py::TypeError("Native path object is not of correct type");
- // PathAgg* path = static_cast<PathAgg*>(path_obj.ptr());
PathIterator path(path_obj);
agg::trans_affine trans = py_to_agg_transformation_matrix(args[2]);
- facepair_t face = _get_rgba_face(args[3], gc.alpha);
trans *= agg::trans_affine_scaling(1.0, -1.0);
trans *= agg::trans_affine_translation(0.0, (double)height);
- transformed_path_t* tpath = NULL;
- agg::path_storage new_path;
+ bool snap = false;
+ if (path.total_vertices() == 2) {
+ double x0, y0, x1, y1;
+ path.vertex(0, &x0, &y0);
+ trans.transform(&x0, &y0);
+ path.vertex(1, &x1, &y1);
+ trans.transform(&x1, &y1);
+ snap = ((int)x0 == (int)x1) || ((int)y0 == (int)y1);
+ }
- bool has_clippath = (gc.clippath != NULL);
+ GCAgg gc = GCAgg(gc_obj, dpi, snap);
+ Py::Object face_obj;
+ if (args.size() == 4)
+ face_obj = args[3];
+ facepair_t face = _get_rgba_face(face_obj, gc.alpha);
- if (has_clippath && (gc.clippath != lastclippath || trans != lastclippath_transform)) {
-// rendererBaseAlphaMask->clear(agg::gray8(0, 0));
-// gc.clippath->rewind(0);
-// transformed_path_t transformed_clippath(*(gc.clippath), trans);
-// theRasterizer->add_path(transformed_clippath);
-// rendererAlphaMask->color(agg::gray8(255, 255));
-// agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, *rendererAlphaMask);
-// lastclippath = gc.clippath;
-// lastclippath_transform = trans;
+ bool has_clippath = (gc.clippath.ptr() != Py_None);
+
+ if (has_clippath &&
+ (gc.clippath.ptr() != lastclippath.ptr() || trans != lastclippath_transform)) {
+ PathIterator clippath(gc.clippath);
+ rendererBaseAlphaMask->clear(agg::gray8(0, 0));
+ transformed_path_t transformed_clippath(clippath, trans);
+ agg::conv_curve<transformed_path_t> curved_clippath(transformed_clippath);
+ theRasterizer->add_path(curved_clippath);
+ rendererAlphaMask->color(agg::gray8(255, 255));
+ agg::render_scanlines(*theRasterizer, *scanlineAlphaMask, *rendererAlphaMask);
+ lastclippath = gc.clippath;
+ lastclippath_transform = trans;
}
try {
// If this is a straight horizontal or vertical line, quantize to nearest
// pixels
-// if (path.total_vertices() == 2) {
-// double x0, y0, x1, y1;
-// path.vertex(0, &x0, &y0);
-// trans.transform(&x0, &y0);
-// path.vertex(1, &x1, &y1);
-// trans.transform(&x1, &y1);
-// if (((int)x0 == (int)x1) || ((int)y0 == (int)y1)) {
-// new_path.move_to((int)x0 + 0.5, (int)y0 + 0.5);
-// new_path.line_to((int)x1 + 0.5, (int)y1 + 0.5);
-// tpath = new transformed_path_t(new_path, agg::trans_affine());
-// }
-// }
- if (!tpath) {
- tpath = new transformed_path_t(path, trans);
- }
+ transformed_path_t tpath(path, trans);
+ quantize_t quantized(tpath, snap);
// Benchmarking shows that there is no noticable slowdown to always
// treating paths as having curved segments. Doing so greatly
// simplifies the code
- curve_t curve(*tpath);
+ curve_t curve(quantized);
set_clipbox_rasterizer(gc.cliprect);
@@ -1106,12 +992,11 @@
}
}
} catch (...) {
- delete tpath;
+ // MGDTODO: We don't have anything on the heap, so this catch
+ // clause isn't really necessary, but we might again soon...
throw;
}
- delete tpath;
-
return Py::Object();
}
@@ -1446,11 +1331,9 @@
behaviors().doc("The agg backend extension module");
add_varargs_method("draw_path", &RendererAgg::draw_path,
- "draw_path(gc, rgbFace, native_path, transform)\n");
- add_varargs_method("convert_to_native_path", &RendererAgg::convert_to_native_path,
- "convert_to_native_path(vertices, codes)\n");
+ "draw_path(gc, path, transform, rgbFace)\n");
add_varargs_method("draw_markers", &RendererAgg::draw_markers,
- "draw_markers(gc, marker_path, marker_trans, vertices, codes, rgbFace)\n");
+ "draw_markers(gc, marker_path, marker_trans, path, rgbFace)\n");
add_varargs_method("draw_text_image", &RendererAgg::draw_text_image,
"draw_text_image(font_image, x, y, r, g, b, a)\n");
add_varargs_method("draw_image", &RendererAgg::draw_image,
@@ -1476,12 +1359,6 @@
"restore_region(region)");
}
-void PathAgg::init_type()
-{
- behaviors().name("PathAgg");
- behaviors().doc("A native Agg path object");
-}
-
extern "C"
DL_EXPORT(void)
init_backend_agg(void)
Modified: branches/transforms/src/_backend_agg.h
===================================================================
--- branches/transforms/src/_backend_agg.h 2007-09-20 13:57:32 UTC (rev 3864)
+++ branches/transforms/src/_backend_agg.h 2007-09-20 13:57:59 UTC (rev 3865)
@@ -105,20 +105,6 @@
};
};
-// A completely opaque data type used only to pass native path
-// data to/from Python. Python can't do anything with the data
-// other than create and then use it.
-class PathAgg :
- public agg::path_storage,
- public Py::PythonExtension<PathAgg> {
-public:
- static void init_type(void);
-
- PathAgg(const Py::Object& path_obj);
-
- bool curvy;
-};
-
class GCAgg {
public:
GCAgg(const Py::Object& gc, double dpi, bool snapto=false);
@@ -126,7 +112,6 @@
~GCAgg() {
delete [] dasha;
delete [] cliprect;
- Py_XINCREF(clippath);
}
double dpi;
@@ -142,7 +127,7 @@
agg::rgba color;
double *cliprect;
- PathAgg *clippath;
+ Py::Object clippath;
//dashes
size_t Ndash;
double dashOffset;
@@ -183,7 +168,6 @@
Py::Object draw_text_image(const Py::Tuple & args);
Py::Object draw_image(const Py::Tuple & args);
Py::Object draw_path(const Py::Tuple & args);
- Py::Object convert_to_native_path(const Py::Tuple & args);
Py::Object write_rgba(const Py::Tuple & args);
Py::Object write_png(const Py::Tuple & args);
@@ -240,7 +224,7 @@
void set_clipbox_rasterizer( double *cliprect);
private:
- PathAgg *lastclippath;
+ Py::Object lastclippath;
agg::trans_affine lastclippath_transform;
};
@@ -253,7 +237,6 @@
: Py::ExtensionModule<_backend_agg_module>( "_backend_agg" )
{
RendererAgg::init_type();
- PathAgg::init_type();
add_keyword_method("RendererAgg", &_backend_agg_module::new_renderer,
"RendererAgg(width, height, dpi)");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-20 13:57:33
|
Revision: 3864
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3864&view=rev
Author: mdboom
Date: 2007-09-20 06:57:32 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
Simplification of marker paths.
Modified Paths:
--------------
branches/transforms/lib/matplotlib/lines.py
Modified: branches/transforms/lib/matplotlib/lines.py
===================================================================
--- branches/transforms/lib/matplotlib/lines.py 2007-09-20 13:50:27 UTC (rev 3863)
+++ branches/transforms/lib/matplotlib/lines.py 2007-09-20 13:57:32 UTC (rev 3864)
@@ -815,7 +815,7 @@
path, self.get_transform())
- _tickhoriz_path = Path([[0.0, 0.5], [1.0, 0.5]])
+ _tickhoriz_path = Path([[0.0, 0.5], [1.0, 0.5]], closed=False)
def _draw_tickleft(self, renderer, gc, path):
offset = renderer.points_to_pixels(self._markersize)
marker_transform = Affine2D().scale(-offset, 1.0)
@@ -830,7 +830,7 @@
path, self.get_transform())
- _tickvert_path = Path([[-0.5, 0.0], [-0.5, 1.0]])
+ _tickvert_path = Path([[-0.5, 0.0], [-0.5, 1.0]], closed=False)
def _draw_tickup(self, renderer, gc, path):
offset = renderer.points_to_pixels(self._markersize)
marker_transform = Affine2D().scale(1.0, offset)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2007-09-20 13:50:34
|
Revision: 3863
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3863&view=rev
Author: jdh2358
Date: 2007-09-20 06:50:27 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
added gradient bar example
Added Paths:
-----------
trunk/matplotlib/examples/gradient_bar.py
Added: trunk/matplotlib/examples/gradient_bar.py
===================================================================
--- trunk/matplotlib/examples/gradient_bar.py (rev 0)
+++ trunk/matplotlib/examples/gradient_bar.py 2007-09-20 13:50:27 UTC (rev 3863)
@@ -0,0 +1,26 @@
+from pylab import figure, show, nx, cm
+
+def gbar(ax, x, y, width=0.5, bottom=0):
+ X = [[.6, .6],[.7,.7]]
+ for left,top in zip(x, y):
+ right = left+width
+ ax.imshow(X, interpolation='bicubic', cmap=cm.Blues,
+ extent=(left, right, bottom, top), alpha=1)
+
+fig = figure()
+
+xmin, xmax = xlim = 0,10
+ymin, ymax = ylim = 0,1
+ax = fig.add_subplot(111, xlim=xlim, ylim=ylim,
+ autoscale_on=False)
+X = [[.6, .6],[.7,.7]]
+
+ax.imshow(X, interpolation='bicubic', cmap=cm.copper,
+ extent=(xmin, xmax, ymin, ymax), alpha=1)
+
+N = 10
+x = nx.arange(N)+0.25
+y = nx.mlab.rand(N)
+gbar(ax, x, y, width=0.7)
+ax.set_aspect('normal')
+show()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2007-09-20 12:40:43
|
Revision: 3862
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3862&view=rev
Author: mdboom
Date: 2007-09-20 05:40:41 -0700 (Thu, 20 Sep 2007)
Log Message:
-----------
Removing debugging output in last commit.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/font_manager.py
Modified: trunk/matplotlib/lib/matplotlib/font_manager.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/font_manager.py 2007-09-20 12:31:26 UTC (rev 3861)
+++ trunk/matplotlib/lib/matplotlib/font_manager.py 2007-09-20 12:40:41 UTC (rev 3862)
@@ -773,7 +773,6 @@
else:
if is_string_like(size):
parent_size = fontManager.get_default_size()
- print "parent_size", parent_size, size
scaling = font_scalings.get(size)
if scaling is not None:
size = parent_size * scaling
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|