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. |