From: <lee...@us...> - 2009-05-07 03:40:46
|
Revision: 7089 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7089&view=rev Author: leejjoon Date: 2009-05-07 03:40:40 +0000 (Thu, 07 May 2009) Log Message: ----------- per-artist rasterization Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/artist.py trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/axis.py trunk/matplotlib/lib/matplotlib/collections.py trunk/matplotlib/lib/matplotlib/figure.py trunk/matplotlib/lib/matplotlib/image.py trunk/matplotlib/lib/matplotlib/legend.py trunk/matplotlib/lib/matplotlib/lines.py trunk/matplotlib/lib/matplotlib/patches.py trunk/matplotlib/lib/matplotlib/quiver.py trunk/matplotlib/lib/matplotlib/table.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/CHANGELOG 2009-05-07 03:40:40 UTC (rev 7089) @@ -1,4 +1,6 @@ ====================================================================== +2009-05-06 Per-artist Rasterization, originally by Eric Bruning. -JJ + 2009-05-05 Add an example that shows how to make a plot that updates using data from another process. Thanks to Robert Cimrman - RMM Modified: trunk/matplotlib/lib/matplotlib/artist.py =================================================================== --- trunk/matplotlib/lib/matplotlib/artist.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/artist.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -22,6 +22,38 @@ # http://groups.google.com/groups?hl=en&lr=&threadm=mailman.5090.1098044946.5135.python-list%40python.org&rnum=1&prev=/groups%3Fq%3D__doc__%2Bauthor%253Ajdhunter%2540ace.bsd.uchicago.edu%26hl%3Den%26btnG%3DGoogle%2BSearch + + +def allow_rasterization(draw): + """ + Decorator for Artist.draw method. Provides routines + that run before and after the draw call. The before and after functions + are useful for changing artist-dependant renderer attributes or making + other setup function calls, such as starting and flushing a mixed-mode + renderer. + """ + def before(artist, renderer): + if artist.get_rasterized(): + renderer.start_rasterizing() + + def after(artist, renderer): + if artist.get_rasterized(): + renderer.stop_rasterizing() + + # the axes class has a second argument inframe for its draw method. + def draw_wrapper(artist, renderer, *kl): + before(artist, renderer) + draw(artist, renderer, *kl) + after(artist, renderer) + + # "safe wrapping" to exactly replicate anything we haven't overridden above + draw_wrapper.__name__ = draw.__name__ + draw_wrapper.__dict__ = draw.__dict__ + draw_wrapper.__doc__ = draw.__doc__ + draw_wrapper._supports_rasterization = True + return draw_wrapper + + class Artist(object): """ Abstract base class for someone who renders into a @@ -45,6 +77,7 @@ self._label = '' self._picker = None self._contains = None + self._rasterized = None self.eventson = False # fire events only if eventson self._oid = 0 # an observer id @@ -510,7 +543,23 @@ else: gc.set_clip_rectangle(None) gc.set_clip_path(None) + + def get_rasterized(self): + return self._rasterized + + def set_rasterized(self, rasterized): + """ + Force rasterized (bitmap) drawing in vector backend output. + + Defaults to None, which implies the backend's default behavior + + ACCEPTS: [True | False | None] + """ + if rasterized and not hasattr(self.draw, "_supports_rasterization"): + warnings.warn("Rasterization of '%s' will be ignored" % self) + self._rasterized = rasterized + def draw(self, renderer, *args, **kwargs): 'Derived classes drawing method' if not self.get_visible(): return Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/axes.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -1602,6 +1602,7 @@ #### Drawing + @allow_rasterization def draw(self, renderer=None, inframe=False): "Draw everything (plot lines, axes, labels)" if renderer is None: Modified: trunk/matplotlib/lib/matplotlib/axis.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axis.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/axis.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -5,6 +5,7 @@ from matplotlib import rcParams import matplotlib.artist as artist +from matplotlib.artist import allow_rasterization import matplotlib.cbook as cbook import matplotlib.font_manager as font_manager import matplotlib.lines as mlines @@ -176,6 +177,7 @@ 'Return the tick location (data coords) as a scalar' return self._loc + @allow_rasterization def draw(self, renderer): if not self.get_visible(): return renderer.open_group(self.__name__) @@ -719,6 +721,7 @@ bbox2 = mtransforms.Bbox.from_extents(0, 0, 0, 0) return bbox, bbox2 + @allow_rasterization def draw(self, renderer, *args, **kwargs): 'Draw the axis lines, grid lines, tick lines and labels' ticklabelBoxes = [] Modified: trunk/matplotlib/lib/matplotlib/collections.py =================================================================== --- trunk/matplotlib/lib/matplotlib/collections.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/collections.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -17,6 +17,7 @@ import matplotlib.cm as cm import matplotlib.transforms as transforms import matplotlib.artist as artist +from matplotlib.artist import allow_rasterization import matplotlib.backend_bases as backend_bases import matplotlib.path as mpath import matplotlib.mlab as mlab @@ -190,6 +191,7 @@ return transform, transOffset, offsets, paths + @allow_rasterization def draw(self, renderer): if not self.get_visible(): return renderer.open_group(self.__class__.__name__) @@ -594,6 +596,7 @@ def get_datalim(self, transData): return self._bbox + @allow_rasterization def draw(self, renderer): if not self.get_visible(): return renderer.open_group(self.__class__.__name__) @@ -781,6 +784,7 @@ __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd + @allow_rasterization def draw(self, renderer): self._transforms = [ transforms.Affine2D().rotate(-self._rotation).scale( Modified: trunk/matplotlib/lib/matplotlib/figure.py =================================================================== --- trunk/matplotlib/lib/matplotlib/figure.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/figure.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -15,7 +15,7 @@ import time import artist -from artist import Artist +from artist import Artist, allow_rasterization from axes import Axes, SubplotBase, subplot_class_factory from cbook import flatten, allequal, Stack, iterable, dedent import _image @@ -727,6 +727,7 @@ """ self.clf() + @allow_rasterization def draw(self, renderer): """ Render the figure using :class:`matplotlib.backend_bases.RendererBase` instance renderer Modified: trunk/matplotlib/lib/matplotlib/image.py =================================================================== --- trunk/matplotlib/lib/matplotlib/image.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/image.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -11,6 +11,7 @@ from matplotlib import rcParams import matplotlib.artist as martist +from matplotlib.artist import allow_rasterization import matplotlib.colors as mcolors import matplotlib.cm as cm import matplotlib.cbook as cbook @@ -225,7 +226,7 @@ norm=self._filternorm, radius=self._filterrad) return im - + @allow_rasterization def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return if (self.axes.get_xscale() != 'linear' or @@ -571,6 +572,7 @@ im.is_grayscale = self.is_grayscale return im + @allow_rasterization def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return im = self.make_image(renderer.get_image_magnification()) @@ -723,6 +725,7 @@ return im + @allow_rasterization def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return # todo: we should be able to do some cacheing here Modified: trunk/matplotlib/lib/matplotlib/legend.py =================================================================== --- trunk/matplotlib/lib/matplotlib/legend.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/legend.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -26,7 +26,7 @@ import numpy as np from matplotlib import rcParams -from matplotlib.artist import Artist +from matplotlib.artist import Artist, allow_rasterization from matplotlib.cbook import is_string_like, iterable, silent_list, safezip from matplotlib.font_manager import FontProperties from matplotlib.lines import Line2D @@ -323,6 +323,7 @@ return x+xdescent, y+ydescent + @allow_rasterization def draw(self, renderer): "Draw everything that belongs to the legend" if not self.get_visible(): return Modified: trunk/matplotlib/lib/matplotlib/lines.py =================================================================== --- trunk/matplotlib/lib/matplotlib/lines.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/lines.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -18,6 +18,8 @@ from transforms import Affine2D, Bbox, TransformedPath, IdentityTransform from matplotlib import rcParams +from artist import allow_rasterization + # special-purpose marker identifiers: (TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN, CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN) = range(8) @@ -459,6 +461,7 @@ if len(x)<2: return 1 return np.alltrue(x[1:]-x[0:-1]>=0) + @allow_rasterization def draw(self, renderer): if self._invalid: self.recache() Modified: trunk/matplotlib/lib/matplotlib/patches.py =================================================================== --- trunk/matplotlib/lib/matplotlib/patches.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/patches.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -7,6 +7,7 @@ import numpy as np import matplotlib.cbook as cbook import matplotlib.artist as artist +from matplotlib.artist import allow_rasterization import matplotlib.colors as colors import matplotlib.transforms as transforms from matplotlib.path import Path @@ -260,7 +261,7 @@ 'Return the current hatching pattern' return self._hatch - + @allow_rasterization def draw(self, renderer): 'Draw the :class:`Patch` to the given *renderer*.' if not self.get_visible(): return @@ -1176,6 +1177,7 @@ self.theta2 = theta2 __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd + @allow_rasterization def draw(self, renderer): """ Ellipses are normally drawn using an approximation that uses Modified: trunk/matplotlib/lib/matplotlib/quiver.py =================================================================== --- trunk/matplotlib/lib/matplotlib/quiver.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/quiver.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -21,6 +21,7 @@ import matplotlib.transforms as transforms import matplotlib.text as mtext import matplotlib.artist as martist +from matplotlib.artist import allow_rasterization import matplotlib.font_manager as font_manager from matplotlib.cbook import delete_masked_points from matplotlib.patches import CirclePolygon @@ -282,6 +283,7 @@ else: return y + @allow_rasterization def draw(self, renderer): self._init() self.vector.draw(renderer) @@ -418,6 +420,7 @@ if self.width is None: self.width = 0.06 * self.span / sn + @allow_rasterization def draw(self, renderer): self._init() if self._new_UV or self.angles == 'xy': Modified: trunk/matplotlib/lib/matplotlib/table.py =================================================================== --- trunk/matplotlib/lib/matplotlib/table.py 2009-05-06 23:02:57 UTC (rev 7088) +++ trunk/matplotlib/lib/matplotlib/table.py 2009-05-07 03:40:40 UTC (rev 7089) @@ -23,7 +23,7 @@ import warnings import artist -from artist import Artist +from artist import Artist, allow_rasterization from patches import Rectangle from cbook import is_string_like from text import Text @@ -90,6 +90,7 @@ return fontsize + @allow_rasterization def draw(self, renderer): if not self.get_visible(): return # draw the rectangle @@ -215,6 +216,7 @@ def _approx_text_height(self): return self.FONTSIZE/72.0*self.figure.dpi/self._axes.bbox.height * 1.2 + @allow_rasterization def draw(self, renderer): # Need a renderer to do hit tests on mouseevent; assume the last one will do if renderer is None: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |