From: <md...@us...> - 2009-09-01 14:06:43
|
Revision: 7625 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7625&view=rev Author: mdehoon Date: 2009-09-01 14:06:35 +0000 (Tue, 01 Sep 2009) Log Message: ----------- Adding calls to gc.restore() whenever new_gc is called. This is necessary for the Mac OS X and the Cairo backend to work correctly. Also, updating the Mac OS X backend to be consistent with recent changes in SVN. See issue 2844845 on sourceforge. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py trunk/matplotlib/lib/matplotlib/collections.py trunk/matplotlib/lib/matplotlib/figure.py trunk/matplotlib/lib/matplotlib/image.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2009-09-01 13:03:20 UTC (rev 7624) +++ trunk/matplotlib/lib/matplotlib/axes.py 2009-09-01 14:06:35 UTC (rev 7625) @@ -1749,6 +1749,7 @@ self.patch.get_transform())) renderer.draw_image(gc, round(l), round(b), im) + gc.restore() if dsu_rasterized: for zorder, i, a in dsu_rasterized: Modified: trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py 2009-09-01 13:03:20 UTC (rev 7624) +++ trunk/matplotlib/lib/matplotlib/backends/backend_macosx.py 2009-09-01 14:06:35 UTC (rev 7625) @@ -58,21 +58,42 @@ rgbFace = tuple(rgbFace) gc.draw_markers(marker_path, marker_trans, path, trans, rgbFace) - def draw_path_collection(self, *args): - # TODO: We should change this in the C code eventually, but this - # re-ordering of arguments should work for now - gc = args[0] - args = tuple([gc, args[1], gc.get_clip_rectangle()] + \ - list(gc.get_clip_path()) + list(args[2:])) - gc.draw_path_collection(*args) + def draw_path_collection(self, gc, master_transform, paths, all_transforms, + offsets, offsetTrans, facecolors, edgecolors, + linewidths, linestyles, antialiaseds, urls): + cliprect = gc.get_clip_rectangle() + clippath, clippath_transform = gc.get_clip_path() + gc.draw_path_collection(master_transform, + cliprect, + clippath, + clippath_transform, + paths, + all_transforms, + offsets, + offsetTrans, + facecolors, + edgecolors, + linewidths, + linestyles, + antialiaseds) - def draw_quad_mesh(self, *args): - # TODO: We should change this in the C code eventually, but this - # re-ordering of arguments should work for now - gc = args[0] - args = [gc, args[1], gc.get_clip_rectangle()] + \ - list(gc.get_clip_path()) + list(args[2:]) - gc.draw_quad_mesh(*args) + def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight, + coordinates, offsets, offsetTrans, facecolors, + antialiased, showedges): + cliprect = gc.get_clip_rectangle() + clippath, clippath_transform = gc.get_clip_path() + gc.draw_quad_mesh(master_transform, + cliprect, + clippath, + clippath_transform, + meshWidth, + meshHeight, + coordinates, + offsets, + offsetTrans, + facecolors, + antialiased, + showedges) def new_gc(self): self.gc.save() @@ -80,8 +101,6 @@ return self.gc def draw_image(self, gc, x, y, im): - # TODO: We should change this in the C code eventually, but this - # re-ordering of arguments should work for now im.flipud_out() nrows, ncols, data = im.as_rgba_str() gc.draw_image(x, y, nrows, ncols, data, gc.get_clip_rectangle(), Modified: trunk/matplotlib/lib/matplotlib/collections.py =================================================================== --- trunk/matplotlib/lib/matplotlib/collections.py 2009-09-01 13:03:20 UTC (rev 7624) +++ trunk/matplotlib/lib/matplotlib/collections.py 2009-09-01 14:06:35 UTC (rev 7625) @@ -214,6 +214,8 @@ gc, transform.frozen(), paths, self.get_transforms(), offsets, transOffset, self.get_facecolor(), self.get_edgecolor(), self._linewidths, self._linestyles, self._antialiaseds, self._urls) + + gc.restore() renderer.close_group(self.__class__.__name__) def contains(self, mouseevent): @@ -1223,6 +1225,7 @@ gc, transform.frozen(), self._meshWidth, self._meshHeight, coordinates, offsets, transOffset, self.get_facecolor(), self._antialiased, self._showedges) + gc.restore() renderer.close_group(self.__class__.__name__) Modified: trunk/matplotlib/lib/matplotlib/figure.py =================================================================== --- trunk/matplotlib/lib/matplotlib/figure.py 2009-09-01 13:03:20 UTC (rev 7624) +++ trunk/matplotlib/lib/matplotlib/figure.py 2009-09-01 14:06:35 UTC (rev 7625) @@ -766,6 +766,7 @@ gc.set_clip_rectangle(self.bbox) gc.set_clip_path(self.get_clip_path()) renderer.draw_image(gc, l, b, im) + gc.restore() # render the axes for a in self.axes: a.draw(renderer) Modified: trunk/matplotlib/lib/matplotlib/image.py =================================================================== --- trunk/matplotlib/lib/matplotlib/image.py 2009-09-01 13:03:20 UTC (rev 7624) +++ trunk/matplotlib/lib/matplotlib/image.py 2009-09-01 14:06:35 UTC (rev 7625) @@ -142,6 +142,7 @@ gc.set_clip_rectangle(self.axes.bbox.frozen()) gc.set_clip_path(self.get_clip_path()) renderer.draw_image(gc, l, b, im) + gc.restore() def contains(self, mouseevent): """ @@ -637,6 +638,7 @@ round(self.axes.bbox.xmin), round(self.axes.bbox.ymin), im) + gc.restore() def set_data(self, x, y, A): @@ -790,6 +792,7 @@ gc.set_clip_rectangle(self.figure.bbox) gc.set_clip_path(self.get_clip_path()) renderer.draw_image(gc, round(self.ox), round(self.oy), im) + gc.restore() def write_png(self, fname): """Write the image to png file with fname""" @@ -931,6 +934,7 @@ self._set_gc_clip(gc) #gc.set_clip_path(self.get_clip_path()) renderer.draw_image(gc, round(l), round(b), im) + gc.restore() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-09-06 21:16:40
|
Revision: 7661 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7661&view=rev Author: jdh2358 Date: 2009-09-06 21:16:27 +0000 (Sun, 06 Sep 2009) Log Message: ----------- fix to empty datetime bug; add datetime tests Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/axis.py trunk/matplotlib/lib/matplotlib/dates.py trunk/matplotlib/lib/matplotlib/transforms.py trunk/matplotlib/lib/matplotlib/units.py Added Paths: ----------- trunk/matplotlib/lib/matplotlib/tests/test_dates.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2009-09-06 20:13:36 UTC (rev 7660) +++ trunk/matplotlib/lib/matplotlib/axes.py 2009-09-06 21:16:27 UTC (rev 7661) @@ -2299,74 +2299,19 @@ *tz* is the time zone to use in labeling dates. Defaults to rc value. """ + # should be enough to inform the unit conversion interface + # dates are comng in + self.xaxis.update_units(datetime.date(2009,1,1)) - xmin, xmax = self.dataLim.intervalx - if xmin==0.: - # no data has been added - let's set the default datalim. - # We should probably use a better proxy for the datalim - # have been updated than the ignore setting - dmax = today = datetime.date.today() - dmin = today-datetime.timedelta(days=10) - self._process_unit_info(xdata=(dmin, dmax)) - dmin, dmax = self.convert_xunits([dmin, dmax]) - self.viewLim.intervalx = dmin, dmax - self.dataLim.intervalx = dmin, dmax - - locator = self.xaxis.get_major_locator() - if not isinstance(locator, mdates.DateLocator): - locator = mdates.AutoDateLocator(tz) - self.xaxis.set_major_locator(locator) - - # the autolocator uses the viewlim to pick the right date - # locator, but it may not have correct viewlim before an - # autoscale. If the viewlim is still zero..1, set it to the - # datalim and the autoscaler will update it on request - if self.viewLim.intervalx[0]==0.: - self.viewLim.intervalx = tuple(self.dataLim.intervalx) - locator.refresh() - - formatter = self.xaxis.get_major_formatter() - if not isinstance(formatter, mdates.DateFormatter): - formatter = mdates.AutoDateFormatter(locator, tz) - self.xaxis.set_major_formatter(formatter) - def yaxis_date(self, tz=None): """Sets up y-axis ticks and labels that treat the y data as dates. *tz* is the time zone to use in labeling dates. Defaults to rc value. """ - ymin, ymax = self.dataLim.intervaly - if ymin==0.: - # no data has been added - let's set the default datalim. - # We should probably use a better proxy for the datalim - # have been updated than the ignore setting - dmax = today = datetime.date.today() - dmin = today-datetime.timedelta(days=10) - self._process_unit_info(ydata=(dmin, dmax)) + # should be enough to inform the unit conversion interface + # dates are comng in + self.yaxis.update_units(datetime.date(2009,1,1)) - dmin, dmax = self.convert_yunits([dmin, dmax]) - self.viewLim.intervaly = dmin, dmax - self.dataLim.intervaly = dmin, dmax - - - locator = self.yaxis.get_major_locator() - if not isinstance(locator, mdates.DateLocator): - locator = mdates.AutoDateLocator(tz) - self.yaxis.set_major_locator(locator) - - # the autolocator uses the viewlim to pick the right date - # locator, but it may not have correct viewlim before an - # autoscale. If the viewlim is still zero..1, set it to the - # datalim and the autoscaler will update it on request - if self.viewLim.intervaly[0]==0.: - self.viewLim.intervaly = tuple(self.dataLim.intervaly) - locator.refresh() - - formatter = self.xaxis.get_major_formatter() - if not isinstance(formatter, mdates.DateFormatter): - formatter = mdates.AutoDateFormatter(locator, tz) - self.yaxis.set_major_formatter(formatter) - def format_xdata(self, x): """ Return *x* string formatted. This function will use the attribute Modified: trunk/matplotlib/lib/matplotlib/axis.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axis.py 2009-09-06 20:13:36 UTC (rev 7660) +++ trunk/matplotlib/lib/matplotlib/axis.py 2009-09-06 21:16:27 UTC (rev 7661) @@ -666,6 +666,19 @@ 'Set the axis data limits' raise NotImplementedError('Derived must override') + def set_default_intervals(self): + 'set the default limits for the axis data and view interval if they are not mutated' + + # this is mainly in support of custom object plotting. For + # example, if someone passes in a datetime object, we do not + # know automagically how to set the default min/max of the + # data and view limits. The unit conversion AxisInfo + # interface provides a hook for custom types to register + # default limits through the AxisInfo.default_limits + # attribute, and the derived code below will check for that + # and use it if is available (else just use 0..1) + pass + def _set_artist_props(self, a): if a is None: return a.set_figure(self.figure) @@ -1010,6 +1023,7 @@ self.set_label_text(info.label) self.isDefault_label = True + self.set_default_intervals() def have_units(self): return self.converter is not None or self.units is not None @@ -1420,6 +1434,25 @@ self.axes.dataLim.intervalx = min(vmin, Vmin), max(vmax, Vmax) + def set_default_intervals(self): + 'set the default limits for the axis interval if they are not mutated' + xmin, xmax = 0., 1. + dataMutated = self.axes.dataLim.mutatedx() + viewMutated = self.axes.viewLim.mutatedx() + if not dataMutated or not viewMutated: + if self.converter is not None: + info = self.converter.axisinfo(self.units, self) + if info.default_limits is not None: + valmin, valmax = info.default_limits + xmin = self.converter.convert(valmin, self.units, self) + xmax = self.converter.convert(valmax, self.units, self) + if not dataMutated: + self.axes.dataLim.intervalx = xmin, xmax + if not viewMutated: + self.axes.viewLim.intervalx = xmin, xmax + + + class YAxis(Axis): __name__ = 'yaxis' axis_name = 'y' @@ -1665,3 +1698,22 @@ else: Vmin, Vmax = self.get_data_interval() self.axes.dataLim.intervaly = min(vmin, Vmin), max(vmax, Vmax) + + def set_default_intervals(self): + 'set the default limits for the axis interval if they are not mutated' + ymin, ymax = 0., 1. + dataMutated = self.axes.dataLim.mutatedy() + viewMutated = self.axes.viewLim.mutatedy() + if not dataMutated or not viewMutated: + if self.converter is not None: + info = self.converter.axisinfo(self.units, self) + if info.default_limits is not None: + valmin, valmax = info.default_limits + ymin = self.converter.convert(valmin, self.units, self) + ymax = self.converter.convert(valmax, self.units, self) + if not dataMutated: + self.axes.dataLim.intervaly = ymin, ymax + if not viewMutated: + self.axes.viewLim.intervaly = ymin, ymax + + Modified: trunk/matplotlib/lib/matplotlib/dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dates.py 2009-09-06 20:13:36 UTC (rev 7660) +++ trunk/matplotlib/lib/matplotlib/dates.py 2009-09-06 21:16:27 UTC (rev 7661) @@ -1062,42 +1062,15 @@ def axisinfo(unit, axis): 'return the unit AxisInfo' # make sure that the axis does not start at 0 - if axis: - ax = axis.axes - if axis is ax.get_xaxis(): - xmin, xmax = ax.dataLim.intervalx - if xmin==0.: - # no data has been added - let's set the default datalim. - # We should probably use a better proxy for the datalim - # have been updated than the ignore setting - dmax = today = datetime.date.today() - dmin = today-datetime.timedelta(days=10) - - ax._process_unit_info(xdata=(dmin, dmax)) - dmin, dmax = ax.convert_xunits([dmin, dmax]) - - ax.viewLim.intervalx = dmin, dmax - ax.dataLim.intervalx = dmin, dmax - elif axis is ax.get_yaxis(): - ymin, ymax = ax.dataLim.intervaly - if ymin==0.: - # no data has been added - let's set the default datalim. - # We should probably use a better proxy for the datalim - # have been updated than the ignore setting - dmax = today = datetime.date.today() - dmin = today-datetime.timedelta(days=10) - - ax._process_unit_info(ydata=(dmin, dmax)) - dmin, dmax = ax.convert_yunits([dmin, dmax]) - - ax.viewLim.intervaly = dmin, dmax - ax.dataLim.intervaly = dmin, dmax - majloc = AutoDateLocator(tz=unit) majfmt = AutoDateFormatter(majloc, tz=unit) - return units.AxisInfo( majloc=majloc, majfmt=majfmt, label='' ) + datemin = datetime.date(2000, 1, 1) + datemax = datetime.date(2010, 1, 1) + return units.AxisInfo( majloc=majloc, majfmt=majfmt, label='', + default_limits=(datemin, datemax)) + @staticmethod def convert(value, unit, axis): if units.ConversionInterface.is_numlike(value): return value Added: trunk/matplotlib/lib/matplotlib/tests/test_dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/test_dates.py (rev 0) +++ trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2009-09-06 21:16:27 UTC (rev 7661) @@ -0,0 +1,76 @@ +import datetime +import numpy as np +import matplotlib +matplotlib.use('Agg') +from matplotlib.testing.decorators import image_comparison +import matplotlib.pyplot as plt + +@image_comparison(baseline_images=['empty_datetime.png']) +def test_empty_datetime(): + # make sure mpl does the right thing when told to plot dates even + # if no date data has been presented, cf + # http://sourceforge.net/tracker/?func=detail&aid=2850075&group_id=80706&atid=560720 + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.xaxis_date() + fig.savefig('empty_datetime.png') + +@image_comparison(baseline_images=['date_axhspan.png']) +def test_date_axhspan(): + # test ax hspan with date inputs + t0 = datetime.datetime(2009, 1, 20) + tf = datetime.datetime(2009, 1, 21) + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.axhspan( t0, tf, facecolor="blue", alpha=0.25 ) + ax.set_xlim(t0-datetime.timedelta(days=5), + tf+datetime.timedelta(days=5)) + fig.autofmt_xdate() + fig.savefig('date_axhspan.png') + +@image_comparison(baseline_images=['date_axvspan.png']) +def test_date_axvspan(): + # test ax hspan with date inputs + t0 = datetime.datetime(2000, 1, 20) + tf = datetime.datetime(2010, 1, 21) + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.axvspan( t0, tf, facecolor="blue", alpha=0.25 ) + ax.set_xlim(t0-datetime.timedelta(days=5), + tf+datetime.timedelta(days=5)) + fig.autofmt_xdate() + fig.savefig('date_axvspan.png') + + +@image_comparison(baseline_images=['date_axhline.png']) +def test_date_axhline(): + # test ax hline with date inputs + t0 = datetime.datetime(2009, 1, 20) + tf = datetime.datetime(2009, 1, 31) + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.axhline( t0, tf, facecolor="blue", lw=3) + ax.set_xlim(t0-datetime.timedelta(days=5), + tf+datetime.timedelta(days=5)) + fig.autofmt_xdate() + fig.savefig('date_axhline.png') + +@image_comparison(baseline_images=['date_axvline.png']) +def test_date_axvline(): + # test ax hline with date inputs + t0 = datetime.datetime(2000, 1, 20) + tf = datetime.datetime(2010, 1, 21) + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + ax.axvline( t0, tf, facecolor="blue", lw=3) + ax.set_xlim(t0-datetime.timedelta(days=5), + tf+datetime.timedelta(days=5)) + fig.autofmt_xdate() + fig.savefig('date_axvline.png') + + +if __name__=='__main__': + import nose + nose.runmodule(argv=['-s','--with-doctest'], exit=False) + + Modified: trunk/matplotlib/lib/matplotlib/transforms.py =================================================================== --- trunk/matplotlib/lib/matplotlib/transforms.py 2009-09-06 20:13:36 UTC (rev 7660) +++ trunk/matplotlib/lib/matplotlib/transforms.py 2009-09-06 21:16:27 UTC (rev 7661) @@ -711,7 +711,10 @@ self._points = np.asarray(points, np.float_) self._minpos = np.array([0.0000001, 0.0000001]) self._ignore = True - + # it is helpful in some contexts to know if the bbox is a + # default or has been mutated; we store the orig points to + # support the mutated methods + self._points_orig = self._points.copy() if DEBUG: ___init__ = __init__ def __init__(self, points): @@ -939,7 +942,22 @@ self._points = other.get_points() self.invalidate() + def mutated(self): + 'return whether the bbox has changed since init' + return self.mutatedx() or self.mutatedy() + def mutatedx(self): + 'return whether the x-limits have changed since init' + return (self._points[0,0]!=self._points_orig[0,0] or + self._points[1,0]!=self._points_orig[1,0]) + def mutatedy(self): + 'return whether the y-limits have changed since init' + return (self._points[0,1]!=self._points_orig[0,1] or + self._points[1,1]!=self._points_orig[1,1]) + + + + class TransformedBbox(BboxBase): """ A :class:`Bbox` that is automatically transformed by a given Modified: trunk/matplotlib/lib/matplotlib/units.py =================================================================== --- trunk/matplotlib/lib/matplotlib/units.py 2009-09-06 20:13:36 UTC (rev 7660) +++ trunk/matplotlib/lib/matplotlib/units.py 2009-09-06 21:16:27 UTC (rev 7661) @@ -46,14 +46,15 @@ from matplotlib.cbook import iterable, is_numlike, is_string_like class AxisInfo: - 'information to support default axis labeling and tick labeling' + 'information to support default axis labeling and tick labeling, and default limits' def __init__(self, majloc=None, minloc=None, - majfmt=None, minfmt=None, label=None): + majfmt=None, minfmt=None, label=None, + default_limits=None): """ majloc and minloc: TickLocators for the major and minor ticks majfmt and minfmt: TickFormatters for the major and minor ticks label: the default axis label - + default_limits: the default min, max of the axis if no data is present If any of the above are None, the axis will simply use the default """ self.majloc = majloc @@ -61,6 +62,7 @@ self.majfmt = majfmt self.minfmt = minfmt self.label = label + self.default_limits = default_limits class ConversionInterface: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <as...@us...> - 2009-09-07 00:25:19
|
Revision: 7669 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7669&view=rev Author: astraw Date: 2009-09-06 23:08:03 +0000 (Sun, 06 Sep 2009) Log Message: ----------- testing: enable test_dates Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/__init__.py trunk/matplotlib/lib/matplotlib/tests/test_dates.py Added Paths: ----------- trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/ trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axhline.png trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axhspan.png trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axvline.png trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axvspan.png trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_empty.png Modified: trunk/matplotlib/lib/matplotlib/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/__init__.py 2009-09-06 22:47:08 UTC (rev 7668) +++ trunk/matplotlib/lib/matplotlib/__init__.py 2009-09-06 23:08:03 UTC (rev 7669) @@ -880,6 +880,7 @@ 'matplotlib.tests.test_basic', 'matplotlib.tests.test_transforms', 'matplotlib.tests.test_axes', + 'matplotlib.tests.test_dates', 'matplotlib.tests.test_spines', ] Added: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axhline.png =================================================================== (Binary files differ) Property changes on: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axhline.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axhspan.png =================================================================== (Binary files differ) Property changes on: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axhspan.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axvline.png =================================================================== (Binary files differ) Property changes on: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axvline.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axvspan.png =================================================================== (Binary files differ) Property changes on: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axvspan.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_empty.png =================================================================== (Binary files differ) Property changes on: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_empty.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/matplotlib/lib/matplotlib/tests/test_dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2009-09-06 22:47:08 UTC (rev 7668) +++ trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2009-09-06 23:08:03 UTC (rev 7669) @@ -1,9 +1,9 @@ -import datetime +import datetime import numpy as np from matplotlib.testing.decorators import image_comparison import matplotlib.pyplot as plt -@image_comparison(baseline_images=['date_empty.png']) +@image_comparison(baseline_images=['date_empty']) def test_date_empty(): # make sure mpl does the right thing when told to plot dates even # if no date data has been presented, cf @@ -11,9 +11,9 @@ fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.xaxis_date() - fig.savefig('date_empty.png') + fig.savefig('date_empty') -@image_comparison(baseline_images=['date_axhspan.png']) +@image_comparison(baseline_images=['date_axhspan']) def test_date_axhspan(): # test ax hspan with date inputs t0 = datetime.datetime(2009, 1, 20) @@ -21,12 +21,12 @@ fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.axhspan( t0, tf, facecolor="blue", alpha=0.25 ) - ax.set_ylim(t0-datetime.timedelta(days=5), + ax.set_ylim(t0-datetime.timedelta(days=5), tf+datetime.timedelta(days=5)) fig.subplots_adjust(left=0.25) - fig.savefig('date_axhspan.png') + fig.savefig('date_axhspan') -@image_comparison(baseline_images=['date_axvspan.png']) +@image_comparison(baseline_images=['date_axvspan']) def test_date_axvspan(): # test ax hspan with date inputs t0 = datetime.datetime(2000, 1, 20) @@ -34,13 +34,13 @@ fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.axvspan( t0, tf, facecolor="blue", alpha=0.25 ) - ax.set_xlim(t0-datetime.timedelta(days=720), + ax.set_xlim(t0-datetime.timedelta(days=720), tf+datetime.timedelta(days=720)) fig.autofmt_xdate() - fig.savefig('date_axvspan.png') + fig.savefig('date_axvspan') -@image_comparison(baseline_images=['date_axhline.png']) +@image_comparison(baseline_images=['date_axhline']) def test_date_axhline(): # test ax hline with date inputs t0 = datetime.datetime(2009, 1, 20) @@ -48,12 +48,12 @@ fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.axhline( t0, color="blue", lw=3) - ax.set_ylim(t0-datetime.timedelta(days=5), + ax.set_ylim(t0-datetime.timedelta(days=5), tf+datetime.timedelta(days=5)) fig.subplots_adjust(left=0.25) - fig.savefig('date_axhline.png') + fig.savefig('date_axhline') -@image_comparison(baseline_images=['date_axvline.png']) +@image_comparison(baseline_images=['date_axvline']) def test_date_axvline(): # test ax hline with date inputs t0 = datetime.datetime(2000, 1, 20) @@ -61,15 +61,12 @@ fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.axvline( t0, color="red", lw=3) - ax.set_xlim(t0-datetime.timedelta(days=5), + ax.set_xlim(t0-datetime.timedelta(days=5), tf+datetime.timedelta(days=5)) fig.autofmt_xdate() - fig.savefig('date_axvline.png') + fig.savefig('date_axvline') if __name__=='__main__': import nose - nose.runmodule(argv=['-s','--with-doctest'], exit=False) - - - + nose.runmodule(argv=['-s','--with-doctest'], exit=False) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-09-07 18:42:49
|
Revision: 7676 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7676&view=rev Author: jdh2358 Date: 2009-09-07 18:42:41 +0000 (Mon, 07 Sep 2009) Log Message: ----------- raise if num ticks exceeds some threshold to address sf bug 2715172 Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/dates.py trunk/matplotlib/lib/matplotlib/tests/test_dates.py trunk/matplotlib/lib/matplotlib/ticker.py trunk/matplotlib/lib/matplotlib/transforms.py Modified: trunk/matplotlib/lib/matplotlib/dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dates.py 2009-09-07 17:18:44 UTC (rev 7675) +++ trunk/matplotlib/lib/matplotlib/dates.py 2009-09-07 18:42:41 UTC (rev 7676) @@ -522,6 +522,8 @@ self.rule.set(dtstart=start, until=stop) dates = self.rule.between(dmin, dmax, True) + if len(dates)>=ticker.Locator.MAXTICKS: + raise RuntimeError('RRuleLocator attempting to generate %d ticks from %s to %s: exceeds matplotlib.ticker.Locator.MAXTICKS'%(len(dates), dates[0], dates[-1])) return date2num(dates) def _get_unit(self): Modified: trunk/matplotlib/lib/matplotlib/tests/test_dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2009-09-07 17:18:44 UTC (rev 7675) +++ trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2009-09-07 18:42:41 UTC (rev 7676) @@ -1,6 +1,6 @@ import datetime import numpy as np -from matplotlib.testing.decorators import image_comparison +from matplotlib.testing.decorators import image_comparison, knownfailureif import matplotlib.pyplot as plt @image_comparison(baseline_images=['date_empty']) @@ -66,7 +66,10 @@ fig.autofmt_xdate() fig.savefig('date_axvline') -@image_comparison(baseline_images=['date_xlim_empty']) +# we want to test that this method raises a RuntimeError -- what is +# the rightway to do this in the current framework +@knownfailureif(True) +#@image_comparison(baseline_images=['date_xlim_empty']) def test_set_xlim_and_unexpected_handling(): # Attempt to test SF 2715172, see # https://sourceforge.net/tracker/?func=detail&aid=2715172&group_id=80706&atid=560720 @@ -80,7 +83,7 @@ ax.xaxis.set_major_locator(DayLocator()) ax.xaxis.set_major_formatter(DateFormatter("%m/%d/%y, %I:%M%p")) ax.xaxis.set_minor_locator(HourLocator()) - if 1: + if 0: # this seems to cause an ininite loop. from nose.plugins.skip import SkipTest raise SkipTest('avoiding never-ending drawing') Modified: trunk/matplotlib/lib/matplotlib/ticker.py =================================================================== --- trunk/matplotlib/lib/matplotlib/ticker.py 2009-09-07 17:18:44 UTC (rev 7675) +++ trunk/matplotlib/lib/matplotlib/ticker.py 2009-09-07 18:42:41 UTC (rev 7676) @@ -657,7 +657,14 @@ because the locator stores references to the Axis data and view limits """ - + + # some automatic tick locators can generate so many ticks they + # kill the machine when you try and render them, see eg sf bug + # report + # https://sourceforge.net/tracker/index.php?func=detail&aid=2715172&group_id=80706&atid=560720. + # This parameter is set to cause locators to raise an error if too + # many ticks are generated + MAXTICKS = 1000 def __call__(self): 'Return the locations of the ticks' raise NotImplementedError('Derived must override') Modified: trunk/matplotlib/lib/matplotlib/transforms.py =================================================================== --- trunk/matplotlib/lib/matplotlib/transforms.py 2009-09-07 17:18:44 UTC (rev 7675) +++ trunk/matplotlib/lib/matplotlib/transforms.py 2009-09-07 18:42:41 UTC (rev 7676) @@ -2266,6 +2266,7 @@ else: vmin -= expander*abs(vmin) vmax += expander*abs(vmax) + if swapped and not increasing: vmin, vmax = vmax, vmin return vmin, vmax This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-09-07 18:50:18
|
Revision: 7677 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7677&view=rev Author: jdh2358 Date: 2009-09-07 18:50:11 +0000 (Mon, 07 Sep 2009) Log Message: ----------- use the max tick limit for all tick locators Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/dates.py trunk/matplotlib/lib/matplotlib/ticker.py Modified: trunk/matplotlib/lib/matplotlib/dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dates.py 2009-09-07 18:42:41 UTC (rev 7676) +++ trunk/matplotlib/lib/matplotlib/dates.py 2009-09-07 18:50:11 UTC (rev 7677) @@ -522,9 +522,7 @@ self.rule.set(dtstart=start, until=stop) dates = self.rule.between(dmin, dmax, True) - if len(dates)>=ticker.Locator.MAXTICKS: - raise RuntimeError('RRuleLocator attempting to generate %d ticks from %s to %s: exceeds matplotlib.ticker.Locator.MAXTICKS'%(len(dates), dates[0], dates[-1])) - return date2num(dates) + return self.raise_if_exceeds(date2num(dates)) def _get_unit(self): """ Modified: trunk/matplotlib/lib/matplotlib/ticker.py =================================================================== --- trunk/matplotlib/lib/matplotlib/ticker.py 2009-09-07 18:42:41 UTC (rev 7676) +++ trunk/matplotlib/lib/matplotlib/ticker.py 2009-09-07 18:50:11 UTC (rev 7677) @@ -669,6 +669,13 @@ 'Return the locations of the ticks' raise NotImplementedError('Derived must override') + def raise_if_exceeds(self, locs): + 'raise a RuntimeError if Locator attempts to create more than MAXTICKS locs' + if len(locs)>=self.MAXTICKS: + raise RuntimeError('Locator attempting to generate %d ticks from %s to %s: exceeds Locator.MAXTICKS'%(len(locs), locs[0], locs[-1])) + + return locs + def view_limits(self, vmin, vmax): """ select a scale for the range from vmin to vmax @@ -728,7 +735,8 @@ def __call__(self): 'Return the locations of the ticks' dmin, dmax = self.axis.get_data_interval() - return np.arange(dmin + self.offset, dmax+1, self._base) + return self.raise_if_exceeds( + np.arange(dmin + self.offset, dmax+1, self._base)) class FixedLocator(Locator): @@ -758,7 +766,7 @@ ticks1 = self.locs[i::step] if np.absolute(ticks1).min() < np.absolute(ticks).min(): ticks = ticks1 - return ticks + return self.raise_if_exceeds(ticks) @@ -812,7 +820,7 @@ if self.numticks==0: return [] ticklocs = np.linspace(vmin, vmax, self.numticks) - return ticklocs + return self.raise_if_exceeds(ticklocs) def _set_numticks(self): @@ -900,7 +908,7 @@ base = self._base.get_base() n = (vmax - vmin + 0.001*base)//base locs = vmin + np.arange(n+1) * base - return locs + return self.raise_if_exceeds(locs) def view_limits(self, dmin, dmax): """ @@ -1010,7 +1018,7 @@ locs = locs[:-1] elif prune=='both': locs = locs[1:-1] - return locs + return self.raise_if_exceeds(locs) def view_limits(self, dmin, dmax): if self._symmetric: @@ -1106,7 +1114,7 @@ else: ticklocs = b**decades - return np.array(ticklocs) + return self.raise_if_exceeds(np.array(ticklocs)) def view_limits(self, vmin, vmax): 'Try to choose the view limits intelligently' @@ -1177,7 +1185,7 @@ ticklocs.extend(subs * (np.sign(decade) * b ** np.abs(decade))) else: ticklocs = np.sign(decades) * b ** np.abs(decades) - return np.array(ticklocs) + return self.raise_if_exceeds(np.array(ticklocs)) def view_limits(self, vmin, vmax): 'Try to choose the view limits intelligently' @@ -1241,7 +1249,7 @@ if vmin > vmax: vmin,vmax = vmax,vmin - return locs[(vmin < locs) & (locs < vmax)] + return self.raise_if_exceeds(locs[(vmin < locs) & (locs < vmax)]) class OldAutoLocator(Locator): @@ -1256,7 +1264,7 @@ def __call__(self): 'Return the locations of the ticks' self.refresh() - return self._locator() + return self.raise_if_exceeds(self._locator()) def refresh(self): 'refresh internal information based on current lim' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-09-07 19:19:32
|
Revision: 7678 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7678&view=rev Author: jdh2358 Date: 2009-09-07 19:19:23 +0000 (Mon, 07 Sep 2009) Log Message: ----------- fix test_dates to chek for RuntimeError on identical date lim test Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/tests/test_dates.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2009-09-07 18:50:11 UTC (rev 7677) +++ trunk/matplotlib/lib/matplotlib/axes.py 2009-09-07 19:19:23 UTC (rev 7678) @@ -2033,6 +2033,8 @@ if xmin is None: xmin = old_xmin if xmax is None: xmax = old_xmax + if xmin==xmax: + warnings.warn('Attempting to set identical xmin==xmax results in singular transformations; automatically expanding. xmin=%s, xmax=%s'%(xmin, xmax)) xmin, xmax = mtransforms.nonsingular(xmin, xmax, increasing=False) xmin, xmax = self.xaxis.limit_range_for_scale(xmin, xmax) @@ -2205,6 +2207,9 @@ if ymin is None: ymin = old_ymin if ymax is None: ymax = old_ymax + if ymin==ymax: + warnings.warn('Attempting to set identical ymin==ymax results in singular transformations; automatically expanding. ymin=%s, ymax=%s'%(ymin, ymax)) + ymin, ymax = mtransforms.nonsingular(ymin, ymax, increasing=False) ymin, ymax = self.yaxis.limit_range_for_scale(ymin, ymax) self.viewLim.intervaly = (ymin, ymax) Modified: trunk/matplotlib/lib/matplotlib/tests/test_dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2009-09-07 18:50:11 UTC (rev 7677) +++ trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2009-09-07 19:19:23 UTC (rev 7678) @@ -2,6 +2,7 @@ import numpy as np from matplotlib.testing.decorators import image_comparison, knownfailureif import matplotlib.pyplot as plt +from nose.tools import assert_raises @image_comparison(baseline_images=['date_empty']) def test_date_empty(): @@ -66,13 +67,12 @@ fig.autofmt_xdate() fig.savefig('date_axvline') -# we want to test that this method raises a RuntimeError -- what is -# the rightway to do this in the current framework -@knownfailureif(True) -#@image_comparison(baseline_images=['date_xlim_empty']) -def test_set_xlim_and_unexpected_handling(): +def test_too_many_date_ticks(): # Attempt to test SF 2715172, see # https://sourceforge.net/tracker/?func=detail&aid=2715172&group_id=80706&atid=560720 + # setting equal datetimes triggers and expander call in + # transforms.nonsingular which results in too many ticks in the + # DayLocator. This should trigger a Locator.MAXTICKS RuntimeError t0 = datetime.datetime(2000, 1, 20) tf = datetime.datetime(2000, 1, 20) fig = plt.figure() @@ -81,13 +81,7 @@ ax.plot([],[]) from matplotlib.dates import DayLocator, DateFormatter, HourLocator ax.xaxis.set_major_locator(DayLocator()) - ax.xaxis.set_major_formatter(DateFormatter("%m/%d/%y, %I:%M%p")) - ax.xaxis.set_minor_locator(HourLocator()) - if 0: - # this seems to cause an ininite loop. - from nose.plugins.skip import SkipTest - raise SkipTest('avoiding never-ending drawing') - fig.savefig('date_xlim_empty') + assert_raises(RuntimeError, fig.savefig, 'junk.png') if __name__=='__main__': import nose This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <as...@us...> - 2009-09-10 22:32:15
|
Revision: 7733 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7733&view=rev Author: astraw Date: 2009-09-10 22:32:08 +0000 (Thu, 10 Sep 2009) Log Message: ----------- testing: add test for SF#2856495 Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/__init__.py Added Paths: ----------- trunk/matplotlib/lib/matplotlib/tests/test_backend_svg.py Modified: trunk/matplotlib/lib/matplotlib/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/__init__.py 2009-09-10 11:39:23 UTC (rev 7732) +++ trunk/matplotlib/lib/matplotlib/__init__.py 2009-09-10 22:32:08 UTC (rev 7733) @@ -878,6 +878,7 @@ default_test_modules = [ 'matplotlib.tests.test_agg', + 'matplotlib.tests.test_backend_svg', 'matplotlib.tests.test_basic', 'matplotlib.tests.test_cbook', 'matplotlib.tests.test_transforms', Added: trunk/matplotlib/lib/matplotlib/tests/test_backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/test_backend_svg.py (rev 0) +++ trunk/matplotlib/lib/matplotlib/tests/test_backend_svg.py 2009-09-10 22:32:08 UTC (rev 7733) @@ -0,0 +1,30 @@ +import matplotlib.pyplot as plt +import numpy as np +import cStringIO as StringIO +import xml.parsers.expat +from matplotlib.testing.decorators import knownfailureif + +@knownfailureif(True) +def test_visibility(): + # This is SF 2856495. See + # https://sourceforge.net/tracker/?func=detail&aid=2856495&group_id=80706&atid=560720 + fig=plt.figure() + ax=fig.add_subplot(1,1,1) + + x = np.linspace(0,4*np.pi,50) + y = np.sin(x) + yerr = np.ones_like(y) + + a,b,c=ax.errorbar(x,y,yerr=yerr,fmt='ko') + for artist in b: + artist.set_visible(False) + + fd = StringIO.StringIO() + fig.savefig(fd,format='svg') + + fd.seek(0) + buf = fd.read() + fd.close() + + parser = xml.parsers.expat.ParserCreate() + parser.Parse(buf) # this will raise ExpatError if the svg is invalid This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2009-09-11 20:58:34
|
Revision: 7746 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7746&view=rev Author: sameerd Date: 2009-09-11 20:58:27 +0000 (Fri, 11 Sep 2009) Log Message: ----------- Added a recs_join function to join a single column of multiple record arrays Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/cbook.py trunk/matplotlib/lib/matplotlib/mlab.py Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2009-09-11 20:48:10 UTC (rev 7745) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2009-09-11 20:58:27 UTC (rev 7746) @@ -1626,7 +1626,48 @@ import matplotlib.mlab as mlab return mlab.quad2cubic(q0x, q0y, q1x, q1y, q2x, q2y) +def align_iterators(func, *iterables): + """ + This generator takes a bunch of iterables that are ordered by func + It sends out ordered tuples (func(row), [rows from all iterators matching func(row)]) + + It is used by mlab.recs_join to join record arrays + """ + class myiter: + def __init__(self, it): + self.it = it + self.key = self.value = None + self.iternext() + def iternext(self): + try: + self.value = self.it.next() + self.key = func(self.value) + except StopIteration: + self.value = self.key = None + + def __call__(self, key): + retval = None + if key == self.key: + retval = self.value + self.iternext() + elif self.key and key > self.key: + raise ValueError, "Iterator has been left behind" + return retval + + # This can be made more efficient by not computing the minimum key for each iteration + iters = [myiter(it) for it in iterables] + minvals = minkey = True + while 1: + minvals = (filter(None, [it.key for it in iters])) + if minvals: + minkey = min(minvals) + yield (minkey, [it(minkey) for it in iters]) + else: + break + + + if __name__=='__main__': assert( allequal([1,1,1]) ) assert(not allequal([1,1,0]) ) Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2009-09-11 20:48:10 UTC (rev 7745) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2009-09-11 20:58:27 UTC (rev 7746) @@ -91,6 +91,9 @@ :meth:`rec_join` join two record arrays on sequence of fields +:meth:`recs_join` + a simple join of multiple recarrays using a single column as a key + :meth:`rec_groupby` summarize data by groups (similar to SQL GROUP BY) @@ -139,7 +142,7 @@ """ from __future__ import division -import csv, warnings, copy, os +import csv, warnings, copy, os, operator import numpy as np ma = np.ma @@ -1880,7 +1883,29 @@ return newrec +def recs_join(key, name, recs,missing=0.): + """ + *key* is the column name that acts as a key + *name* is the name that we want to join + *missing" is what the missing fields are replaced by + *recarrays* is a list of record arrays to join + returns a record array with columns [rowkey, name1, name2, ... namen] + + >>> r = recs_join("date", "close", recs=[r0, r1], missing=0.) + + """ + results = [] + def extract(r): + if r is None: return missing + else: return r[name] + + for rowkey, row in cbook.align_iterators(operator.attrgetter(key), *[iter(r) for r in recs]): + results.append([rowkey] + map(extract, row)) + names = ",".join([key] + ["%s%d" % (name, d) for d in range(len(recs))]) + return np.rec.fromrecords(results, names=names) + + def csv2rec(fname, comments='#', skiprows=0, checkrows=0, delimiter=',', converterd=None, names=None, missing='', missingd=None, use_mrecords=False): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-09-20 22:10:16
|
Revision: 7802 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7802&view=rev Author: jdh2358 Date: 2009-09-20 22:10:07 +0000 (Sun, 20 Sep 2009) Log Message: ----------- some unit cleanup; warn on zero value dates in the formatter Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/__init__.py trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/axis.py trunk/matplotlib/lib/matplotlib/cbook.py trunk/matplotlib/lib/matplotlib/dates.py Modified: trunk/matplotlib/lib/matplotlib/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/__init__.py 2009-09-20 19:51:44 UTC (rev 7801) +++ trunk/matplotlib/lib/matplotlib/__init__.py 2009-09-20 22:10:07 UTC (rev 7802) @@ -900,7 +900,7 @@ backend = rcParams['backend'] original_params = rcParams.copy() - use('Agg') # use Agg backend for these tests + use('Agg', warn=False) # use Agg backend for these tests # These settings *must* be hardcoded for running the comparison # tests and are not necessarily the default values as specified in @@ -922,7 +922,7 @@ ) # restore the old backend and rcParams - use(backend) + use(backend, warn=False) rcParams.update(original_params) return success Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2009-09-20 19:51:44 UTC (rev 7801) +++ trunk/matplotlib/lib/matplotlib/axes.py 2009-09-20 22:10:07 UTC (rev 7802) @@ -2306,16 +2306,14 @@ """ # should be enough to inform the unit conversion interface # dates are comng in - self.xaxis.update_units(datetime.date(2009,1,1)) + self.xaxis.axis_date() def yaxis_date(self, tz=None): """Sets up y-axis ticks and labels that treat the y data as dates. *tz* is the time zone to use in labeling dates. Defaults to rc value. """ - # should be enough to inform the unit conversion interface - # dates are comng in - self.yaxis.update_units(datetime.date(2009,1,1)) + self.yaxis.axis_date() def format_xdata(self, x): """ Modified: trunk/matplotlib/lib/matplotlib/axis.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axis.py 2009-09-20 19:51:44 UTC (rev 7801) +++ trunk/matplotlib/lib/matplotlib/axis.py 2009-09-20 22:10:07 UTC (rev 7802) @@ -987,12 +987,17 @@ converter = munits.registry.get_converter(data) if converter is None: return False + + neednew = self.converter!=converter self.converter = converter default = self.converter.default_units(data, self) #print 'update units: default="%s", units=%s"'%(default, self.units) if default is not None and self.units is None: self.set_units(default) - self._update_axisinfo() + + + if neednew: + self._update_axisinfo() return True def _update_axisinfo(self): @@ -1196,6 +1201,17 @@ "Zoom in/out on axis; if *direction* is >0 zoom in, else zoom out" self.major.locator.zoom(direction) + + def axis_date(self): + """ + Sets up x-axis ticks and labels that treat the x data as dates. + """ + import datetime + # should be enough to inform the unit conversion interface + # dates are comng in + self.update_units(datetime.date(2009,1,1)) + + class XAxis(Axis): __name__ = 'xaxis' axis_name = 'x' @@ -1442,7 +1458,7 @@ if not dataMutated or not viewMutated: if self.converter is not None: info = self.converter.axisinfo(self.units, self) - if info.default_limits is not None: + if info.default_limits is not None: valmin, valmax = info.default_limits xmin = self.converter.convert(valmin, self.units, self) xmax = self.converter.convert(valmax, self.units, self) @@ -1451,8 +1467,8 @@ if not viewMutated: self.axes.viewLim.intervalx = xmin, xmax - + class YAxis(Axis): __name__ = 'yaxis' axis_name = 'y' @@ -1707,7 +1723,7 @@ if not dataMutated or not viewMutated: if self.converter is not None: info = self.converter.axisinfo(self.units, self) - if info.default_limits is not None: + if info.default_limits is not None: valmin, valmax = info.default_limits ymin = self.converter.convert(valmin, self.units, self) ymax = self.converter.convert(valmax, self.units, self) @@ -1716,4 +1732,4 @@ if not viewMutated: self.axes.viewLim.intervaly = ymin, ymax - + Modified: trunk/matplotlib/lib/matplotlib/cbook.py =================================================================== --- trunk/matplotlib/lib/matplotlib/cbook.py 2009-09-20 19:51:44 UTC (rev 7801) +++ trunk/matplotlib/lib/matplotlib/cbook.py 2009-09-20 22:10:07 UTC (rev 7802) @@ -317,7 +317,7 @@ def is_numlike(obj): 'return true if *obj* looks like a number' try: obj+1 - except TypeError: return False + except: return False else: return True def to_filehandle(fname, flag='rU', return_opened=False): Modified: trunk/matplotlib/lib/matplotlib/dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dates.py 2009-09-20 19:51:44 UTC (rev 7801) +++ trunk/matplotlib/lib/matplotlib/dates.py 2009-09-20 22:10:07 UTC (rev 7802) @@ -290,6 +290,8 @@ self.tz = tz def __call__(self, x, pos=0): + if x==0: + raise ValueError('DateFormatter found a value of x=0, which is an illegal date. This usually occurs because you have not informed the axis that it is plotting dates, eg with ax.xaxis_date()') dt = num2date(x, self.tz) return self.strftime(dt, self.fmt) @@ -430,6 +432,7 @@ } def __call__(self, x, pos=0): + scale = float( self._locator._get_unit() ) fmt = self.defaultfmt @@ -1065,10 +1068,10 @@ majloc = AutoDateLocator(tz=unit) majfmt = AutoDateFormatter(majloc, tz=unit) - datemin = datetime.date(2000, 1, 1) - datemax = datetime.date(2010, 1, 1) + datemin = datetime.date(2000, 1, 1) + datemax = datetime.date(2010, 1, 1) - return units.AxisInfo( majloc=majloc, majfmt=majfmt, label='', + return units.AxisInfo( majloc=majloc, majfmt=majfmt, label='', default_limits=(datemin, datemax)) @staticmethod This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2009-10-02 19:19:34
|
Revision: 7841 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7841&view=rev Author: leejjoon Date: 2009-10-02 18:58:20 +0000 (Fri, 02 Oct 2009) Log Message: ----------- add framon option for legend Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/legend.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2009-10-01 16:12:04 UTC (rev 7840) +++ trunk/matplotlib/lib/matplotlib/axes.py 2009-10-02 18:58:20 UTC (rev 7841) @@ -3925,6 +3925,9 @@ The relative size of legend markers vs. original. If *None*, use rc settings. + *frameon*: [ True | False ] + if True, draw a frame. Default is True + *fancybox*: [ None | False | True ] if True, draw a frame with a round fancybox. If None, use rc Modified: trunk/matplotlib/lib/matplotlib/legend.py =================================================================== --- trunk/matplotlib/lib/matplotlib/legend.py 2009-10-01 16:12:04 UTC (rev 7840) +++ trunk/matplotlib/lib/matplotlib/legend.py 2009-10-02 18:58:20 UTC (rev 7841) @@ -115,6 +115,7 @@ title = None, # set a title for the legend bbox_to_anchor = None, # bbox that the legend will be anchored. bbox_transform = None, # transform for the bbox + frameon = True, # draw frame ): """ - *parent* : the artist that contains the legend @@ -132,6 +133,7 @@ numpoints the number of points in the legend for line scatterpoints the number of points in the legend for scatter plot scatteryoffsets a list of yoffsets for scatter symbols in legend + frameon if True, draw a frame (default is True) fancybox if True, draw a frame with a round fancybox. If None, use rc shadow if True, draw a shadow behind legend ncol number of columns @@ -303,7 +305,7 @@ self._set_artist_props(self.legendPatch) - self._drawFrame = True + self._drawFrame = frameon # init with null renderer self._init_legend_box(handles, labels) @@ -687,7 +689,7 @@ def draw_frame(self, b): 'b is a boolean. Set draw frame to b' - self._drawFrame = b + self.set_frame_on(b) def get_children(self): 'return a list of child artists' @@ -737,6 +739,20 @@ return self.legendPatch.get_window_extent() + def get_frame_on(self): + """ + Get whether the legend box patch is drawn + """ + return self._drawFrame + + def set_frame_on(self, b): + """ + Set whether the legend box patch is drawn + + ACCEPTS: [ *True* | *False* ] + """ + self._drawFrame = b + def get_bbox_to_anchor(self): """ return the bbox that the legend will be anchored This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2009-10-12 13:30:49
|
Revision: 7875 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7875&view=rev Author: mdboom Date: 2009-10-12 13:30:32 +0000 (Mon, 12 Oct 2009) Log Message: ----------- Add SVG tests. Fix a hatching bug found in the process of this. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/__init__.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/testing/compare.py trunk/matplotlib/lib/matplotlib/testing/decorators.py trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/shaped_data.pdf trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/shaped_data.png trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_simplification/hatch_simplify.pdf trunk/matplotlib/lib/matplotlib/tests/test_axes.py Added Paths: ----------- trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/axhspan_epoch.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/axvspan_epoch.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/const_xy.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/fill_units.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/formatter_ticker_001.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/formatter_ticker_002.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/formatter_ticker_003.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/formatter_ticker_004.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/formatter_ticker_005.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/hexbin_extent.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/nonfinite_limits.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/offset_points.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/polar_axes.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/polar_coords.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/polar_units.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/polar_wrap_180.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/polar_wrap_360.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/shaped data.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/shaped_data.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/single_date.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/single_point.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/DateFormatter_fractionalSeconds.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/RRuleLocator_bounds.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axhline.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axhspan.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axvline.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_axvspan.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_dates/date_empty.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_image/image_interps.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_simplification/clipping.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_simplification/clipping_diamond.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_simplification/hatch_simplify.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_simplification/overflow.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_simplification/simplify_curve.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_spines/spines_axes_positions.svg Modified: trunk/matplotlib/lib/matplotlib/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/__init__.py 2009-10-12 13:21:07 UTC (rev 7874) +++ trunk/matplotlib/lib/matplotlib/__init__.py 2009-10-12 13:30:32 UTC (rev 7875) @@ -301,6 +301,30 @@ except (IndexError, ValueError, UnboundLocalError, OSError): return None +def checkdep_inkscape(): + try: + s = subprocess.Popen(['inkscape','-V'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + for line in s.stdout: + if 'Inkscape' in line: + v = line.split()[1] + break + return v + except (IndexError, ValueError, UnboundLocalError, OSError): + return None + +def checkdep_xmllint(): + try: + s = subprocess.Popen(['xmllint','--version'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + for line in s.stderr: + if 'version' in line: + v = line.split()[-1] + break + return v + except (IndexError, ValueError, UnboundLocalError, OSError): + return None + def compare_versions(a, b): "return True if a is greater than or equal to b" if a: Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-10-12 13:21:07 UTC (rev 7874) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-10-12 13:30:32 UTC (rev 7875) @@ -1344,7 +1344,7 @@ def draw_path(self, gc, path, transform, rgbFace=None): self.check_gc(gc, rgbFace) - self.file.writePath(path, transform, rgbFace is None) + self.file.writePath(path, transform, (rgbFace is None and gc.get_hatch_path() is None)) self.file.output(self.gc.paint()) def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-10-12 13:21:07 UTC (rev 7874) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-10-12 13:30:32 UTC (rev 7875) @@ -471,7 +471,9 @@ """ Draws a Path instance using the given affine transform. """ - ps = self._convert_path(path, transform, clip=(rgbFace is None)) + ps = self._convert_path( + path, transform, + clip=(rgbFace is None and gc.get_hatch_path() is None)) self._draw_ps(ps, gc, rgbFace) def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2009-10-12 13:21:07 UTC (rev 7874) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2009-10-12 13:30:32 UTC (rev 7875) @@ -61,7 +61,7 @@ RendererBase.__init__(self) self._glyph_map = dict() - + svgwriter.write(svgProlog%(width,height,width,height)) def _draw_svg_element(self, element, details, gc, rgbFace): @@ -241,7 +241,8 @@ def draw_path(self, gc, path, transform, rgbFace=None): trans_and_flip = self._make_flip_transform(transform) - path_data = self._convert_path(path, trans_and_flip, clip=(rgbFace is None)) + path_data = self._convert_path(path, trans_and_flip, + clip=(rgbFace is None and gc.get_hatch_path() is None)) self._draw_svg_element('path', 'd="%s"' % path_data, gc, rgbFace) def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): @@ -412,7 +413,7 @@ def _adjust_char_id(self, char_id): return char_id.replace("%20","_") - + def draw_text_as_path(self, gc, x, y, s, prop, angle, ismath): """ draw the text by converting them to paths using textpath module. @@ -422,26 +423,26 @@ *s* text to be converted - + *usetex* If True, use matplotlib usetex mode. *ismath* If True, use mathtext parser. If "TeX", use *usetex* mode. - + """ # this method works for normal text, mathtext and usetex mode. # But currently only utilized by draw_tex method. - + glyph_map=self._glyph_map - + text2path = self._text2path color = rgb2hex(gc.get_rgb()[:3]) fontsize = prop.get_size_in_points() write = self._svgwriter.write - + if ismath == False: font = text2path._get_font(prop) _glyphs = text2path.get_glyphs_with_font(font, s, glyph_map=glyph_map, @@ -460,7 +461,7 @@ write('</defs>\n') glyph_map.update(glyph_map_new) - + svg = [] clipid = self._get_gc_clip_svg(gc) if clipid is not None: @@ -508,7 +509,7 @@ write('</defs>\n') glyph_map.update(glyph_map_new) - + svg = [] clipid = self._get_gc_clip_svg(gc) if clipid is not None: @@ -800,7 +801,7 @@ w, h, d = texmanager.get_text_width_height_descent(s, fontsize, renderer=self) return w, h, d - + if ismath: width, height, descent, trash, used_characters = \ self.mathtext_parser.parse(s, 72, prop) Modified: trunk/matplotlib/lib/matplotlib/testing/compare.py =================================================================== --- trunk/matplotlib/lib/matplotlib/testing/compare.py 2009-10-12 13:21:07 UTC (rev 7874) +++ trunk/matplotlib/lib/matplotlib/testing/compare.py 2009-10-12 13:30:32 UTC (rev 7875) @@ -95,23 +95,32 @@ converter['pdf'] = cmd converter['eps'] = cmd +if matplotlib.checkdep_inkscape() is not None: + cmd = lambda old, new: \ + ['inkscape', old, '--export-png=' + new] + converter['svg'] = cmd + def comparable_formats(): '''Returns the list of file formats that compare_images can compare on this system.''' return ['png'] + converter.keys() def convert(filename): - '''Convert the named file into a png file. + ''' + Convert the named file into a png file. Returns the name of the created file. ''' base, extension = filename.rsplit('.', 1) if extension not in converter: raise ImageComparisonFailure, "Don't know how to convert %s files to png" % extension newname = base + '_' + extension + '.png' + if not os.path.exists(filename): + raise IOError, "'%s' does not exist" % filename cmd = converter[extension](filename, newname) pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = pipe.communicate() - if not os.path.exists(newname): + errcode = pipe.wait() + if not os.path.exists(newname) or errcode: msg = "Conversion command failed:\n%s\n" % ' '.join(cmd) if stdout: msg += "Standard output:\n%s\n" % stdout @@ -120,6 +129,33 @@ raise IOError, msg return newname +verifiers = { } + +def verify(filename): + """ + Verify the file through some sort of verification tool. + """ + if not os.path.exists(filename): + raise IOError, "'%s' does not exist" % filename + base, extension = filename.rsplit('.', 1) + verifier = verifiers.get(extension, None) + if verifier is not None: + cmd = verifier(filename) + pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = pipe.communicate() + errcode = pipe.wait() + if errcode != 0: + msg = "File verification command failed:\n%s\n" % ' '.join(cmd) + if stdout: + msg += "Standard output:\n%s\n" % stdout + if stderr: + msg += "Standard error:\n%s\n" % stderr + raise IOError, msg + +if matplotlib.checkdep_xmllint(): + verifiers['svg'] = lambda filename: [ + 'xmllint', '--valid', '--nowarning', '--noout', filename] + def compare_images( expected, actual, tol, in_decorator=False ): '''Compare two image files - not the greatest, but fast and good enough. @@ -134,7 +170,7 @@ - expected The filename of the expected image. - actual The filename of the actual image. - tol The tolerance (a unitless float). This is used to - determinte the 'fuzziness' to use when comparing images. + determine the 'fuzziness' to use when comparing images. - in_decorator If called from image_comparison decorator, this should be True. (default=False) ''' @@ -151,10 +187,12 @@ else: return msg + verify(actual) + # Convert the image to png extension = expected.split('.')[-1] if extension != 'png': - expected, actual = convert(expected), convert(actual) + actual, expected = convert(actual), convert(expected) # open the image files and remove the alpha channel (if it exists) expectedImage = Image.open( expected ).convert("RGB") Modified: trunk/matplotlib/lib/matplotlib/testing/decorators.py =================================================================== --- trunk/matplotlib/lib/matplotlib/testing/decorators.py 2009-10-12 13:21:07 UTC (rev 7874) +++ trunk/matplotlib/lib/matplotlib/testing/decorators.py 2009-10-12 13:30:32 UTC (rev 7875) @@ -74,7 +74,7 @@ if extensions is None: # default extensions to test - extensions = ['png', 'pdf'] + extensions = ['png', 'pdf', 'svg'] # The multiple layers of defs are required because of how # parameterized decorators work, and because we want to turn the Added: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/axhspan_epoch.svg =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/axhspan_epoch.svg (rev 0) +++ trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/axhspan_epoch.svg 2009-10-12 13:30:32 UTC (rev 7875) @@ -0,0 +1,322 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.sourceforge.net/) --> +<svg width="576pt" height="432pt" viewBox="0 0 576 432" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + version="1.1" + id="svg1"> +<filter id="colorAdd"><feComposite in="SourceGraphic" in2="BackgroundImage" operator="arithmetic" k2="1" k3="1"/></filter> +<g id="figure1"> +<g id="patch1"> +<path style="fill: #ffffff; stroke: #ffffff; stroke-width: 1.000000; stroke-linejoin: round; stroke-linecap: square; opacity: 1.000000" d="M0.000000 432.000000L576.000000 432.000000L576.000000 0.000000 +L0.000000 0.000000L0.000000 432.000000"/> +</g> +<g id="axes1"> +<g id="patch2"> +<path style="fill: #ffffff; opacity: 1.000000" d="M72.000000 388.800000L518.400000 388.800000L518.400000 43.200000 +L72.000000 43.200000L72.000000 388.800000"/> +</g> +<g id="patch3"> +<defs> + <clipPath id="p50431ccdcb28178602d99d9270004dde"> +<rect x="72.000000" y="43.200000" width="446.400000" height="345.600000"/> + </clipPath> +</defs><path style="fill: #0000ff; stroke: #000000; stroke-width: 1.000000; stroke-linejoin: round; stroke-linecap: square; opacity: 0.250000" clip-path="url(#p50431ccdcb28178602d99d9270004dde)" d="M72.000000 231.709091L72.000000 200.290909L518.400000 200.290909 +L518.400000 231.709091L72.000000 231.709091"/> +</g> +<g id="matplotlib.axis1"> +<g id="xtick1"> +<g id="line2d1"> +<defs><path id="m30e32995789d870ad79a2e54c91cf9c6" d="M0.000000 0.000000L0.000000 -4.000000"/></defs> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="72.000000" y="388.800000"/> +</g></g> +<g id="line2d2"> +<defs><path id="m9281cae24120827b11d5ea8a7ad3e96b" d="M0.000000 0.000000L0.000000 4.000000"/></defs> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="72.000000" y="43.200000"/> +</g></g> +<g id="text1"> +<defs> +<path id="c_7a2040fe3b94fcd41d0a72c84e93b115" d="M31.781250 -66.406250q-7.609375 0.000000 -11.453125 7.500000q-3.828125 7.484375 -3.828125 22.531250q0.000000 14.984375 3.828125 22.484375q3.843750 7.500000 11.453125 7.500000q7.671875 0.000000 11.500000 -7.500000q3.843750 -7.500000 3.843750 -22.484375q0.000000 -15.046875 -3.843750 -22.531250q-3.828125 -7.500000 -11.500000 -7.500000M31.781250 -74.218750q12.265625 0.000000 18.734375 9.703125q6.468750 9.687500 6.468750 28.140625q0.000000 18.406250 -6.468750 28.109375q-6.468750 9.687500 -18.734375 9.687500q-12.250000 0.000000 -18.718750 -9.687500q-6.468750 -9.703125 -6.468750 -28.109375q0.000000 -18.453125 6.468750 -28.140625q6.468750 -9.703125 18.718750 -9.703125"/> +<path id="c_ed3e21196fb739f392806f09ca0594ef" d="M10.687500 -12.406250l10.312500 0.000000l0.000000 12.406250l-10.312500 0.000000z"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(63.250000,401.706250)scale(0.120000)"> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115"/> +<use xlink:href="#c_ed3e21196fb739f392806f09ca0594ef" x="63.623047"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="95.410156"/> +</g> +</g> +</g> +<g id="xtick2"> +<g id="line2d3"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="161.280000" y="388.800000"/> +</g></g> +<g id="line2d4"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="161.280000" y="43.200000"/> +</g></g> +<g id="text2"> +<defs> +<path id="c_ed3f3ed3ebfbd18bcb9c012009a68ad1" d="M19.187500 -8.296875l34.421875 0.000000l0.000000 8.296875l-46.281250 0.000000l0.000000 -8.296875q5.609375 -5.812500 15.296875 -15.593750q9.703125 -9.796875 12.187500 -12.640625q4.734375 -5.312500 6.609375 -9.000000q1.890625 -3.687500 1.890625 -7.250000q0.000000 -5.812500 -4.078125 -9.468750q-4.078125 -3.671875 -10.625000 -3.671875q-4.640625 0.000000 -9.796875 1.609375q-5.140625 1.609375 -11.000000 4.890625l0.000000 -9.968750q5.953125 -2.390625 11.125000 -3.609375q5.187500 -1.218750 9.484375 -1.218750q11.328125 0.000000 18.062500 5.671875q6.734375 5.656250 6.734375 15.125000q0.000000 4.500000 -1.687500 8.531250q-1.671875 4.015625 -6.125000 9.484375q-1.218750 1.421875 -7.765625 8.187500q-6.531250 6.765625 -18.453125 18.921875"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(152.733125,401.706250)scale(0.120000)"> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115"/> +<use xlink:href="#c_ed3e21196fb739f392806f09ca0594ef" x="63.623047"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="95.410156"/> +</g> +</g> +</g> +<g id="xtick3"> +<g id="line2d5"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="250.560000" y="388.800000"/> +</g></g> +<g id="line2d6"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="250.560000" y="43.200000"/> +</g></g> +<g id="text3"> +<defs> +<path id="c_a0416418d96557a09b8c1332d34883ba" d="M37.796875 -64.312500l-24.906250 38.921875l24.906250 0.000000zM35.203125 -72.906250l12.406250 0.000000l0.000000 47.515625l10.406250 0.000000l0.000000 8.203125l-10.406250 0.000000l0.000000 17.187500l-9.812500 0.000000l0.000000 -17.187500l-32.906250 0.000000l0.000000 -9.515625z"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(241.747500,401.706250)scale(0.120000)"> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115"/> +<use xlink:href="#c_ed3e21196fb739f392806f09ca0594ef" x="63.623047"/> +<use xlink:href="#c_a0416418d96557a09b8c1332d34883ba" x="95.410156"/> +</g> +</g> +</g> +<g id="xtick4"> +<g id="line2d7"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="339.840000" y="388.800000"/> +</g></g> +<g id="line2d8"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="339.840000" y="43.200000"/> +</g></g> +<g id="text4"> +<defs> +<path id="c_cc8d6d580d1b10c8632f7a42cd53db8a" d="M33.015625 -40.375000q-6.640625 0.000000 -10.531250 4.546875q-3.875000 4.531250 -3.875000 12.437500q0.000000 7.859375 3.875000 12.437500q3.890625 4.562500 10.531250 4.562500q6.640625 0.000000 10.515625 -4.562500q3.875000 -4.578125 3.875000 -12.437500q0.000000 -7.906250 -3.875000 -12.437500q-3.875000 -4.546875 -10.515625 -4.546875M52.593750 -71.296875l0.000000 8.984375q-3.718750 -1.750000 -7.500000 -2.671875q-3.781250 -0.937500 -7.500000 -0.937500q-9.765625 0.000000 -14.921875 6.593750q-5.140625 6.593750 -5.875000 19.921875q2.875000 -4.250000 7.218750 -6.515625q4.359375 -2.265625 9.578125 -2.265625q10.984375 0.000000 17.359375 6.671875q6.375000 6.656250 6.375000 18.125000q0.000000 11.234375 -6.640625 18.031250q-6.640625 6.781250 -17.671875 6.781250q-12.656250 0.000000 -19.343750 -9.687500q-6.687500 -9.703125 -6.687500 -28.109375q0.000000 -17.281250 8.203125 -27.562500q8.203125 -10.281250 22.015625 -10.281250q3.718750 0.000000 7.500000 0.734375q3.781250 0.734375 7.890625 2.187500"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(331.074375,401.706250)scale(0.120000)"> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115"/> +<use xlink:href="#c_ed3e21196fb739f392806f09ca0594ef" x="63.623047"/> +<use xlink:href="#c_cc8d6d580d1b10c8632f7a42cd53db8a" x="95.410156"/> +</g> +</g> +</g> +<g id="xtick5"> +<g id="line2d9"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="429.120000" y="388.800000"/> +</g></g> +<g id="line2d10"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="429.120000" y="43.200000"/> +</g></g> +<g id="text5"> +<defs> +<path id="c_bef35738d52871942e50b9de9b122bab" d="M31.781250 -34.625000q-7.031250 0.000000 -11.062500 3.765625q-4.015625 3.765625 -4.015625 10.343750q0.000000 6.593750 4.015625 10.359375q4.031250 3.765625 11.062500 3.765625q7.031250 0.000000 11.078125 -3.781250q4.062500 -3.796875 4.062500 -10.343750q0.000000 -6.578125 -4.031250 -10.343750q-4.015625 -3.765625 -11.109375 -3.765625M21.921875 -38.812500q-6.343750 -1.562500 -9.890625 -5.906250q-3.531250 -4.359375 -3.531250 -10.609375q0.000000 -8.734375 6.218750 -13.812500q6.234375 -5.078125 17.062500 -5.078125q10.890625 0.000000 17.093750 5.078125q6.203125 5.078125 6.203125 13.812500q0.000000 6.250000 -3.546875 10.609375q-3.531250 4.343750 -9.828125 5.906250q7.125000 1.656250 11.093750 6.500000q3.984375 4.828125 3.984375 11.796875q0.000000 10.609375 -6.468750 16.281250q-6.468750 5.656250 -18.531250 5.656250q-12.046875 0.000000 -18.531250 -5.656250q-6.468750 -5.671875 -6.468750 -16.281250q0.000000 -6.968750 4.000000 -11.796875q4.015625 -4.843750 11.140625 -6.500000M18.312500 -54.390625q0.000000 5.656250 3.531250 8.828125q3.546875 3.171875 9.937500 3.171875q6.359375 0.000000 9.937500 -3.171875q3.593750 -3.171875 3.593750 -8.828125q0.000000 -5.671875 -3.593750 -8.843750q-3.578125 -3.171875 -9.937500 -3.171875q-6.390625 0.000000 -9.937500 3.171875q-3.531250 3.171875 -3.531250 8.843750"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(420.385625,401.706250)scale(0.120000)"> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115"/> +<use xlink:href="#c_ed3e21196fb739f392806f09ca0594ef" x="63.623047"/> +<use xlink:href="#c_bef35738d52871942e50b9de9b122bab" x="95.410156"/> +</g> +</g> +</g> +<g id="xtick6"> +<g id="line2d11"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="518.400000" y="388.800000"/> +</g></g> +<g id="line2d12"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="518.400000" y="43.200000"/> +</g></g> +<g id="text6"> +<defs> +<path id="c_42baa63129a918535c52adb20d687ea7" d="M12.406250 -8.296875l16.109375 0.000000l0.000000 -55.625000l-17.531250 3.515625l0.000000 -8.984375l17.437500 -3.515625l9.859375 0.000000l0.000000 64.609375l16.109375 0.000000l0.000000 8.296875l-41.984375 0.000000z"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(509.907812,401.706250)scale(0.120000)"> +<use xlink:href="#c_42baa63129a918535c52adb20d687ea7"/> +<use xlink:href="#c_ed3e21196fb739f392806f09ca0594ef" x="63.623047"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="95.410156"/> +</g> +</g> +</g> +</g> +<g id="matplotlib.axis2"> +<g id="ytick1"> +<g id="line2d13"> +<defs><path id="m3400efa6b1638b3fea9e19e898273957" d="M0.000000 0.000000L4.000000 0.000000"/></defs> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m3400efa6b1638b3fea9e19e898273957" x="72.000000" y="357.381818"/> +</g></g> +<g id="line2d14"> +<defs><path id="m20b58b2501143cb5e0a5e8f1ef6f1643" d="M0.000000 0.000000L-4.000000 0.000000"/></defs> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m20b58b2501143cb5e0a5e8f1ef6f1643" x="518.400000" y="357.381818"/> +</g></g> +<g id="text7"> +<defs> +<path id="c_54624f4845a86755fe6d2d7ebbf10290" d="M9.812500 -72.906250l9.859375 0.000000l0.000000 67.828125q0.000000 13.187500 -5.000000 19.140625q-5.000000 5.953125 -16.093750 5.953125l-3.750000 0.000000l0.000000 -8.296875l3.078125 0.000000q6.531250 0.000000 9.218750 -3.671875q2.687500 -3.656250 2.687500 -13.125000z"/> +<path id="c_01d93a582460e35a7945ca50d148ffeb" d="M34.281250 -27.484375q-10.890625 0.000000 -15.093750 2.484375q-4.203125 2.484375 -4.203125 8.500000q0.000000 4.781250 3.156250 7.593750q3.156250 2.796875 8.562500 2.796875q7.484375 0.000000 12.000000 -5.296875q4.515625 -5.296875 4.515625 -14.078125l0.000000 -2.000000zM52.203125 -31.203125l0.000000 31.203125l-8.984375 0.000000l0.000000 -8.296875q-3.078125 4.968750 -7.671875 7.343750q-4.593750 2.375000 -11.234375 2.375000q-8.390625 0.000000 -13.359375 -4.718750q-4.953125 -4.718750 -4.953125 -12.625000q0.000000 -9.218750 6.171875 -13.906250q6.187500 -4.687500 18.437500 -4.687500l12.609375 0.000000l0.000000 -0.890625q0.000000 -6.203125 -4.078125 -9.593750q-4.078125 -3.390625 -11.453125 -3.390625q-4.687500 0.000000 -9.140625 1.125000q-4.437500 1.125000 -8.531250 3.375000l0.000000 -8.312500q4.921875 -1.906250 9.562500 -2.843750q4.640625 -0.953125 9.031250 -0.953125q11.875000 0.000000 17.734375 6.156250q5.859375 6.140625 5.859375 18.640625"/> +<path id="c_fe791a90f5471e2ab20a5ed41a7fa451" d="M54.890625 -33.015625l0.000000 33.015625l-8.984375 0.000000l0.000000 -32.718750q0.000000 -7.765625 -3.031250 -11.609375q-3.031250 -3.859375 -9.078125 -3.859375q-7.281250 0.000000 -11.484375 4.640625q-4.203125 4.625000 -4.203125 12.640625l0.000000 30.906250l-9.031250 0.000000l0.000000 -54.687500l9.031250 0.000000l0.000000 8.500000q3.234375 -4.937500 7.593750 -7.375000q4.375000 -2.437500 10.093750 -2.437500q9.421875 0.000000 14.250000 5.828125q4.843750 5.828125 4.843750 17.156250"/> +<path id="c_d41d8cd98f00b204e9800998ecf8427e" d=""/> +<path id="c_956f18cfdaf972f35a6c2b4aaac2532b" d="M8.203125 -72.906250l46.875000 0.000000l0.000000 4.203125l-26.468750 68.703125l-10.296875 0.000000l24.906250 -64.593750l-35.015625 0.000000z"/> +<path id="c_cd96f817f3cab988d24a2b49a5577fe6" d="M10.984375 -1.515625l0.000000 -8.984375q3.718750 1.765625 7.515625 2.687500q3.812500 0.921875 7.484375 0.921875q9.765625 0.000000 14.906250 -6.562500q5.156250 -6.562500 5.890625 -19.953125q-2.828125 4.203125 -7.187500 6.453125q-4.343750 2.250000 -9.609375 2.250000q-10.937500 0.000000 -17.312500 -6.609375q-6.375000 -6.625000 -6.375000 -18.109375q0.000000 -11.218750 6.640625 -18.000000q6.640625 -6.796875 17.671875 -6.796875q12.656250 0.000000 19.312500 9.703125q6.671875 9.687500 6.671875 28.140625q0.000000 17.234375 -8.187500 27.515625q-8.171875 10.281250 -21.984375 10.281250q-3.718750 0.000000 -7.531250 -0.734375q-3.796875 -0.734375 -7.906250 -2.203125M30.609375 -32.421875q6.640625 0.000000 10.515625 -4.531250q3.890625 -4.546875 3.890625 -12.468750q0.000000 -7.859375 -3.890625 -12.421875q-3.875000 -4.562500 -10.515625 -4.562500q-6.640625 0.000000 -10.515625 4.562500q-3.875000 4.562500 -3.875000 12.421875q0.000000 7.921875 3.875000 12.468750q3.875000 4.531250 10.515625 4.531250"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(-3.765625,360.631818)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_42baa63129a918535c52adb20d687ea7" x="185.937500"/> +<use xlink:href="#c_956f18cfdaf972f35a6c2b4aaac2532b" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="ytick2"> +<g id="line2d15"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m3400efa6b1638b3fea9e19e898273957" x="72.000000" y="294.545455"/> +</g></g> +<g id="line2d16"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m20b58b2501143cb5e0a5e8f1ef6f1643" x="518.400000" y="294.545455"/> +</g></g> +<g id="text8"> +<g style="fill: #000000; opacity: 1.000000" transform="translate(-3.765625,297.795455)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_42baa63129a918535c52adb20d687ea7" x="185.937500"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="ytick3"> +<g id="line2d17"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m3400efa6b1638b3fea9e19e898273957" x="72.000000" y="231.709091"/> +</g></g> +<g id="line2d18"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m20b58b2501143cb5e0a5e8f1ef6f1643" x="518.400000" y="231.709091"/> +</g></g> +<g id="text9"> +<g style="fill: #000000; opacity: 1.000000" transform="translate(-3.765625,234.959091)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="185.937500"/> +<use xlink:href="#c_42baa63129a918535c52adb20d687ea7" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="ytick4"> +<g id="line2d19"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m3400efa6b1638b3fea9e19e898273957" x="72.000000" y="168.872727"/> +</g></g> +<g id="line2d20"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m20b58b2501143cb5e0a5e8f1ef6f1643" x="518.400000" y="168.872727"/> +</g></g> +<g id="text10"> +<defs> +<path id="c_3dcfa38a02242cb63ec6726c6e70be7a" d="M40.578125 -39.312500q7.078125 1.515625 11.046875 6.312500q3.984375 4.781250 3.984375 11.812500q0.000000 10.781250 -7.421875 16.703125q-7.421875 5.906250 -21.093750 5.906250q-4.578125 0.000000 -9.437500 -0.906250q-4.859375 -0.906250 -10.031250 -2.718750l0.000000 -9.515625q4.093750 2.390625 8.968750 3.609375q4.890625 1.218750 10.218750 1.218750q9.265625 0.000000 14.125000 -3.656250q4.859375 -3.656250 4.859375 -10.640625q0.000000 -6.453125 -4.515625 -10.078125q-4.515625 -3.640625 -12.562500 -3.640625l-8.500000 0.000000l0.000000 -8.109375l8.890625 0.000000q7.265625 0.000000 11.125000 -2.906250q3.859375 -2.906250 3.859375 -8.375000q0.000000 -5.609375 -3.984375 -8.609375q-3.968750 -3.015625 -11.390625 -3.015625q-4.062500 0.000000 -8.703125 0.890625q-4.640625 0.875000 -10.203125 2.718750l0.000000 -8.781250q5.625000 -1.562500 10.531250 -2.343750q4.906250 -0.781250 9.250000 -0.781250q11.234375 0.000000 17.765625 5.109375q6.546875 5.093750 6.546875 13.781250q0.000000 6.062500 -3.468750 10.234375q-3.468750 4.171875 -9.859375 5.781250"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(-3.765625,172.122727)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="185.937500"/> +<use xlink:href="#c_3dcfa38a02242cb63ec6726c6e70be7a" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="ytick5"> +<g id="line2d21"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m3400efa6b1638b3fea9e19e898273957" x="72.000000" y="106.036364"/> +</g></g> +<g id="line2d22"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m20b58b2501143cb5e0a5e8f1ef6f1643" x="518.400000" y="106.036364"/> +</g></g> +<g id="text11"> +<defs> +<path id="c_1260a2df50f305f3db244e29828f968e" d="M10.796875 -72.906250l38.718750 0.000000l0.000000 8.312500l-29.687500 0.000000l0.000000 17.859375q2.140625 -0.734375 4.281250 -1.093750q2.156250 -0.359375 4.312500 -0.359375q12.203125 0.000000 19.328125 6.687500q7.140625 6.687500 7.140625 18.109375q0.000000 11.765625 -7.328125 18.296875q-7.328125 6.515625 -20.656250 6.515625q-4.593750 0.000000 -9.359375 -0.781250q-4.750000 -0.781250 -9.828125 -2.343750l0.000000 -9.921875q4.390625 2.390625 9.078125 3.562500q4.687500 1.171875 9.906250 1.171875q8.453125 0.000000 13.375000 -4.437500q4.937500 -4.437500 4.937500 -12.062500q0.000000 -7.609375 -4.937500 -12.046875q-4.921875 -4.453125 -13.375000 -4.453125q-3.953125 0.000000 -7.890625 0.875000q-3.921875 0.875000 -8.015625 2.734375z"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(-3.765625,109.286364)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="185.937500"/> +<use xlink:href="#c_1260a2df50f305f3db244e29828f968e" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="ytick6"> +<g id="line2d23"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m3400efa6b1638b3fea9e19e898273957" x="72.000000" y="43.200000"/> +</g></g> +<g id="line2d24"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m20b58b2501143cb5e0a5e8f1ef6f1643" x="518.400000" y="43.200000"/> +</g></g> +<g id="text12"> +<g style="fill: #000000; opacity: 1.000000" transform="translate(-3.765625,46.450000)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="185.937500"/> +<use xlink:href="#c_956f18cfdaf972f35a6c2b4aaac2532b" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="text13"> +<defs> +<path id="c_dbe439baa035de1a298d0549b22269d8" d="M9.812500 -72.906250l46.093750 0.000000l0.000000 8.312500l-36.234375 0.000000l0.000000 21.578125l34.718750 0.000000l0.000000 8.296875l-34.718750 0.000000l0.000000 26.421875l37.109375 0.000000l0.000000 8.296875l-46.968750 0.000000z"/> +<path id="c_9e4b30cbdf32072672ded72e9074c4c9" d="M-0.296875 -72.906250l61.671875 0.000000l0.000000 8.312500l-25.875000 0.000000l0.000000 64.593750l-9.906250 0.000000l0.000000 -64.593750l-25.890625 0.000000z"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(-8.765625,222.882812)rotate(-90.0)scale(0.120000)"> +<use xlink:href="#c_dbe439baa035de1a298d0549b22269d8"/> +<use xlink:href="#c_9e4b30cbdf32072672ded72e9074c4c9" x="63.183594"/> +</g> +</g> +</g> +<g id="patch4"> +<path style="fill: none; stroke: #000000; stroke-width: 1.000000; stroke-linejoin: round; stroke-linecap: square; opacity: 1.000000" d="M72.000000 43.200000L518.400000 43.200000"/> +</g> +<g id="patch5"> +<path style="fill: none; stroke: #000000; stroke-width: 1.000000; stroke-linejoin: round; stroke-linecap: square; opacity: 1.000000" d="M518.400000 388.800000L518.400000 43.200000"/> +</g> +<g id="patch6"> +<path style="fill: none; stroke: #000000; stroke-width: 1.000000; stroke-linejoin: round; stroke-linecap: square; opacity: 1.000000" d="M72.000000 388.800000L518.400000 388.800000"/> +</g> +<g id="patch7"> +<path style="fill: none; stroke: #000000; stroke-width: 1.000000; stroke-linejoin: round; stroke-linecap: square; opacity: 1.000000" d="M72.000000 388.800000L72.000000 43.200000"/> +</g> +</g> +</g> +</svg> Added: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/axvspan_epoch.svg =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/axvspan_epoch.svg (rev 0) +++ trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_axes/axvspan_epoch.svg 2009-10-12 13:30:32 UTC (rev 7875) @@ -0,0 +1,318 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Created with matplotlib (http://matplotlib.sourceforge.net/) --> +<svg width="576pt" height="432pt" viewBox="0 0 576 432" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + version="1.1" + id="svg1"> +<filter id="colorAdd"><feComposite in="SourceGraphic" in2="BackgroundImage" operator="arithmetic" k2="1" k3="1"/></filter> +<g id="figure1"> +<g id="patch1"> +<path style="fill: #ffffff; stroke: #ffffff; stroke-width: 1.000000; stroke-linejoin: round; stroke-linecap: square; opacity: 1.000000" d="M0.000000 432.000000L576.000000 432.000000L576.000000 0.000000 +L0.000000 0.000000L0.000000 432.000000"/> +</g> +<g id="axes1"> +<g id="patch2"> +<path style="fill: #ffffff; opacity: 1.000000" d="M72.000000 388.800000L518.400000 388.800000L518.400000 43.200000 +L72.000000 43.200000L72.000000 388.800000"/> +</g> +<g id="patch3"> +<defs> + <clipPath id="p50431ccdcb28178602d99d9270004dde"> +<rect x="72.000000" y="43.200000" width="446.400000" height="345.600000"/> + </clipPath> +</defs><path style="fill: #0000ff; stroke: #000000; stroke-width: 1.000000; stroke-linejoin: round; stroke-linecap: square; opacity: 0.250000" clip-path="url(#p50431ccdcb28178602d99d9270004dde)" d="M274.909091 388.800000L274.909091 43.200000L315.490909 43.200000 +L315.490909 388.800000L274.909091 388.800000"/> +</g> +<g id="matplotlib.axis1"> +<g id="xtick1"> +<g id="line2d1"> +<defs><path id="m30e32995789d870ad79a2e54c91cf9c6" d="M0.000000 0.000000L0.000000 -4.000000"/></defs> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="112.581818" y="388.800000"/> +</g></g> +<g id="line2d2"> +<defs><path id="m9281cae24120827b11d5ea8a7ad3e96b" d="M0.000000 0.000000L0.000000 4.000000"/></defs> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="112.581818" y="43.200000"/> +</g></g> +<g id="text1"> +<defs> +<path id="c_54624f4845a86755fe6d2d7ebbf10290" d="M9.812500 -72.906250l9.859375 0.000000l0.000000 67.828125q0.000000 13.187500 -5.000000 19.140625q-5.000000 5.953125 -16.093750 5.953125l-3.750000 0.000000l0.000000 -8.296875l3.078125 0.000000q6.531250 0.000000 9.218750 -3.671875q2.687500 -3.656250 2.687500 -13.125000z"/> +<path id="c_01d93a582460e35a7945ca50d148ffeb" d="M34.281250 -27.484375q-10.890625 0.000000 -15.093750 2.484375q-4.203125 2.484375 -4.203125 8.500000q0.000000 4.781250 3.156250 7.593750q3.156250 2.796875 8.562500 2.796875q7.484375 0.000000 12.000000 -5.296875q4.515625 -5.296875 4.515625 -14.078125l0.000000 -2.000000zM52.203125 -31.203125l0.000000 31.203125l-8.984375 0.000000l0.000000 -8.296875q-3.078125 4.968750 -7.671875 7.343750q-4.593750 2.375000 -11.234375 2.375000q-8.390625 0.000000 -13.359375 -4.718750q-4.953125 -4.718750 -4.953125 -12.625000q0.000000 -9.218750 6.171875 -13.906250q6.187500 -4.687500 18.437500 -4.687500l12.609375 0.000000l0.000000 -0.890625q0.000000 -6.203125 -4.078125 -9.593750q-4.078125 -3.390625 -11.453125 -3.390625q-4.687500 0.000000 -9.140625 1.125000q-4.437500 1.125000 -8.531250 3.375000l0.000000 -8.312500q4.921875 -1.906250 9.562500 -2.843750q4.640625 -0.953125 9.031250 -0.953125q11.875000 0.000000 17.734375 6.156250q5.859375 6.140625 5.859375 18.640625"/> +<path id="c_fe791a90f5471e2ab20a5ed41a7fa451" d="M54.890625 -33.015625l0.000000 33.015625l-8.984375 0.000000l0.000000 -32.718750q0.000000 -7.765625 -3.031250 -11.609375q-3.031250 -3.859375 -9.078125 -3.859375q-7.281250 0.000000 -11.484375 4.640625q-4.203125 4.625000 -4.203125 12.640625l0.000000 30.906250l-9.031250 0.000000l0.000000 -54.687500l9.031250 0.000000l0.000000 8.500000q3.234375 -4.937500 7.593750 -7.375000q4.375000 -2.437500 10.093750 -2.437500q9.421875 0.000000 14.250000 5.828125q4.843750 5.828125 4.843750 17.156250"/> +<path id="c_d41d8cd98f00b204e9800998ecf8427e" d=""/> +<path id="c_42baa63129a918535c52adb20d687ea7" d="M12.406250 -8.296875l16.109375 0.000000l0.000000 -55.625000l-17.531250 3.515625l0.000000 -8.984375l17.437500 -3.515625l9.859375 0.000000l0.000000 64.609375l16.109375 0.000000l0.000000 8.296875l-41.984375 0.000000z"/> +<path id="c_956f18cfdaf972f35a6c2b4aaac2532b" d="M8.203125 -72.906250l46.875000 0.000000l0.000000 4.203125l-26.468750 68.703125l-10.296875 0.000000l24.906250 -64.593750l-35.015625 0.000000z"/> +<path id="c_ed3f3ed3ebfbd18bcb9c012009a68ad1" d="M19.187500 -8.296875l34.421875 0.000000l0.000000 8.296875l-46.281250 0.000000l0.000000 -8.296875q5.609375 -5.812500 15.296875 -15.593750q9.703125 -9.796875 12.187500 -12.640625q4.734375 -5.312500 6.609375 -9.000000q1.890625 -3.687500 1.890625 -7.250000q0.000000 -5.812500 -4.078125 -9.468750q-4.078125 -3.671875 -10.625000 -3.671875q-4.640625 0.000000 -9.796875 1.609375q-5.140625 1.609375 -11.000000 4.890625l0.000000 -9.968750q5.953125 -2.390625 11.125000 -3.609375q5.187500 -1.218750 9.484375 -1.218750q11.328125 0.000000 18.062500 5.671875q6.734375 5.656250 6.734375 15.125000q0.000000 4.500000 -1.687500 8.531250q-1.671875 4.015625 -6.125000 9.484375q-1.218750 1.421875 -7.765625 8.187500q-6.531250 6.765625 -18.453125 18.921875"/> +<path id="c_7a2040fe3b94fcd41d0a72c84e93b115" d="M31.781250 -66.406250q-7.609375 0.000000 -11.453125 7.500000q-3.828125 7.484375 -3.828125 22.531250q0.000000 14.984375 3.828125 22.484375q3.843750 7.500000 11.453125 7.500000q7.671875 0.000000 11.500000 -7.500000q3.843750 -7.500000 3.843750 -22.484375q0.000000 -15.046875 -3.843750 -22.531250q-3.828125 -7.500000 -11.500000 -7.500000M31.781250 -74.218750q12.265625 0.000000 18.734375 9.703125q6.468750 9.687500 6.468750 28.140625q0.000000 18.406250 -6.468750 28.109375q-6.468750 9.687500 -18.734375 9.687500q-12.250000 0.000000 -18.718750 -9.687500q-6.468750 -9.703125 -6.468750 -28.109375q0.000000 -18.453125 6.468750 -28.140625q6.468750 -9.703125 18.718750 -9.703125"/> +<path id="c_cd96f817f3cab988d24a2b49a5577fe6" d="M10.984375 -1.515625l0.000000 -8.984375q3.718750 1.765625 7.515625 2.687500q3.812500 0.921875 7.484375 0.921875q9.765625 0.000000 14.906250 -6.562500q5.156250 -6.562500 5.890625 -19.953125q-2.828125 4.203125 -7.187500 6.453125q-4.343750 2.250000 -9.609375 2.250000q-10.937500 0.000000 -17.312500 -6.609375q-6.375000 -6.625000 -6.375000 -18.109375q0.000000 -11.218750 6.640625 -18.000000q6.640625 -6.796875 17.671875 -6.796875q12.656250 0.000000 19.312500 9.703125q6.671875 9.687500 6.671875 28.140625q0.000000 17.234375 -8.187500 27.515625q-8.171875 10.281250 -21.984375 10.281250q-3.718750 0.000000 -7.531250 -0.734375q-3.796875 -0.734375 -7.906250 -2.203125M30.609375 -32.421875q6.640625 0.000000 10.515625 -4.531250q3.890625 -4.546875 3.890625 -12.468750q0.000000 -7.859375 -3.890625 -12.421875q-3.875000 -4.562500 -10.515625 -4.562500q-6.640625 0.000000 -10.515625 4.562500q-3.875000 4.562500 -3.875000 12.421875q0.000000 7.921875 3.875000 12.468750q3.875000 4.531250 10.515625 4.531250"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(76.699006,401.706250)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_42baa63129a918535c52adb20d687ea7" x="185.937500"/> +<use xlink:href="#c_956f18cfdaf972f35a6c2b4aaac2532b" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="xtick2"> +<g id="line2d3"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="193.745455" y="388.800000"/> +</g></g> +<g id="line2d4"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="193.745455" y="43.200000"/> +</g></g> +<g id="text2"> +<g style="fill: #000000; opacity: 1.000000" transform="translate(157.862642,401.706250)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_42baa63129a918535c52adb20d687ea7" x="185.937500"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="xtick3"> +<g id="line2d5"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="274.909091" y="388.800000"/> +</g></g> +<g id="line2d6"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="274.909091" y="43.200000"/> +</g></g> +<g id="text3"> +<g style="fill: #000000; opacity: 1.000000" transform="translate(239.026278,401.706250)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="185.937500"/> +<use xlink:href="#c_42baa63129a918535c52adb20d687ea7" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="xtick4"> +<g id="line2d7"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="356.072727" y="388.800000"/> +</g></g> +<g id="line2d8"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="356.072727" y="43.200000"/> +</g></g> +<g id="text4"> +<defs> +<path id="c_3dcfa38a02242cb63ec6726c6e70be7a" d="M40.578125 -39.312500q7.078125 1.515625 11.046875 6.312500q3.984375 4.781250 3.984375 11.812500q0.000000 10.781250 -7.421875 16.703125q-7.421875 5.906250 -21.093750 5.906250q-4.578125 0.000000 -9.437500 -0.906250q-4.859375 -0.906250 -10.031250 -2.718750l0.000000 -9.515625q4.093750 2.390625 8.968750 3.609375q4.890625 1.218750 10.218750 1.218750q9.265625 0.000000 14.125000 -3.656250q4.859375 -3.656250 4.859375 -10.640625q0.000000 -6.453125 -4.515625 -10.078125q-4.515625 -3.640625 -12.562500 -3.640625l-8.500000 0.000000l0.000000 -8.109375l8.890625 0.000000q7.265625 0.000000 11.125000 -2.906250q3.859375 -2.906250 3.859375 -8.375000q0.000000 -5.609375 -3.984375 -8.609375q-3.968750 -3.015625 -11.390625 -3.015625q-4.062500 0.000000 -8.703125 0.890625q-4.640625 0.875000 -10.203125 2.718750l0.000000 -8.781250q5.625000 -1.562500 10.531250 -2.343750q4.906250 -0.781250 9.250000 -0.781250q11.234375 0.000000 17.765625 5.109375q6.546875 5.093750 6.546875 13.781250q0.000000 6.062500 -3.468750 10.234375q-3.468750 4.171875 -9.859375 5.781250"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(320.189915,401.706250)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="185.937500"/> +<use xlink:href="#c_3dcfa38a02242cb63ec6726c6e70be7a" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="xtick5"> +<g id="line2d9"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="437.236364" y="388.800000"/> +</g></g> +<g id="line2d10"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="437.236364" y="43.200000"/> +</g></g> +<g id="text5"> +<defs> +<path id="c_1260a2df50f305f3db244e29828f968e" d="M10.796875 -72.906250l38.718750 0.000000l0.000000 8.312500l-29.687500 0.000000l0.000000 17.859375q2.140625 -0.734375 4.281250 -1.093750q2.156250 -0.359375 4.312500 -0.359375q12.203125 0.000000 19.328125 6.687500q7.140625 6.687500 7.140625 18.109375q0.000000 11.765625 -7.328125 18.296875q-7.328125 6.515625 -20.656250 6.515625q-4.593750 0.000000 -9.359375 -0.781250q-4.750000 -0.781250 -9.828125 -2.343750l0.000000 -9.921875q4.390625 2.390625 9.078125 3.562500q4.687500 1.171875 9.906250 1.171875q8.453125 0.000000 13.375000 -4.437500q4.937500 -4.437500 4.937500 -12.062500q0.000000 -7.609375 -4.937500 -12.046875q-4.921875 -4.453125 -13.375000 -4.453125q-3.953125 0.000000 -7.890625 0.875000q-3.921875 0.875000 -8.015625 2.734375z"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(401.353551,401.706250)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="185.937500"/> +<use xlink:href="#c_1260a2df50f305f3db244e29828f968e" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="xtick6"> +<g id="line2d11"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m30e32995789d870ad79a2e54c91cf9c6" x="518.400000" y="388.800000"/> +</g></g> +<g id="line2d12"> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m9281cae24120827b11d5ea8a7ad3e96b" x="518.400000" y="43.200000"/> +</g></g> +<g id="text6"> +<g style="fill: #000000; opacity: 1.000000" transform="translate(482.517188,401.706250)scale(0.120000)"> +<use xlink:href="#c_54624f4845a86755fe6d2d7ebbf10290"/> +<use xlink:href="#c_01d93a582460e35a7945ca50d148ffeb" x="29.492188"/> +<use xlink:href="#c_fe791a90f5471e2ab20a5ed41a7fa451" x="90.771484"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="154.150391"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="185.937500"/> +<use xlink:href="#c_956f18cfdaf972f35a6c2b4aaac2532b" x="249.560547"/> +<use xlink:href="#c_d41d8cd98f00b204e9800998ecf8427e" x="313.183594"/> +<use xlink:href="#c_ed3f3ed3ebfbd18bcb9c012009a68ad1" x="344.970703"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="408.593750"/> +<use xlink:href="#c_7a2040fe3b94fcd41d0a72c84e93b115" x="472.216797"/> +<use xlink:href="#c_cd96f817f3cab988d24a2b49a5577fe6" x="535.839844"/> +</g> +</g> +</g> +<g id="text7"> +<defs> +<path id="c_dbe439baa035de1a298d0549b22269d8" d="M9.812500 -72.906250l46.093750 0.000000l0.000000 8.312500l-36.234375 0.000000l0.000000 21.578125l34.718750 0.000000l0.000000 8.296875l-34.718750 0.000000l0.000000 26.421875l37.109375 0.000000l0.000000 8.296875l-46.968750 0.000000z"/> +<path id="c_9e4b30cbdf32072672ded72e9074c4c9" d="M-0.296875 -72.906250l61.671875 0.000000l0.000000 8.312500l-25.875000 0.000000l0.000000 64.593750l-9.906250 0.000000l0.000000 -64.593750l-25.890625 0.000000z"/> +</defs> +<g style="fill: #000000; opacity: 1.000000" transform="translate(288.317187,417.862500)scale(0.120000)"> +<use xlink:href="#c_dbe439baa035de1a298d0549b22269d8"/> +<use xlink:href="#c_9e4b30cbdf32072672ded72e9074c4c9" x="63.183594"/> +</g> +</g> +</g> +<g id="matplotlib.axis2"> +<g id="ytick1"> +<g id="line2d13"> +<defs><path id="m3400efa6b1638b3fea9e19e898273957" d="M0.000000 0.000000L4.000000 0.000000"/></defs> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m3400efa6b1638b3fea9e19e898273957" x="72.000000" y="388.800000"/> +</g></g> +<g id="line2d14"> +<defs><path id="m20b58b2501143cb5e0a5e8f1ef6f1643" d="M0.000000 0.000000L-4.000000 0.000000"/></defs> +<g ><use style="fill: none; stroke: #000000; stroke-width: 0.500000; stroke-linejoin: round; stroke-linecap: butt; opacity: 1.000000" xlink:href="#m20b58b2501143cb5e0a5e8f1ef6f1643" x="518.400000" y="388.800000"/> +</g></g> +<g id="text8"> +<defs> +<path id="c_ed3e21196fb739f392806f09ca0594ef" d="M10.687500 -12.406250l10.312500 0.000000l0.000000... [truncated message content] |
From: <md...@us...> - 2009-10-14 17:37:51
|
Revision: 7883 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7883&view=rev Author: mdboom Date: 2009-10-14 17:37:41 +0000 (Wed, 14 Oct 2009) Log Message: ----------- Support running of individual tests and multiprocess support. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/__init__.py trunk/matplotlib/lib/matplotlib/testing/compare.py trunk/matplotlib/lib/matplotlib/tests/__init__.py Modified: trunk/matplotlib/lib/matplotlib/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/__init__.py 2009-10-13 05:28:55 UTC (rev 7882) +++ trunk/matplotlib/lib/matplotlib/__init__.py 2009-10-14 17:37:41 UTC (rev 7883) @@ -920,19 +920,6 @@ from testing.noseclasses import KnownFailure from nose.plugins.manager import PluginManager - # Store the current backend and all rcParams for restoration later - backend = rcParams['backend'] - original_params = rcParams.copy() - - use('Agg', warn=False) # use Agg backend for these tests - - # These settings *must* be hardcoded for running the comparison - # tests and are not necessarily the default values as specified in - # rcsetup.py - rcdefaults() # Start with all defaults - rcParams['font.family'] = 'Bitstream Vera Sans' - rcParams['text.hinting'] = False - # store the old values before overriding plugins = [] plugins.append( KnownFailure() ) @@ -945,9 +932,6 @@ config=config, ) - # restore the old backend and rcParams - use(backend, warn=False) - rcParams.update(original_params) return success test.__test__ = False # nose: this function is not a test Modified: trunk/matplotlib/lib/matplotlib/testing/compare.py =================================================================== --- trunk/matplotlib/lib/matplotlib/testing/compare.py 2009-10-13 05:28:55 UTC (rev 7882) +++ trunk/matplotlib/lib/matplotlib/testing/compare.py 2009-10-14 17:37:41 UTC (rev 7883) @@ -152,7 +152,8 @@ msg += "Standard error:\n%s\n" % stderr raise IOError, msg -if matplotlib.checkdep_xmllint(): +# Turning this off, because it seems to cause multiprocessing issues +if matplotlib.checkdep_xmllint() and False: verifiers['svg'] = lambda filename: [ 'xmllint', '--valid', '--nowarning', '--noout', filename] Modified: trunk/matplotlib/lib/matplotlib/tests/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/__init__.py 2009-10-13 05:28:55 UTC (rev 7882) +++ trunk/matplotlib/lib/matplotlib/tests/__init__.py 2009-10-14 17:37:41 UTC (rev 7883) @@ -0,0 +1,13 @@ +from matplotlib import rcParams, rcdefaults, use + +_multiprocess_can_split_ = True + +def setup(): + use('Agg', warn=False) # use Agg backend for these tests + + # These settings *must* be hardcoded for running the comparison + # tests and are not necessarily the default values as specified in + # rcsetup.py + rcdefaults() # Start with all defaults + rcParams['font.family'] = 'Bitstream Vera Sans' + rcParams['text.hinting'] = False This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2009-10-29 19:04:53
|
Revision: 7911 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7911&view=rev Author: leejjoon Date: 2009-10-29 19:04:42 +0000 (Thu, 29 Oct 2009) Log Message: ----------- fix patheffect to work w/ MixedModeRenederer Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/patheffects.py trunk/matplotlib/lib/matplotlib/text.py Modified: trunk/matplotlib/lib/matplotlib/patheffects.py =================================================================== --- trunk/matplotlib/lib/matplotlib/patheffects.py 2009-10-26 17:08:35 UTC (rev 7910) +++ trunk/matplotlib/lib/matplotlib/patheffects.py 2009-10-29 19:04:42 UTC (rev 7911) @@ -5,6 +5,7 @@ """ from matplotlib.backend_bases import RendererBase +from matplotlib.backends.backend_mixed import MixedModeRenderer import matplotlib.transforms as transforms @@ -57,6 +58,9 @@ def _draw_text_as_path(self, renderer, gc, x, y, s, prop, angle, ismath): + if isinstance(renderer, MixedModeRenderer): + renderer = renderer._renderer + path, transform = RendererBase._get_text_path_transform(renderer, x, y, s, prop, angle, Modified: trunk/matplotlib/lib/matplotlib/text.py =================================================================== --- trunk/matplotlib/lib/matplotlib/text.py 2009-10-26 17:08:35 UTC (rev 7910) +++ trunk/matplotlib/lib/matplotlib/text.py 2009-10-29 19:04:42 UTC (rev 7911) @@ -278,9 +278,15 @@ horizLayout = np.zeros((len(lines), 4)) if self.get_path_effects(): - def get_text_width_height_descent(*kl, **kwargs): - return RendererBase.get_text_width_height_descent(renderer, - *kl, **kwargs) + from matplotlib.backends.backend_mixed import MixedModeRenderer + if isinstance(renderer, MixedModeRenderer): + def get_text_width_height_descent(*kl, **kwargs): + return RendererBase.get_text_width_height_descent(renderer._renderer, + *kl, **kwargs) + else: + def get_text_width_height_descent(*kl, **kwargs): + return RendererBase.get_text_width_height_descent(renderer, + *kl, **kwargs) else: get_text_width_height_descent = renderer.get_text_width_height_descent This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-11-03 20:52:08
|
Revision: 7927 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7927&view=rev Author: jdh2358 Date: 2009-11-03 20:51:55 +0000 (Tue, 03 Nov 2009) Log Message: ----------- added pca test Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/__init__.py trunk/matplotlib/lib/matplotlib/mlab.py Added Paths: ----------- trunk/matplotlib/lib/matplotlib/tests/test_mlab.py Modified: trunk/matplotlib/lib/matplotlib/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/__init__.py 2009-11-03 20:27:23 UTC (rev 7926) +++ trunk/matplotlib/lib/matplotlib/__init__.py 2009-11-03 20:51:55 UTC (rev 7927) @@ -905,6 +905,7 @@ 'matplotlib.tests.test_backend_svg', 'matplotlib.tests.test_basic', 'matplotlib.tests.test_cbook', + 'matplotlib.tests.test_mlab', 'matplotlib.tests.test_transforms', 'matplotlib.tests.test_axes', 'matplotlib.tests.test_dates', Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2009-11-03 20:27:23 UTC (rev 7926) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2009-11-03 20:51:55 UTC (rev 7927) @@ -761,7 +761,7 @@ """ WARNING: this function is deprecated -- please see class PCA instead - + Compute the principal components of *P*. *P* is a (*numVars*, *numObs*) array. *frac* is the minimum fraction of variance that a component must contain to be included. @@ -870,6 +870,27 @@ 'center the data using the mean and sigma from training set a' return (x - self.mu)/self.sigma + + + @staticmethod + def _get_colinear(): + c0 = np.array([ + 0.19294738, 0.6202667 , 0.45962655, 0.07608613, 0.135818 , + 0.83580842, 0.07218851, 0.48318321, 0.84472463, 0.18348462, + 0.81585306, 0.96923926, 0.12835919, 0.35075355, 0.15807861, + 0.837437 , 0.10824303, 0.1723387 , 0.43926494, 0.83705486]) + + c1 = np.array([ + -1.17705601, -0.513883 , -0.26614584, 0.88067144, 1.00474954, + -1.1616545 , 0.0266109 , 0.38227157, 1.80489433, 0.21472396, + -1.41920399, -2.08158544, -0.10559009, 1.68999268, 0.34847107, + -0.4685737 , 1.23980423, -0.14638744, -0.35907697, 0.22442616]) + + c2 = c0 + 2*c1 + c3 = -3*c0 + 4*c1 + a = np.array([c3, c0, c1, c2]).T + return a + def prctile(x, p = (0.0, 25.0, 50.0, 75.0, 100.0)): """ Return the percentiles of *x*. *p* can either be a sequence of Added: trunk/matplotlib/lib/matplotlib/tests/test_mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/test_mlab.py (rev 0) +++ trunk/matplotlib/lib/matplotlib/tests/test_mlab.py 2009-11-03 20:51:55 UTC (rev 7927) @@ -0,0 +1,11 @@ +import numpy as np +import matplotlib.mlab as mlab + +@staticmethod +def test_colinear_pca(): + a = mlab.PCA._get_colinear() + pca = mlab.PCA(a) + + assert(np.allclose(pca.fracs[2:], 0.)) + assert(np.allclose(pca.Y[:,2:], 0.)) + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-11-03 21:17:58
|
Revision: 7931 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7931&view=rev Author: jdh2358 Date: 2009-11-03 21:17:48 +0000 (Tue, 03 Nov 2009) Log Message: ----------- remove static decorator Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mlab.py trunk/matplotlib/lib/matplotlib/tests/test_mlab.py Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2009-11-03 20:57:23 UTC (rev 7930) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2009-11-03 21:17:48 UTC (rev 7931) @@ -820,6 +820,10 @@ *Y* : a projected into PCA space + + The factor loadings are in the Wt factor, ie the factor + loadings for the 1st principal component are given by Wt[0] + """ n, m = a.shape if n<m: Modified: trunk/matplotlib/lib/matplotlib/tests/test_mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/test_mlab.py 2009-11-03 20:57:23 UTC (rev 7930) +++ trunk/matplotlib/lib/matplotlib/tests/test_mlab.py 2009-11-03 21:17:48 UTC (rev 7931) @@ -1,7 +1,6 @@ import numpy as np import matplotlib.mlab as mlab -@staticmethod def test_colinear_pca(): a = mlab.PCA._get_colinear() pca = mlab.PCA(a) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-11-04 17:30:20
|
Revision: 7936 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7936&view=rev Author: jdh2358 Date: 2009-11-04 17:30:12 +0000 (Wed, 04 Nov 2009) Log Message: ----------- added levels kwarg to contour Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/contour.py trunk/matplotlib/lib/matplotlib/mlab.py trunk/matplotlib/lib/matplotlib/widgets.py Modified: trunk/matplotlib/lib/matplotlib/contour.py =================================================================== --- trunk/matplotlib/lib/matplotlib/contour.py 2009-11-04 16:26:37 UTC (rev 7935) +++ trunk/matplotlib/lib/matplotlib/contour.py 2009-11-04 17:30:12 UTC (rev 7936) @@ -1066,6 +1066,11 @@ scaling data values to colors. If *norm* is *None* and *colors* is *None*, the default linear scaling is used. + *levels* [level0, level1, ..., leveln] + A list of floating point numbers indicating the level + curves to draw; eg to draw just the zero contour pass + ``levels=[0]`` + *origin*: [ None | 'upper' | 'lower' | 'image' ] If *None*, the first value of *Z* will correspond to the lower left corner, location (0,0). If 'image', the rc Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2009-11-04 16:26:37 UTC (rev 7935) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2009-11-04 17:30:12 UTC (rev 7936) @@ -2576,6 +2576,10 @@ *withheader*: if withheader is False, do not write the attribute names in the first row + for formatd type FormatFloat, we override the precision to store + full precision floats in the CSV file + + .. seealso:: :func:`csv2rec` Modified: trunk/matplotlib/lib/matplotlib/widgets.py =================================================================== --- trunk/matplotlib/lib/matplotlib/widgets.py 2009-11-04 16:26:37 UTC (rev 7935) +++ trunk/matplotlib/lib/matplotlib/widgets.py 2009-11-04 17:30:12 UTC (rev 7936) @@ -669,6 +669,8 @@ self.vertOn = True self.useblit = useblit + if useblit: + lineprops['animated'] = True self.lineh = ax.axhline(ax.get_ybound()[0], visible=False, **lineprops) self.linev = ax.axvline(ax.get_xbound()[0], visible=False, **lineprops) @@ -741,10 +743,14 @@ """ def __init__(self, canvas, axes, useblit=True, **lineprops): + self.canvas = canvas self.axes = axes xmin, xmax = axes[-1].get_xlim() xmid = 0.5*(xmin+xmax) + if useblit: + lineprops['animated'] = True + self.lines = [ax.axvline(xmid, visible=False, **lineprops) for ax in axes] self.visible = True This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2009-11-04 17:53:31
|
Revision: 7937 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7937&view=rev Author: leejjoon Date: 2009-11-04 17:53:25 +0000 (Wed, 04 Nov 2009) Log Message: ----------- add bbox_extra_artists keyword for savefig Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backend_bases.py trunk/matplotlib/lib/matplotlib/figure.py Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2009-11-04 17:30:12 UTC (rev 7936) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2009-11-04 17:53:25 UTC (rev 7937) @@ -1536,11 +1536,26 @@ *edgecolor* the edgecolor of the figure - *orientation* ' + *orientation* landscape' | 'portrait' (not supported on all backends) *format* when set, forcibly set the file format to save to + + + *bbox_inches* + Bbox in inches. Only the given portion of the figure is + saved. If 'tight', try to figure out the tight bbox of + the figure. + + *pad_inches* + Amount of padding around the figure when bbox_inches is + 'tight'. + + *bbox_extra_artists* + A list of extra artists that will be considered when the + tight bbox is calculated. + """ if format is None: if cbook.is_string_like(filename): @@ -1597,6 +1612,18 @@ **kwargs) renderer = self.figure._cachedRenderer bbox_inches = self.figure.get_tightbbox(renderer) + + bb = [a.get_window_extent(renderer) for a in kwargs.pop("bbox_extra_artists", []) \ + if a.get_visible()] + if bb: + _bbox = Bbox.union([b for b in bb if b.width!=0 or b.height!=0]) + + bbox_inches1 = TransformedBbox(_bbox, + Affine2D().scale(1./self.figure.dpi)) + + bbox_inches = Bbox.union([bbox_inches, bbox_inches1]) + + pad = kwargs.pop("pad_inches", 0.1) bbox_inches = bbox_inches.padded(pad) Modified: trunk/matplotlib/lib/matplotlib/figure.py =================================================================== --- trunk/matplotlib/lib/matplotlib/figure.py 2009-11-04 17:30:12 UTC (rev 7936) +++ trunk/matplotlib/lib/matplotlib/figure.py 2009-11-04 17:53:25 UTC (rev 7937) @@ -1031,6 +1031,10 @@ Amount of padding around the figure when bbox_inches is 'tight'. + *bbox_extra_artists*: + A list of extra artists that will be considered when the + tight bbox is calculated. + """ for key in ('dpi', 'facecolor', 'edgecolor'): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2009-11-12 20:53:44
|
Revision: 7956 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7956&view=rev Author: mdboom Date: 2009-11-12 20:53:36 +0000 (Thu, 12 Nov 2009) Log Message: ----------- Fix a number of font manager issues: 1) AFM fonts now store stretch information in the FontManager database 2) pdf.use14corefonts and ps.useafm will now only use the afm files for their respective formats 3) The fontList.cache file is now versioned -- if the version doesn't match the current version of matplotlib it is thrown away and regenerated Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/font_manager.py trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-11-12 17:57:13 UTC (rev 7955) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-11-12 20:53:36 UTC (rev 7956) @@ -363,6 +363,8 @@ else: raise ValueError("filename must be a path or a file-like object") + self._core14fontdir = os.path.join( + rcParams['datapath'], 'fonts', 'pdfcorefonts') self.fh = fh self.currentstream = None # stream object to write to, if any fh.write("%PDF-1.4\n") # 1.4 is the first version to have alpha @@ -507,7 +509,11 @@ if is_string_like(fontprop): filename = fontprop elif rcParams['pdf.use14corefonts']: - filename = findfont(fontprop, fontext='afm') + filename = findfont( + fontprop, fontext='afm', directory=self._core14fontdir) + if filename is None: + filename = findfont( + "Helvetica", fontext='afm', directory=self._core14fontdir) else: filename = findfont(fontprop) @@ -1743,7 +1749,12 @@ key = hash(prop) font = self.afm_font_cache.get(key) if font is None: - filename = findfont(prop, fontext='afm') + filename = findfont( + prop, fontext='afm', directory=self.file._core14fontdir) + if filename is None: + filename = findfont( + "Helvetica", fontext='afm', + directory=self.file._core14fontdir) font = self.afm_font_cache.get(filename) if font is None: fh = file(filename) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-11-12 17:57:13 UTC (rev 7955) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-11-12 20:53:36 UTC (rev 7956) @@ -170,6 +170,9 @@ self.used_characters = {} self.mathtext_parser = MathTextParser("PS") + self._afm_font_dir = os.path.join( + rcParams['datapath'], 'fonts', 'afm') + def track_characters(self, font, s): """Keeps track of which characters are required from each font.""" @@ -312,10 +315,13 @@ key = hash(prop) font = self.afmfontd.get(key) if font is None: - fname = findfont(prop, fontext='afm') + fname = findfont(prop, fontext='afm', directory=self._afm_font_dir) + if fname is None: + fname = findfont( + "Helvetica", fontext='afm', directory=self._afm_font_dir) font = self.afmfontd.get(fname) if font is None: - font = AFM(file(findfont(prop, fontext='afm'))) + font = AFM(file(fname)) self.afmfontd[fname] = font self.afmfontd[key] = font return font Modified: trunk/matplotlib/lib/matplotlib/font_manager.py =================================================================== --- trunk/matplotlib/lib/matplotlib/font_manager.py 2009-11-12 17:57:13 UTC (rev 7955) +++ trunk/matplotlib/lib/matplotlib/font_manager.py 2009-11-12 20:53:36 UTC (rev 7956) @@ -301,7 +301,7 @@ except OSError: # Calling fc-list did not work, so we'll just return nothing return fontfiles - + if pipe.returncode == 0: for line in output.split('\n'): fname = line.split(':')[0] @@ -463,8 +463,7 @@ # Relative stretches are: wider, narrower # Child value is: inherit - # !!!! Incomplete - if sfnt4.find('narrow') >= 0 or sfnt4.find('condensed') >= 0 or \ + if sfnt4.find('narrow') >= 0 or sfnt4.find('condensed') >= 0 or \ sfnt4.find('cond') >= 0: stretch = 'condensed' elif sfnt4.find('demi cond') >= 0: @@ -502,6 +501,7 @@ """ name = font.get_familyname() + fontname = font.get_fontname().lower() # Styles are: italic, oblique, and normal (default) @@ -532,10 +532,16 @@ # and ultra-expanded. # Relative stretches are: wider, narrower # Child value is: inherit + if fontname.find('narrow') >= 0 or fontname.find('condensed') >= 0 or \ + fontname.find('cond') >= 0: + stretch = 'condensed' + elif fontname.find('demi cond') >= 0: + stretch = 'semi-condensed' + elif fontname.find('wide') >= 0 or fontname.find('expanded') >= 0: + stretch = 'expanded' + else: + stretch = 'normal' - # !!!! Incomplete - stretch = 'normal' - # Sizes can be absolute and relative. # Absolute sizes are: xx-small, x-small, small, medium, large, x-large, # and xx-large. @@ -960,12 +966,20 @@ matches the specification. If no good enough match is found, a default font is returned. """ + # Increment this version number whenever the font cache data + # format or behavior has changed and requires a existing font + # cache files to be rebuilt. + __version__ = 5 + def __init__(self, size=None, weight='normal'): + self._version = self.__version__ + self.__default_weight = weight self.default_size = size paths = [os.path.join(rcParams['datapath'], 'fonts', 'ttf'), - os.path.join(rcParams['datapath'], 'fonts', 'afm')] + os.path.join(rcParams['datapath'], 'fonts', 'afm'), + os.path.join(rcParams['datapath'], 'fonts', 'pdfcorefonts')] # Create list of font paths for pathname in ['TTFPATH', 'AFMPATH']: @@ -982,32 +996,23 @@ # Load TrueType fonts and create font dictionary. self.ttffiles = findSystemFonts(paths) + findSystemFonts() + self.defaultFont = {} for fname in self.ttffiles: verbose.report('trying fontname %s' % fname, 'debug') if fname.lower().find('vera.ttf')>=0: - self.defaultFont = fname + self.defaultFont['ttf'] = fname break else: # use anything - self.defaultFont = self.ttffiles[0] + self.defaultFont['ttf'] = self.ttffiles[0] self.ttflist = createFontList(self.ttffiles) - if rcParams['pdf.use14corefonts']: - # Load only the 14 PDF core fonts. These fonts do not need to be - # embedded; every PDF viewing application is required to have them: - # Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique, - # Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique, - # Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic, Symbol, - # ZapfDingbats. - afmpath = os.path.join(rcParams['datapath'],'fonts','pdfcorefonts') - afmfiles = findSystemFonts(afmpath, fontext='afm') - self.afmlist = createFontList(afmfiles, fontext='afm') - else: - self.afmfiles = findSystemFonts(paths, fontext='afm') + \ - findSystemFonts(fontext='afm') - self.afmlist = createFontList(self.afmfiles, fontext='afm') + self.afmfiles = findSystemFonts(paths, fontext='afm') + \ + findSystemFonts(fontext='afm') + self.afmlist = createFontList(self.afmfiles, fontext='afm') + self.defaultFont['afm'] = None self.ttf_lookup_cache = {} self.afm_lookup_cache = {} @@ -1151,7 +1156,7 @@ return 1.0 return abs(sizeval1 - sizeval2) / 72.0 - def findfont(self, prop, fontext='ttf'): + def findfont(self, prop, fontext='ttf', directory=None): """ Search the font list for the font that most closely matches the :class:`FontProperties` *prop*. @@ -1162,6 +1167,9 @@ returned. If no matches below a certain threshold are found, the default font (usually Vera Sans) is returned. + `directory`, is specified, will only return fonts from the + given directory (or subdirectory of that directory). + The result is cached, so subsequent lookups don't have to perform the O(n) nearest neighbor search. @@ -1194,6 +1202,10 @@ best_font = None for font in fontlist: + if (directory is not None and + os.path.commonprefix([font.fname, directory]) != directory): + print directory, font.fname, os.path.commonprefix([font.fname, directory]) + continue # Matching family should have highest priority, so it is multiplied # by 10.0 score = \ @@ -1211,8 +1223,8 @@ if best_font is None or best_score >= 10.0: verbose.report('findfont: Could not match %s. Returning %s' % - (prop, self.defaultFont)) - result = self.defaultFont + (prop, self.defaultFont[fontext])) + result = self.defaultFont[fontext] else: verbose.report('findfont: Matching %s to %s (%s) with score of %f' % (prop, best_font.name, best_font.fname, best_score)) @@ -1289,16 +1301,16 @@ try: fontManager = pickle_load(_fmcache) - fontManager.default_size = None - verbose.report("Using fontManager instance from %s" % _fmcache) + if (not hasattr(fontManager, '_version') or + fontManager._version != FontManager.__version__): + _rebuild() + else: + fontManager.default_size = None + verbose.report("Using fontManager instance from %s" % _fmcache) except: _rebuild() def findfont(prop, **kw): global fontManager font = fontManager.findfont(prop, **kw) - if not os.path.exists(font): - verbose.report("%s returned by pickled fontManager does not exist" % font) - _rebuild() - font = fontManager.findfont(prop, **kw) return font Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2009-11-12 17:57:13 UTC (rev 7955) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2009-11-12 20:53:36 UTC (rev 7956) @@ -1032,7 +1032,11 @@ self.glyphd = {} self.fonts = {} - filename = findfont(default_font_prop, fontext='afm') + filename = findfont(default_font_prop, fontext='afm', + directory=self.basepath) + if filename is None: + filename = findfont('Helvetica', fontext='afm', + directory=self.basepath) default_font = AFM(file(filename, 'r')) default_font.fname = filename This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2009-11-15 14:17:21
|
Revision: 7969 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7969&view=rev Author: mdehoon Date: 2009-11-15 14:17:14 +0000 (Sun, 15 Nov 2009) Log Message: ----------- Bracket each call to new_gc() by a corresponding call to gc.restore() to avoid bugs in the Cairo and Mac OS X backends. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/patheffects.py trunk/matplotlib/lib/matplotlib/text.py Modified: trunk/matplotlib/lib/matplotlib/patheffects.py =================================================================== --- trunk/matplotlib/lib/matplotlib/patheffects.py 2009-11-15 14:07:11 UTC (rev 7968) +++ trunk/matplotlib/lib/matplotlib/patheffects.py 2009-11-15 14:17:14 UTC (rev 7969) @@ -119,6 +119,7 @@ gc0 = self._update_gc(gc0, self._gc) renderer.draw_path(gc0, tpath, affine, None) + gc0.restore() class withStroke(Stroke): @@ -183,6 +184,7 @@ gc0 = self._update_gc(gc0, self._gc) renderer.draw_path(gc0, tpath, affine0, shadow_rgbFace) + gc0.restore() class withSimplePatchShadow(SimplePatchShadow): @@ -198,6 +200,7 @@ gc1.copy_properties(gc) gc1.set_alpha(gc1.get_alpha()*self._patch_alpha) renderer.draw_path(gc1, tpath, affine, rgbFace) + gc1.restore() if __name__ == '__main__': Modified: trunk/matplotlib/lib/matplotlib/text.py =================================================================== --- trunk/matplotlib/lib/matplotlib/text.py 2009-11-15 14:07:11 UTC (rev 7968) +++ trunk/matplotlib/lib/matplotlib/text.py 2009-11-15 14:17:14 UTC (rev 7969) @@ -590,6 +590,7 @@ else: renderer.draw_tex(gc, x, y, clean_line, self._fontproperties, angle) + gc.restore() renderer.close_group('text') return This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2009-11-23 20:27:13
|
Revision: 7980 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7980&view=rev Author: jdh2358 Date: 2009-11-23 20:26:44 +0000 (Mon, 23 Nov 2009) Log Message: ----------- make index formatter derive from base Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/dates.py trunk/matplotlib/lib/matplotlib/ticker.py Modified: trunk/matplotlib/lib/matplotlib/dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dates.py 2009-11-23 03:38:11 UTC (rev 7979) +++ trunk/matplotlib/lib/matplotlib/dates.py 2009-11-23 20:26:44 UTC (rev 7980) @@ -454,6 +454,7 @@ return self._formatter(x, pos) + class rrulewrapper: def __init__(self, freq, **kwargs): Modified: trunk/matplotlib/lib/matplotlib/ticker.py =================================================================== --- trunk/matplotlib/lib/matplotlib/ticker.py 2009-11-23 03:38:11 UTC (rev 7979) +++ trunk/matplotlib/lib/matplotlib/ticker.py 2009-11-23 20:26:44 UTC (rev 7980) @@ -206,13 +206,14 @@ """ return s -class IndexFormatter: +class IndexFormatter(Formatter): """ format the position x to the nearest i-th label where i=int(x+0.5) """ def __init__(self, labels): self.labels = labels self.n = len(labels) + def __call__(self, x, pos=None): 'Return the format for tick val x at position pos; pos=None indicated unspecified' i = int(x+0.5) @@ -657,7 +658,7 @@ because the locator stores references to the Axis data and view limits """ - + # some automatic tick locators can generate so many ticks they # kill the machine when you try and render them, see eg sf bug # report @@ -673,7 +674,7 @@ 'raise a RuntimeError if Locator attempts to create more than MAXTICKS locs' if len(locs)>=self.MAXTICKS: raise RuntimeError('Locator attempting to generate %d ticks from %s to %s: exceeds Locator.MAXTICKS'%(len(locs), locs[0], locs[-1])) - + return locs def view_limits(self, vmin, vmax): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2009-12-02 01:13:38
|
Revision: 8000 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8000&view=rev Author: efiring Date: 2009-12-02 01:13:25 +0000 (Wed, 02 Dec 2009) Log Message: ----------- Draw artists with identical zorder in the order in which they were added. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/figure.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2009-12-01 19:09:10 UTC (rev 7999) +++ trunk/matplotlib/lib/matplotlib/axes.py 2009-12-02 01:13:25 UTC (rev 8000) @@ -1700,10 +1700,10 @@ dsu = [ (a.zorder, a) for a in artists if not a.get_animated() ] - dsu.sort() + dsu.sort(key=lambda x: x[0]) - # rasterze artists with negative zorder + # rasterize artists with negative zorder # if the minimum zorder is negative, start rasterization rasterization_zorder = self._rasterization_zorder if len(dsu) > 0 and dsu[0][0] < rasterization_zorder: @@ -1722,15 +1722,15 @@ if len(self.images)<=1 or renderer.option_image_nocomposite(): for im in self.images: dsu.append( (im.zorder, im) ) - dsu.sort() # re-sort with images now + dsu.sort(key=lambda x: x[0]) # re-sort with images now else: # make a composite image blending alpha # list of (mimage.Image, ox, oy) zorder_images = [(im.zorder, im) for im in self.images \ if im.get_visible()] - zorder_images.sort() - + zorder_images.sort(key=lambda x: x[0]) + mag = renderer.get_image_magnification() ims = [(im.make_image(mag),0,0) for z,im in zorder_images] @@ -1793,7 +1793,7 @@ if self._lastRenderer is None: raise RuntimeError('You must first call ax.draw()') dsu = [(a.zorder, a) for a in self.animated.keys()] - dsu.sort() + dsu.sort(key=lambda x: x[0]) renderer = self._lastRenderer renderer.blit() for tmp, a in dsu: Modified: trunk/matplotlib/lib/matplotlib/figure.py =================================================================== --- trunk/matplotlib/lib/matplotlib/figure.py 2009-12-01 19:09:10 UTC (rev 7999) +++ trunk/matplotlib/lib/matplotlib/figure.py 2009-12-02 01:13:25 UTC (rev 8000) @@ -798,7 +798,7 @@ dsu.append( (a.get_zorder(), a.draw, [renderer])) - dsu.sort() + dsu.sort(key=lambda x: x[0]) for zorder, func, args in dsu: func(*args) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2009-12-03 20:21:32
|
Revision: 8005 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8005&view=rev Author: mdboom Date: 2009-12-03 20:21:21 +0000 (Thu, 03 Dec 2009) Log Message: ----------- Backport a number of mathtext fixes from mathtex project. Add unit tests. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/__init__.py trunk/matplotlib/lib/matplotlib/mathtext.py trunk/matplotlib/lib/matplotlib/testing/decorators.py Added Paths: ----------- trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/ trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext.pdf trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext.png trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix.pdf trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix.png trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix.svg trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans.pdf trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans.png trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans.svg Modified: trunk/matplotlib/lib/matplotlib/__init__.py =================================================================== --- trunk/matplotlib/lib/matplotlib/__init__.py 2009-12-03 19:24:30 UTC (rev 8004) +++ trunk/matplotlib/lib/matplotlib/__init__.py 2009-12-03 20:21:21 UTC (rev 8005) @@ -912,6 +912,7 @@ 'matplotlib.tests.test_spines', 'matplotlib.tests.test_image', 'matplotlib.tests.test_simplification', + 'matplotlib.tests.test_mathtext' ] def test(verbosity=0): Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2009-12-03 19:24:30 UTC (rev 8004) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2009-12-03 20:21:21 UTC (rev 8005) @@ -999,6 +999,11 @@ if glyphindex is not None: alternatives.append((i, unichr(uniindex))) + # The largest size of the radical symbol in STIX has incorrect + # metrics that cause it to be disconnected from the stem. + if sym == r'\__sqrt__': + alternatives = alternatives[:-1] + self._size_alternatives[sym] = alternatives return alternatives @@ -1186,7 +1191,7 @@ GROW_FACTOR = 1.0 / SHRINK_FACTOR # The number of different sizes of chars to use, beyond which they will not # get any smaller -NUM_SIZE_LEVELS = 4 +NUM_SIZE_LEVELS = 6 # Percentage of x-height of additional horiz. space after sub/superscripts SCRIPT_SPACE = 0.2 # Percentage of x-height that sub/superscripts drop below the baseline @@ -1648,9 +1653,10 @@ """ Convenience class to create a horizontal rule. """ - def __init__(self, state): - thickness = state.font_output.get_underline_thickness( - state.font, state.fontsize, state.dpi) + def __init__(self, state, thickness=None): + if thickness is None: + thickness = state.font_output.get_underline_thickness( + state.font, state.fontsize, state.dpi) height = depth = thickness * 0.5 Rule.__init__(self, inf, height, depth, state) @@ -2202,6 +2208,41 @@ | Error(r"Expected \frac{num}{den}")) ).setParseAction(self.frac).setName("frac") + stackrel = Group( + Suppress(Literal(r"\stackrel")) + + ((group + group) + | Error(r"Expected \stackrel{num}{den}")) + ).setParseAction(self.stackrel).setName("stackrel") + + + binom = Group( + Suppress(Literal(r"\binom")) + + ((group + group) + | Error(r"Expected \binom{num}{den}")) + ).setParseAction(self.binom).setName("binom") + + ambiDelim = oneOf(list(self._ambiDelim)) + leftDelim = oneOf(list(self._leftDelim)) + rightDelim = oneOf(list(self._rightDelim)) + rightDelimSafe = oneOf(list(self._rightDelim - set(['}']))) + genfrac = Group( + Suppress(Literal(r"\genfrac")) + + ((Suppress(Literal('{')) + + oneOf(list(self._ambiDelim | self._leftDelim | set(['']))) + + Suppress(Literal('}')) + + Suppress(Literal('{')) + + oneOf(list(self._ambiDelim | + (self._rightDelim - set(['}'])) | + set(['', r'\}']))) + + Suppress(Literal('}')) + + Suppress(Literal('{')) + + Regex("[0-9]*(\.?[0-9]*)?") + + Suppress(Literal('}')) + + group + group + group) + | Error(r"Expected \genfrac{ldelim}{rdelim}{rulesize}{style}{num}{den}")) + ).setParseAction(self.genfrac).setName("genfrac") + + sqrt = Group( Suppress(Literal(r"\sqrt")) + Optional( @@ -2218,6 +2259,9 @@ ^ accent ^ group ^ frac + ^ stackrel + ^ binom + ^ genfrac ^ sqrt ) @@ -2239,9 +2283,6 @@ | placeable ) - ambiDelim = oneOf(list(self._ambiDelim)) - leftDelim = oneOf(list(self._leftDelim)) - rightDelim = oneOf(list(self._rightDelim)) autoDelim <<(Suppress(Literal(r"\left")) + ((leftDelim | ambiDelim) | Error("Expected a delimiter")) + Group( @@ -2626,9 +2667,9 @@ hlist = HCentered([sub]) hlist.hpack(width, 'exactly') vlist.extend([Kern(rule_thickness * 3.0), hlist]) - shift = hlist.height + hlist.depth + rule_thickness * 2.0 + shift = hlist.height vlist = Vlist(vlist) - vlist.shift_amount = shift + nucleus.depth * 0.5 + vlist.shift_amount = shift + nucleus.depth result = Hlist([vlist]) return [result] @@ -2677,40 +2718,78 @@ result = Hlist([nucleus, x]) return [result] - def frac(self, s, loc, toks): - assert(len(toks)==1) - assert(len(toks[0])==2) + def _genfrac(self, ldelim, rdelim, rule, style, num, den): state = self.get_state() thickness = state.font_output.get_underline_thickness( state.font, state.fontsize, state.dpi) - num, den = toks[0] + rule = float(rule) num.shrink() den.shrink() cnum = HCentered([num]) cden = HCentered([den]) - width = max(num.width, den.width) + thickness * 10. + width = max(num.width, den.width) cnum.hpack(width, 'exactly') cden.hpack(width, 'exactly') vlist = Vlist([cnum, # numerator Vbox(0, thickness * 2.0), # space - Hrule(state), # rule - Vbox(0, thickness * 4.0), # space + Hrule(state, rule), # rule + Vbox(0, thickness * 2.0), # space cden # denominator ]) # Shift so the fraction line sits in the middle of the # equals sign metrics = state.font_output.get_metrics( - state.font, rcParams['mathtext.default'], '=', state.fontsize, state.dpi) + state.font, rcParams['mathtext.default'], + '=', state.fontsize, state.dpi) shift = (cden.height - ((metrics.ymax + metrics.ymin) / 2 - thickness * 3.0)) vlist.shift_amount = shift - hlist = Hlist([vlist, Hbox(thickness * 2.)]) - return [hlist] + result = [Hlist([vlist, Hbox(thickness * 2.)])] + if ldelim or rdelim: + if ldelim == '': + ldelim = '.' + if rdelim == '': + rdelim = '.' + elif rdelim == r'\}': + rdelim = '}' + return self._auto_sized_delimiter(ldelim, result, rdelim) + return result + def genfrac(self, s, loc, toks): + assert(len(toks)==1) + assert(len(toks[0])==6) + + return self._genfrac(*tuple(toks[0])) + + def frac(self, s, loc, toks): + assert(len(toks)==1) + assert(len(toks[0])==2) + state = self.get_state() + + thickness = state.font_output.get_underline_thickness( + state.font, state.fontsize, state.dpi) + num, den = toks[0] + + return self._genfrac('', '', thickness, '', num, den) + + def stackrel(self, s, loc, toks): + assert(len(toks)==1) + assert(len(toks[0])==2) + num, den = toks[0] + + return self._genfrac('', '', 0.0, '', num, den) + + def binom(self, s, loc, toks): + assert(len(toks)==1) + assert(len(toks[0])==2) + num, den = toks[0] + + return self._genfrac('(', ')', 0.0, '', num, den) + def sqrt(self, s, loc, toks): #~ print "sqrt", toks root, body = toks[0] @@ -2756,9 +2835,7 @@ rightside]) # Body return [hlist] - def auto_sized_delimiter(self, s, loc, toks): - #~ print "auto_sized_delimiter", toks - front, middle, back = toks + def _auto_sized_delimiter(self, front, middle, back): state = self.get_state() height = max([x.height for x in middle]) depth = max([x.depth for x in middle]) @@ -2766,12 +2843,19 @@ # \left. and \right. aren't supposed to produce any symbols if front != '.': parts.append(AutoHeightChar(front, height, depth, state)) - parts.extend(middle.asList()) + parts.extend(middle) if back != '.': parts.append(AutoHeightChar(back, height, depth, state)) hlist = Hlist(parts) return hlist + + def auto_sized_delimiter(self, s, loc, toks): + #~ print "auto_sized_delimiter", toks + front, middle, back = toks + + return self._auto_sized_delimiter(front, middle.asList(), back) + ### ############################################################################## Modified: trunk/matplotlib/lib/matplotlib/testing/decorators.py =================================================================== --- trunk/matplotlib/lib/matplotlib/testing/decorators.py 2009-12-03 19:24:30 UTC (rev 8004) +++ trunk/matplotlib/lib/matplotlib/testing/decorators.py 2009-12-03 20:21:21 UTC (rev 8005) @@ -88,7 +88,7 @@ orig_expected_fnames = [os.path.join(baseline_dir,fname) + '.' + extension for fname in baseline_images] expected_fnames = [os.path.join(result_dir,'expected-'+fname) + '.' + extension for fname in baseline_images] for src,dst in zip( orig_expected_fnames, expected_fnames ): - if not os.path.exists(dst): + if os.path.exists(src) and not os.path.exists(dst): shutil.copyfile(src,dst) actual_fnames = [os.path.join(result_dir, fname) + '.' + extension for fname in baseline_images] have_baseline_images = [os.path.exists(expected) for expected in expected_fnames] Added: trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext.pdf =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext.pdf (rev 0) +++ trunk/matplotlib/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext.pdf 2009-12-03 20:21:21 UTC (rev 8005) @@ -0,0 +1,2076 @@ +%PDF-1.4 +%\xAC\xDC \xAB\xBA +1 0 obj +<< /Type /Catalog /Pages 2 0 R >> +endobj +8 0 obj +<< /XObject 7 0 R /Pattern 5 0 R +/ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ExtGState 4 0 R +/Shading 6 0 R /Font 3 0 R >> +endobj +10 0 obj +<< /Contents 9 0 R /Type /Page /Resources 8 0 R /Parent 2 0 R +/MediaBox [ 0 0 360 2268 ] >> +endobj +9 0 obj +<< /Filter /FlateDecode /Length 11 0 R >> +stream +x\x9C\xED\{\xAF\xB7q\xFF\xFF~\x8A\xD34E\xAFa\x9C5\xDF\xB7\x8A \xB1\x93\xFC\xA4UZ\xB9(Ȗ\xE4J\x96d=\xC0N\x81|\xBB\xE9#\x9AčS\xA4\xAD\xEC\xB4M?Xg\x96C\xEE\x90K\xEE\xD9s\xAF\x8A&\x818\x92\xF6p\x87\xDC\xE1<~\xF3 \xE5\xE1\xFE\x85:|\xF3 \xEF\xC0o\\x88\x838<<h\x87>\x98\xFFT\xCA\xF8+\xFB\xFCr\xF1\xF9M\xF8\xDB;\xF0\xDFO.$\xFCy9\x8F\xD3\xEA\xF0\xF6Ë\xAF܀1rr^o7n_\xBC\xF2\xBA<Hu\xB8q\xF7\xE2\xF2\xD6K\x87\xF7/\xC2d\x8C\xD2:e\xE1\xBDy\x84\xCA#^\x9EGH1 o}\x90ˈB\xE3\xADy\x84\x9F\x94\xF5F\xCDs\xF4i(;yu\xFE=S\x96\x93py\xEE)\xFD\x8E\xBF~w\xFE\xF5(\xA6>;\xB2\xD9\xE4\xCFhr\xAF\x84\x96\xC3\xE5\xED\xC6\xC5\xA4\x91m\xE9o\xDAO\xD1\xFA\xF4Za\xF0\xEB\x95?\xBB\xF1\x8D\x9Bo\xDCyt\xE7\xE9\xAD\xC7;\xDC{\xFC\xEC\xC3W\xF8v\x87\x88\x8F\x93\xB6\xD68|w'\x91o7\xDB$\xA3+ۤ\xFB\xDB\xF4AbU\x98\xA4r\xD2/<\xBE\xFCp\xFCy\xBE\xCE9#\x90\xB1z\xB4\xB2\xEF=\xBA\xA7\x94\x83\x85\x81\xD4兩\xA9\xAC\xCA\xE4U}\x99x\xEF\xB4\xF1n\x9EK9x.\xCE|>\xCD\xCF\xF5\xA41v\xD9ݳ\xE9\xFAt\x92\xDFt1V"l\xF3\x88\xEFfF\xAF\x98\xA4̢db\xF2Y\xFE@\xA7\x93̤*\xE6,\xFF\xDB\xFF\xC6EfR\xAF&5\x9At\xD4\xCE\x96\x87\xF4\xA9Aɖ\x97\x8E \xF7j\xD6\xE4\x86>\xA6賊\xB3X+?\xD9e\xC6 \xFE\xEF\xE9\x9D\xC3\xDD\xC3Z^DL\x90I\xB3z\x82\xEC\xA6`\xA2\xE3\xB6\xE0\xC3{\x85U\x8C\xA6\x92\xE4\xD2~\xBE K\xD3\xC7I\xAD-[\xD6iگ\xBDhڗL㍶\xCC"_c\x89\xAF\x92\xF8\xFBҿMz\xBDYD\xAD\xFBW\xB8"\xC3V\xF8'\xF4\xA6V\xE0۸j\x96ؓɌgC6\xA9\x9A\xABT\xA1\xFF\xAF?\xA0\xC4f\x85W\x97\xDF\xFC!}\xBDU!\x8A\xF1\xA7\xED\xE7\xFEk\xD5\xCA\xD3\xDBv +A-ҷ\x83\xE5_\xE6Tv0Z\xC6 \xF6y\xA9-f\xFC:i\x8B\x9A|e\xA1\xAF\xCE +F;\xD0甼\xCA&n\xD1\xFE\xE8\xCA*\xA3a\xFEa\xF2ɤ\xEE2\x8A\xAF\xBC\xEE\xEBv\xAA\xF47\xB4\xEF\xAFVW\xD6\x93v&#\x95V>\xAE^\xEC4\xE9h+\x99\x9F#\xBC\xAB\xDCU\xFE\xC1N\xCA{\xAFM\xBB +\xE7\xB1a\xBDAF\x80ũ\xF66\xBF\xBF\xFA\xB2<\x85\x9Ad-\xB5\x9F<C\xCAf"\xC3;g\xCC\xDF\xF9#\xE2r\xB1\xE8U\xB3I\xAD\xD9\xF9V_/\x9F\x92wv\xB1\xC0[\x95J\xBFM\x9B\xAD\xACwg\xF0\xFCQ\xF5*\xD0\xC2ۅ\x95o\xF8\xF1\x90z1\xA3 +\xF8\xAC |
From: <lee...@us...> - 2009-12-09 20:29:17
|
Revision: 8014 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8014&view=rev Author: leejjoon Date: 2009-12-09 20:29:10 +0000 (Wed, 09 Dec 2009) Log Message: ----------- print out more meaningful messages when legend is called with artists that are not supported Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/legend.py trunk/matplotlib/lib/matplotlib/offsetbox.py Modified: trunk/matplotlib/lib/matplotlib/legend.py =================================================================== --- trunk/matplotlib/lib/matplotlib/legend.py 2009-12-08 02:12:38 UTC (rev 8013) +++ trunk/matplotlib/lib/matplotlib/legend.py 2009-12-09 20:29:10 UTC (rev 8014) @@ -432,14 +432,6 @@ ) labelboxes = [] - - for l in labels: - textbox = TextArea(l, textprops=label_prop, - multilinebaseline=True, minimumdescent=True) - text_list.append(textbox._text) - - labelboxes.append(textbox) - handleboxes = [] @@ -457,7 +449,8 @@ # default trasnform (eg, Collections), you need to # manually set their transform to the self.get_transform(). - for handle in handles: + + for handle, lab in zip(handles, labels): if isinstance(handle, RegularPolyCollection) or \ isinstance(handle, CircleCollection): npoints = self.scatterpoints @@ -578,32 +571,47 @@ p.set_clip_path(None) handle_list.append(p) else: + handle_type = type(handle) + warnings.warn("Legend does not support %s\nUse proxy artist instead.\n\nhttp://matplotlib.sourceforge.net/users/legend_guide.html#using-proxy-artist\n" % (str(handle_type),)) handle_list.append(None) - handlebox = DrawingArea(width=self.handlelength*fontsize, - height=height, - xdescent=0., ydescent=descent) + handle = handle_list[-1] - handlebox.add_artist(handle) - if hasattr(handle, "_legmarker"): - handlebox.add_artist(handle._legmarker) - handleboxes.append(handlebox) + if handle is not None: # handle is None is the artist is not supproted + textbox = TextArea(lab, textprops=label_prop, + multilinebaseline=True, minimumdescent=True) + text_list.append(textbox._text) + + labelboxes.append(textbox) + handlebox = DrawingArea(width=self.handlelength*fontsize, + height=height, + xdescent=0., ydescent=descent) - # We calculate number of lows in each column. The first - # (num_largecol) columns will have (nrows+1) rows, and remaing - # (num_smallcol) columns will have (nrows) rows. - ncol = min(self._ncol, len(handleboxes)) - nrows, num_largecol = divmod(len(handleboxes), ncol) - num_smallcol = ncol-num_largecol + handlebox.add_artist(handle) + if hasattr(handle, "_legmarker"): + handlebox.add_artist(handle._legmarker) + handleboxes.append(handlebox) - # starting index of each column and number of rows in it. - largecol = safezip(range(0, num_largecol*(nrows+1), (nrows+1)), - [nrows+1] * num_largecol) - smallcol = safezip(range(num_largecol*(nrows+1), len(handleboxes), nrows), - [nrows] * num_smallcol) + if len(handleboxes) > 0: + + # We calculate number of lows in each column. The first + # (num_largecol) columns will have (nrows+1) rows, and remaing + # (num_smallcol) columns will have (nrows) rows. + ncol = min(self._ncol, len(handleboxes)) + nrows, num_largecol = divmod(len(handleboxes), ncol) + num_smallcol = ncol-num_largecol + + # starting index of each column and number of rows in it. + largecol = safezip(range(0, num_largecol*(nrows+1), (nrows+1)), + [nrows+1] * num_largecol) + smallcol = safezip(range(num_largecol*(nrows+1), len(handleboxes), nrows), + [nrows] * num_smallcol) + else: + largecol, smallcol = [], [] + handle_label = safezip(handleboxes, labelboxes) columnbox = [] for i0, di in largecol+smallcol: Modified: trunk/matplotlib/lib/matplotlib/offsetbox.py =================================================================== --- trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-12-08 02:12:38 UTC (rev 8013) +++ trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-12-09 20:29:10 UTC (rev 8014) @@ -375,6 +375,9 @@ whd_list = [c.get_extent(renderer) for c in self.get_visible_children()] + if not whd_list: + return 2*pad, 2*pad, pad, pad, [] + if self.height is None: height_descent = max([h-yd for w,h,xd,yd in whd_list]) ydescent = max([yd for w,h,xd,yd in whd_list]) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lee...@us...> - 2009-12-17 19:31:31
|
Revision: 8037 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8037&view=rev Author: leejjoon Date: 2009-12-17 19:31:21 +0000 (Thu, 17 Dec 2009) Log Message: ----------- draw_image api to use an arbitrary affine transform Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/image.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-12-16 19:21:44 UTC (rev 8036) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-12-17 19:31:21 UTC (rev 8037) @@ -386,14 +386,15 @@ """ return True - def draw_image(self, gc, x, y, im, sx=None, sy=None): + def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None): """ Draw the Image instance into the current axes; x is the distance in pixels from the left hand side of the canvas and y is the distance from bottom - bbox is a matplotlib.transforms.BBox instance for clipping, or - None + dx, dy is the width and height of the image. If a transform + (which must be an affine transform) is given, x, y, dx, dy are + interpreted as the coordinate of the transform. """ im.flipud_out() @@ -406,13 +407,22 @@ imagecmd = "false 3 colorimage" hexlines = '\n'.join(self._hex_lines(bits)) - if sx is None: - sx = 1./self.image_magnification - if sy is None: - sy = 1./self.image_magnification - - xscale, yscale = (w*sx, h*sy) - + if dx is None: + xscale = w / self.image_magnification + else: + xscale = dx + + if dy is None: + yscale = h/self.image_magnification + else: + yscale = dy + + + if transform is None: + matrix = "1 0 0 1 0 0" + else: + matrix = " ".join(map(str, transform.to_values())) + figh = self.height*72 #print 'values', origin, flipud, figh, h, y @@ -431,6 +441,7 @@ #y = figh-(y+h) ps = """gsave %(clip)s +[%(matrix)s] concat %(x)s %(y)s translate %(xscale)s %(yscale)s scale /DataString %(w)s string def Modified: trunk/matplotlib/lib/matplotlib/image.py =================================================================== --- trunk/matplotlib/lib/matplotlib/image.py 2009-12-16 19:21:44 UTC (rev 8036) +++ trunk/matplotlib/lib/matplotlib/image.py 2009-12-17 19:31:21 UTC (rev 8037) @@ -144,7 +144,7 @@ sy = dyintv/viewlim.height numrows, numcols = A.shape[:2] if sx > 2: - x0 = (viewim.x0-xmin)/dxintv * numcols + x0 = (viewlim.x0-xmin)/dxintv * numcols ix0 = max(0, int(x0 - self._filterrad)) x1 = (viewlim.x1-xmin)/dxintv * numcols ix1 = min(numcols, int(x1 + self._filterrad)) @@ -170,7 +170,7 @@ ymin = ymin_old + iy0*dyintv/numrows ymax = ymin_old + iy1*dyintv/numrows dyintv = ymax - ymin - sy = dyintv/self.axes.viewLim.height + sy = dyintv/viewlim.height else: yslice = slice(0, numrows) @@ -203,7 +203,7 @@ return im, xmin, ymin, dxintv, dyintv, sx, sy - + def _draw_unsampled_image(self, renderer, gc): """ draw unsampled image. The renderer should support a draw_image method @@ -213,10 +213,6 @@ self._get_unsampled_image(self._A, self.get_extent(), self.axes.viewLim) if im is None: return # I'm not if this check is required. -JJL - - transData = self.axes.transData - xx1, yy1 = transData.transform_point((xmin, ymin)) - xx2, yy2 = transData.transform_point((xmin+dxintv, ymin+dyintv)) fc = self.axes.patch.get_facecolor() bg = mcolors.colorConverter.to_rgba(fc, 0) @@ -228,19 +224,23 @@ im.resize(numcols, numrows) # just to create im.bufOut that is required by backends. There may be better solution -JJL - sx = (xx2-xx1)/numcols - sy = (yy2-yy1)/numrows im._url = self.get_url() - renderer.draw_image(gc, xx1, yy1, im, sx, sy) - + trans = self.get_transform() #axes.transData + xx1, yy1 = trans.transform_non_affine((xmin, ymin)) + xx2, yy2 = trans.transform_non_affine((xmin+dxintv, ymin+dyintv)) + + renderer.draw_image(gc, xx1, yy1, im, xx2-xx1, yy2-yy1, + trans.get_affine()) + + def _check_unsampled_image(self, renderer): """ return True if the image is better to be drawn unsampled. The derived class needs to override it. """ return False - + @allow_rasterization def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <as...@us...> - 2009-12-21 02:24:28
|
Revision: 8047 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8047&view=rev Author: astraw Date: 2009-12-21 02:24:14 +0000 (Mon, 21 Dec 2009) Log Message: ----------- spines: attempt to fix initial placement bug Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/spines.py Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2009-12-21 00:47:49 UTC (rev 8046) +++ trunk/matplotlib/lib/matplotlib/axes.py 2009-12-21 02:24:14 UTC (rev 8047) @@ -2065,9 +2065,6 @@ other.figure.canvas is not None): other.figure.canvas.draw_idle() - for loc in ('bottom','top'): - self.spines[loc].set_bounds(xmin,xmax) - return xmin, xmax def get_xscale(self): @@ -2242,9 +2239,6 @@ other.figure.canvas is not None): other.figure.canvas.draw_idle() - for loc in ('left','right'): - self.spines[loc].set_bounds(ymin,ymax) - return ymin, ymax def get_yscale(self): Modified: trunk/matplotlib/lib/matplotlib/spines.py =================================================================== --- trunk/matplotlib/lib/matplotlib/spines.py 2009-12-21 00:47:49 UTC (rev 8046) +++ trunk/matplotlib/lib/matplotlib/spines.py 2009-12-21 02:24:14 UTC (rev 8047) @@ -11,6 +11,7 @@ import matplotlib.patches as mpatches import matplotlib.path as mpath import matplotlib.cbook as cbook +import numpy as np import warnings class Spine(mpatches.Patch): @@ -57,6 +58,8 @@ self.set_zorder(2.5) self.set_transform(self.axes.transData) # default transform + self._bounds = None # default bounds + # Defer initial position determination. (Not much support for # non-rectangular axes is currently implemented, and this lets # them pass through the spines machinery without errors.) @@ -138,6 +141,39 @@ if self.axis is not None: self.axis.cla() + def _adjust_location(self): + """automatically set spine bounds to the view interval""" + + if self.spine_type == 'circle': + return + + if self._bounds is None: + if self.spine_type in ('left','right'): + low,high = self.axes.viewLim.intervaly + elif self.spine_type in ('top','bottom'): + low,high = self.axes.viewLim.intervalx + else: + raise ValueError('unknown spine spine_type: %s'%self.spine_type) + else: + low,high = self._bounds + + v1 = self._path.vertices[:] # copy + assert v1.shape == (2,2), 'unexpected vertices shape' + if self.spine_type in ['left','right']: + v1[0,1] = low + v1[1,1] = high + elif self.spine_type in ['bottom','top']: + v1[0,0] = low + v1[1,0] = high + else: + raise ValueError('unable to set bounds for spine "%s"'%spine_type) + self._path.vertices = v1 # replace + + @allow_rasterization + def draw(self, renderer): + self._adjust_location() + return super( Spine, self).draw(renderer) + def _calc_offset_transform(self): """calculate the offset transform performed by the spine""" self._ensure_position_is_set() @@ -280,17 +316,10 @@ raise ValueError("unknown spine_transform type: %s"%what) def set_bounds( self, low, high ): - v1 = self._path.vertices[:] # copy - assert v1.shape == (2,2), 'unexpected vertices shape' - if self.spine_type in ['left','right']: - v1[0,1] = low - v1[1,1] = high - elif self.spine_type in ['bottom','top']: - v1[0,0] = low - v1[1,0] = high - else: - raise ValueError('unable to set bounds for spine "%s"'%spine_type) - self._path.vertices = v1 # replace + if self.spine_type == 'circle': + raise ValueError( + 'set_bounds() method incompatible with circular spines') + self._bounds = (low, high) @classmethod def linear_spine(cls, axes, spine_type, **kwargs): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |