From: <lee...@us...> - 2008-12-17 07:32:22
|
Revision: 6642 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6642&view=rev Author: leejjoon Date: 2008-12-17 07:32:18 +0000 (Wed, 17 Dec 2008) Log Message: ----------- added group id in Artist. added two svg filter example Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/artist.py trunk/matplotlib/lib/matplotlib/backend_bases.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/lines.py trunk/matplotlib/lib/matplotlib/patches.py trunk/matplotlib/lib/matplotlib/text.py Added Paths: ----------- trunk/matplotlib/examples/misc/svg_filter_line.py trunk/matplotlib/examples/misc/svg_filter_pie.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2008-12-17 00:55:52 UTC (rev 6641) +++ trunk/matplotlib/CHANGELOG 2008-12-17 07:32:18 UTC (rev 6642) @@ -1,3 +1,6 @@ +2008-12-17 Add group id support in artist. Two examples which + demostrate svg filter are added. -JJL + 2008-12-16 Another attempt to fix dpi-dependent behavior of Legend. -JJL 2008-12-16 Fixed dpi-dependent behavior of Legend and fancybox in Text. Added: trunk/matplotlib/examples/misc/svg_filter_line.py =================================================================== --- trunk/matplotlib/examples/misc/svg_filter_line.py (rev 0) +++ trunk/matplotlib/examples/misc/svg_filter_line.py 2008-12-17 07:32:18 UTC (rev 6642) @@ -0,0 +1,85 @@ +""" +Demonstrate SVG filtering effects which might be used with mpl. + +Note that the filtering effects are only effective if your svg rederer +support it. +""" + +import matplotlib + +matplotlib.use("Svg") + +import matplotlib.pyplot as plt +import matplotlib.transforms as mtransforms + +fig1 = plt.figure() +ax = fig1.add_axes([0.1, 0.1, 0.8, 0.8]) + +# draw lines +l1, = ax.plot([0.1, 0.5, 0.9], [0.1, 0.9, 0.5], "bo-", + mec="b", lw=5, ms=10, label="Line 1") +l2, = ax.plot([0.1, 0.5, 0.9], [0.5, 0.2, 0.7], "rs-", + mec="r", lw=5, ms=10, color="r", label="Line 2") + + +for l in [l1, l2]: + + # draw shadows with same lines with slight offset and gray colors. + + xx = l.get_xdata() + yy = l.get_ydata() + shadow, = ax.plot(xx, yy) + shadow.update_from(l) + + # adjust color + shadow.set_color("0.2") + # adjust zorder of the shadow lines so that it is drawn below the + # original lines + shadow.set_zorder(l.get_zorder()-0.5) + + # offset transform + ot = mtransforms.offset_copy(l.get_transform(), fig1, + x=4.0, y=-6.0, units='points') + + shadow.set_transform(ot) + + # set the id for a later use + shadow.set_gid(l.get_label()+"_shadow") + + +ax.set_xlim(0., 1.) +ax.set_ylim(0., 1.) + +# save the figure as a string in the svg format. +from StringIO import StringIO +f = StringIO() +plt.savefig(f, format="svg") + + +import xml.etree.cElementTree as ET + +# filter definition for a gaussian blur +filter_def = """ + <defs xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> + <filter id='dropshadow' height='1.2' width='1.2'> + <feGaussianBlur result='blur' stdDeviation='3'/> + </filter> + </defs> +""" + + +# read in the saved svg +tree, xmlid = ET.XMLID(f.getvalue()) + +# insert the filter definition in the svg dom tree. +tree.insert(0, ET.XML(filter_def)) + +for l in [l1, l2]: + # pick up the svg element with given id + shadow = xmlid[l.get_label()+"_shadow"] + # apply shdow filter + shadow.set("filter",'url(#dropshadow)') + +fn = "svg_filter_line.svg" +print "Saving '%s'" % fn +ET.ElementTree(tree).write(fn) Added: trunk/matplotlib/examples/misc/svg_filter_pie.py =================================================================== --- trunk/matplotlib/examples/misc/svg_filter_pie.py (rev 0) +++ trunk/matplotlib/examples/misc/svg_filter_pie.py 2008-12-17 07:32:18 UTC (rev 6642) @@ -0,0 +1,95 @@ +""" +Demonstrate SVG filtering effects which might be used with mpl. +The pie chart drawing code is borrowed from pie_demo.py + +Note that the filtering effects are only effective if your svg rederer +support it. +""" + + +import matplotlib +matplotlib.use("Svg") + +import matplotlib.pyplot as plt +from matplotlib.patches import Shadow + +# make a square figure and axes +fig1 = plt.figure(1, figsize=(6,6)) +ax = fig1.add_axes([0.1, 0.1, 0.8, 0.8]) + +labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' +fracs = [15,30,45, 10] + +explode=(0, 0.05, 0, 0) + +# We want to draw the shadow for each pie but we will not use "shadow" +# option as it does'n save the references to the shadow patches. +pies = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%') + +for w in pies[0]: + # set the id with the label. + w.set_gid(w.get_label()) + + # we don't want to draw the edge of the pie + w.set_ec("none") + +for w in pies[0]: + # create shadow patch + s = Shadow(w, -0.01, -0.01) + s.set_gid(w.get_gid()+"_shadow") + s.set_zorder(w.get_zorder() - 0.1) + ax.add_patch(s) + + +# save +from StringIO import StringIO +f = StringIO() +plt.savefig(f, format="svg") + +import xml.etree.cElementTree as ET + + +# filter definition for shadow using a gaussian blur +# and lighteneing effect. +# The lightnening filter is copied from http://www.w3.org/TR/SVG/filters.html + +# I tested it with Inkscape and Firefox3. "Gaussian blur" is supported +# in both, but the lightnening effect only in the inkscape. Also note +# that, inkscape's exporting also may not support it. + +filter_def = """ + <defs xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> + <filter id='dropshadow' height='1.2' width='1.2'> + <feGaussianBlur result='blur' stdDeviation='2'/> + </filter> + + <filter id='MyFilter' filterUnits='objectBoundingBox' x='0' y='0' width='1' height='1'> + <feGaussianBlur in='SourceAlpha' stdDeviation='4%' result='blur'/> + <feOffset in='blur' dx='4%' dy='4%' result='offsetBlur'/> + <feSpecularLighting in='blur' surfaceScale='5' specularConstant='.75' + specularExponent='20' lighting-color='#bbbbbb' result='specOut'> + <fePointLight x='-5000%' y='-10000%' z='20000%'/> + </feSpecularLighting> + <feComposite in='specOut' in2='SourceAlpha' operator='in' result='specOut'/> + <feComposite in='SourceGraphic' in2='specOut' operator='arithmetic' + k1='0' k2='1' k3='1' k4='0'/> + </filter> + </defs> +""" + + +tree, xmlid = ET.XMLID(f.getvalue()) + +# insert the filter definition in the svg dom tree. +tree.insert(0, ET.XML(filter_def)) + +for i, pie_name in enumerate(labels): + pie = xmlid[pie_name] + pie.set("filter", 'url(#MyFilter)') + + shadow = xmlid[pie_name + "_shadow"] + shadow.set("filter",'url(#dropshadow)') + +fn = "svg_filter_pie.svg" +print "Saving '%s'" % fn +ET.ElementTree(tree).write(fn) Modified: trunk/matplotlib/lib/matplotlib/artist.py =================================================================== --- trunk/matplotlib/lib/matplotlib/artist.py 2008-12-17 00:55:52 UTC (rev 6641) +++ trunk/matplotlib/lib/matplotlib/artist.py 2008-12-17 07:32:18 UTC (rev 6642) @@ -52,6 +52,7 @@ self.axes = None self._remove_method = None self._url = None + self._gid = None self.x_isdata = True # False to avoid updating Axes.dataLim with x self.y_isdata = True # with y self._snap = None @@ -330,9 +331,26 @@ def set_url(self, url): """ Sets the url for the artist + + ACCEPTS: a url string """ self._url = url + + def get_gid(self): + """ + Returns the group id + """ + return self._gid + + def set_gid(self, gid): + """ + Sets the (group) id for the artist + + ACCEPTS: an id string + """ + self._gid = gid + def get_snap(self): """ Returns the snap setting which may be: Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-12-17 00:55:52 UTC (rev 6641) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2008-12-17 07:32:18 UTC (rev 6642) @@ -52,10 +52,11 @@ def __init__(self): self._texmanager = None - def open_group(self, s): + def open_group(self, s, gid=None): """ - Open a grouping element with label *s*. Is only currently used by - :mod:`~matplotlib.backends.backend_svg` + Open a grouping element with label *s*. If *gid* is given, use + *gid* as the id of the group. Is only currently used by + :mod:`~matplotlib.backends.backend_svg`. """ pass Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2008-12-17 00:55:52 UTC (rev 6641) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2008-12-17 07:32:18 UTC (rev 6642) @@ -147,9 +147,16 @@ self._clipd[path] = id return id - def open_group(self, s): - self._groupd[s] = self._groupd.get(s,0) + 1 - self._svgwriter.write('<g id="%s%d">\n' % (s, self._groupd[s])) + def open_group(self, s, gid=None): + """ + Open a grouping element with label *s*. If *gid* is given, use + *gid* as the id of the group. + """ + if gid: + self._svgwriter.write('<g id="%s">\n' % (gid)) + else: + self._groupd[s] = self._groupd.get(s,0) + 1 + self._svgwriter.write('<g id="%s%d">\n' % (s, self._groupd[s])) def close_group(self, s): self._svgwriter.write('</g>\n') Modified: trunk/matplotlib/lib/matplotlib/lines.py =================================================================== --- trunk/matplotlib/lib/matplotlib/lines.py 2008-12-17 00:55:52 UTC (rev 6641) +++ trunk/matplotlib/lib/matplotlib/lines.py 2008-12-17 07:32:18 UTC (rev 6642) @@ -463,7 +463,7 @@ if self._invalid: self.recache() - renderer.open_group('line2d') + renderer.open_group('line2d', self.get_gid()) if not self._visible: return gc = renderer.new_gc() Modified: trunk/matplotlib/lib/matplotlib/patches.py =================================================================== --- trunk/matplotlib/lib/matplotlib/patches.py 2008-12-17 00:55:52 UTC (rev 6641) +++ trunk/matplotlib/lib/matplotlib/patches.py 2008-12-17 07:32:18 UTC (rev 6642) @@ -264,7 +264,8 @@ def draw(self, renderer): 'Draw the :class:`Patch` to the given *renderer*.' if not self.get_visible(): return - #renderer.open_group('patch') + + renderer.open_group('patch', self.get_gid()) gc = renderer.new_gc() if cbook.is_string_like(self._edgecolor) and self._edgecolor.lower()=='none': @@ -300,7 +301,7 @@ renderer.draw_path(gc, tpath, affine, rgbFace) - #renderer.close_group('patch') + renderer.close_group('patch') def get_path(self): """ Modified: trunk/matplotlib/lib/matplotlib/text.py =================================================================== --- trunk/matplotlib/lib/matplotlib/text.py 2008-12-17 00:55:52 UTC (rev 6641) +++ trunk/matplotlib/lib/matplotlib/text.py 2008-12-17 07:32:18 UTC (rev 6642) @@ -447,6 +447,8 @@ if not self.get_visible(): return if self._text=='': return + renderer.open_group('text', self.get_gid()) + bbox, info = self._get_layout(renderer) trans = self.get_transform() @@ -499,6 +501,8 @@ self._fontproperties, angle, ismath=ismath) + renderer.close_group('text') + def get_color(self): "Return the color of the text" return self._color This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |