From: <jd...@us...> - 2010-02-17 02:33:08
|
Revision: 8138 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8138&view=rev Author: jdh2358 Date: 2010-02-17 02:33:01 +0000 (Wed, 17 Feb 2010) Log Message: ----------- added TJ's filled marker patch Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/lines.py trunk/matplotlib/lib/matplotlib/path.py Added Paths: ----------- trunk/matplotlib/examples/pylab_examples/filledmarker_demo.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2010-02-17 02:15:13 UTC (rev 8137) +++ trunk/matplotlib/CHANGELOG 2010-02-17 02:33:01 UTC (rev 8138) @@ -1,3 +1,7 @@ +2010-02-16 Committed TJ's filled marker patch for + left|right|bottom|top|full filled markers. See + examples/pylab_examples/filledmarker_demo.py. JDH + 2010-02-11 Added 'bootstrap' option to boxplot. This allows bootstrap estimates of median confidence intervals. Based on an initial patch by Paul Hobson. - ADS Added: trunk/matplotlib/examples/pylab_examples/filledmarker_demo.py =================================================================== --- trunk/matplotlib/examples/pylab_examples/filledmarker_demo.py (rev 0) +++ trunk/matplotlib/examples/pylab_examples/filledmarker_demo.py 2010-02-17 02:33:01 UTC (rev 8138) @@ -0,0 +1,38 @@ +import itertools + +import numpy as np +import matplotlib.lines as mlines +import matplotlib.pyplot as plt + +colors = itertools.cycle(['b', 'g', 'r', 'c', 'm', 'y', 'k']) +altcolor = 'lightgreen' + +plt.rcParams['text.usetex'] = False # otherwise, '^' will cause trouble + +y = np.arange(10) +for marker in mlines.Line2D.filled_markers: + f = plt.figure() + f.text(.5,.95, "marker = %r" % marker, ha='center') + for i,fs in enumerate(mlines.Line2D.fillStyles): + color = colors.next() + + ax = f.add_subplot(121) + ax.plot(2*(4-i)+y, c=color, + marker=marker, + markersize=20, + fillstyle=fs, + label=fs) + ax.legend(loc=2) + ax.set_title('fillstyle') + + ax = f.add_subplot(122) + ax.plot(2*(4-i)+y, c=color, + marker=marker, + markersize=20, + markerfacecoloralt=altcolor, + fillstyle=fs, + label=fs) + ax.legend(loc=2) + ax.set_title('fillstyle') + +plt.show() Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2010-02-17 02:15:13 UTC (rev 8137) +++ trunk/matplotlib/lib/matplotlib/axes.py 2010-02-17 02:33:01 UTC (rev 8138) @@ -62,9 +62,21 @@ # Is fmt just a colorspec? try: color = mcolors.colorConverter.to_rgb(fmt) - return linestyle, marker, color # Yes. + + # We need to differentiate grayscale '1.0' from tri_down marker '1' + try: + fmtint = str(int(fmt)) + except ValueError: + return linestyle, marker, color # Yes + else: + if fmt != fmtint: + # user definitely doesn't want tri_down marker + return linestyle, marker, color # Yes + else: + # ignore converted color + color = None except ValueError: - pass # No, not just a color. + pass # No, not just a color. # handle the multi char special cases and strip them from the # string Modified: trunk/matplotlib/lib/matplotlib/lines.py =================================================================== --- trunk/matplotlib/lib/matplotlib/lines.py 2010-02-17 02:15:13 UTC (rev 8137) +++ trunk/matplotlib/lib/matplotlib/lines.py 2010-02-17 02:33:01 UTC (rev 8138) @@ -142,6 +142,8 @@ filled_markers = ('o', '^', 'v', '<', '>', 's', 'd', 'D', 'h', 'H', 'p', '*') + fillStyles = ('full', 'left' , 'right' , 'bottom' , 'top') + zorder = 2 validCap = ('butt', 'round', 'projecting') validJoin = ('miter', 'round', 'bevel') @@ -167,6 +169,7 @@ markeredgewidth = None, markeredgecolor = None, markerfacecolor = None, + markerfacecoloralt = 'none', fillstyle = 'full', antialiased = None, dash_capstyle = None, @@ -232,6 +235,7 @@ self.set_markerfacecolor(markerfacecolor) + self.set_markerfacecoloralt(markerfacecoloralt) self.set_markeredgecolor(markeredgecolor) self.set_markeredgewidth(markeredgewidth) self.set_fillstyle(fillstyle) @@ -336,7 +340,7 @@ ACCEPTS: ['full' | 'left' | 'right' | 'bottom' | 'top'] """ - assert fs in ['full', 'left' , 'right' , 'bottom' , 'top'] + assert fs in self.fillStyles self._fillstyle = fs def set_markevery(self, every): @@ -586,18 +590,25 @@ return self._markeredgecolor def get_markeredgewidth(self): return self._markeredgewidth - def get_markerfacecolor(self): - if (self._markerfacecolor is None or - (is_string_like(self._markerfacecolor) and - self._markerfacecolor.lower()=='none') ): - return self._markerfacecolor - elif (is_string_like(self._markerfacecolor) and - self._markerfacecolor.lower() == 'auto'): + def _get_markerfacecolor(self, alt=False): + if alt: + fc = self._markerfacecoloralt + else: + fc = self._markerfacecolor + + if (fc is None or (is_string_like(fc) and fc.lower()=='none') ): + return fc + elif (is_string_like(fc) and fc.lower() == 'auto'): return self._color else: - return self._markerfacecolor + return fc + def get_markerfacecolor(self): + return self._get_markerfacecolor(alt=False) + def get_markerfacecoloralt(self): + return self._get_markerfacecolor(alt=True) + def get_markersize(self): return self._markersize def get_data(self, orig=True): @@ -820,14 +831,26 @@ def set_markerfacecolor(self, fc): """ - Set the marker face color + Set the marker face color. ACCEPTS: any matplotlib color """ - if fc is None : + if fc is None: fc = 'auto' + self._markerfacecolor = fc + def set_markerfacecoloralt(self, fc): + """ + Set the alternate marker face color. + + ACCEPTS: any matplotlib color + """ + if fc is None: + fc = 'auto' + + self._markerfacecoloralt = fc + def set_markersize(self, sz): """ Set the marker size in points @@ -872,6 +895,7 @@ def _draw_lines(self, renderer, gc, path, trans): self._lineFunc(renderer, gc, path, trans) + def _draw_mathtext_path(self, renderer, gc, path, trans): """ Draws mathtext markers '$...$' using TextPath object. @@ -904,6 +928,7 @@ rgbFace = self._get_rgb_face() renderer.draw_markers(gc, text, path_trans, path, trans, rgbFace) + def _draw_steps_pre(self, renderer, gc, path, trans): vertices = self._xy steps = ma.zeros((2*len(vertices)-1, 2), np.float_) @@ -915,6 +940,7 @@ path = path.transformed(self.get_transform()) self._lineFunc(renderer, gc, path, IdentityTransform()) + def _draw_steps_post(self, renderer, gc, path, trans): vertices = self._xy steps = ma.zeros((2*len(vertices)-1, 2), np.float_) @@ -926,6 +952,7 @@ path = path.transformed(self.get_transform()) self._lineFunc(renderer, gc, path, IdentityTransform()) + def _draw_steps_mid(self, renderer, gc, path, trans): vertices = self._xy steps = ma.zeros((2*len(vertices), 2), np.float_) @@ -944,10 +971,12 @@ def _draw_nothing(self, *args, **kwargs): pass + def _draw_solid(self, renderer, gc, path, trans): gc.set_linestyle('solid') renderer.draw_path(gc, path, trans) + def _draw_dashed(self, renderer, gc, path, trans): gc.set_linestyle('dashed') if self._dashSeq is not None: @@ -967,100 +996,146 @@ def _draw_point(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') - + # just like _draw_circle + gc.set_snap(renderer.points_to_pixels(self._markersize) > 3.0) w = renderer.points_to_pixels(self._markersize) * \ self._point_size_reduction * 0.5 - gc.set_snap(renderer.points_to_pixels(self._markersize) > 3.0) + transform = Affine2D().scale(w) rgbFace = self._get_rgb_face() - transform = Affine2D().scale(w) - renderer.draw_markers( - gc, Path.unit_circle(), transform, path, path_trans, - rgbFace) + fs = self.get_fillstyle() + if fs=='full': + renderer.draw_markers( + gc, Path.unit_circle(), transform, path, path_trans, rgbFace) + else: + rgbFace_alt = self._get_rgb_face(alt=True) + # build a right-half circle + if fs=='bottom': rotate = 270. + elif fs=='top': rotate = 90. + elif fs=='left': rotate = 180. + else: rotate = 0. + righthalf = Path.unit_circle_righthalf() + transform = transform.rotate_deg(rotate) + renderer.draw_markers(gc, righthalf, transform, + path, path_trans, rgbFace) + transform = transform.rotate_deg(180.) + renderer.draw_markers(gc, righthalf, transform, + path, path_trans, rgbFace_alt) + + _draw_pixel_transform = Affine2D().translate(-0.5, -0.5) def _draw_pixel(self, renderer, gc, path, path_trans): + gc.set_snap(False) + rgbFace = self._get_rgb_face() fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') - - rgbFace = self._get_rgb_face() - gc.set_snap(False) + # There is no visible difference, so always paint it 'full' renderer.draw_markers(gc, Path.unit_rectangle(), self._draw_pixel_transform, path, path_trans, rgbFace) def _draw_circle(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') - + gc.set_snap(renderer.points_to_pixels(self._markersize) > 3.0) w = renderer.points_to_pixels(self._markersize) * 0.5 - gc.set_snap(renderer.points_to_pixels(self._markersize) > 3.0) + transform = Affine2D().scale(w, w) rgbFace = self._get_rgb_face() - transform = Affine2D().scale(w, w) - renderer.draw_markers( - gc, Path.unit_circle(), transform, path, path_trans, - rgbFace) + fs = self.get_fillstyle() + if fs=='full': + renderer.draw_markers(gc, Path.unit_circle(), transform, + path, path_trans, rgbFace) + else: + rgbFace_alt = self._get_rgb_face(alt=True) + # build a right-half circle + if fs=='bottom': rotate = 270. + elif fs=='top': rotate = 90. + elif fs=='left': rotate = 180. + else: rotate = 0. + righthalf = Path.unit_circle_righthalf() + transform = transform.rotate_deg(rotate) + renderer.draw_markers(gc, righthalf, transform, + path, path_trans, rgbFace) + transform = transform.rotate_deg(180.) + renderer.draw_markers(gc, righthalf, transform, + path, path_trans, rgbFace_alt) + _triangle_path = Path([[0.0, 1.0], [-1.0, -1.0], [1.0, -1.0], [0.0, 1.0]]) - def _draw_triangle_up(self, renderer, gc, path, path_trans): - - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') - + # Going down halfway looks to small. Golden ratio is too far. + _triangle_path_u = Path([[0.0, 1.0], [-3/5., -1/5.], [3/5., -1/5.], [0.0, 1.0]]) + _triangle_path_d = Path([[-3/5., -1/5.], [3/5., -1/5.], [1.0, -1.0], [-1.0, -1.0], [-3/5., -1/5.]]) + _triangle_path_l = Path([[0.0, 1.0], [0.0, -1.0], [-1.0, -1.0], [0.0, 1.0]]) + _triangle_path_r = Path([[0.0, 1.0], [0.0, -1.0], [1.0, -1.0], [0.0, 1.0]]) + def _draw_triangle(self, renderer, gc, path, path_trans, direction): gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) offset = 0.5*renderer.points_to_pixels(self._markersize) - transform = Affine2D().scale(offset, offset) + assert direction in ['up', 'down', 'left', 'right'] + if direction == 'up': + x,y = offset, offset + rot = 0.0 + skip = 0 + elif direction == 'down': + x,y = offset, offset + rot = 180.0 + skip = 2 + elif direction == 'left': + x,y = offset, offset + rot = 90.0 + skip = 3 + else: + x,y = offset, offset + rot = 270.0 + skip = 1 + transform = Affine2D().scale(x,y).rotate_deg(rot) rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, self._triangle_path, transform, - path, path_trans, rgbFace) + fs = self.get_fillstyle() + if fs=='full': + renderer.draw_markers(gc, self._triangle_path, transform, + path, path_trans, rgbFace) + else: + rgbFace_alt = self._get_rgb_face(alt=True) + mpaths = [self._triangle_path_u, + self._triangle_path_l, + self._triangle_path_d, + self._triangle_path_r] + + if fs=='top': + mpath = mpaths[(0+skip) % 4] + mpath_alt = mpaths[(2+skip) % 4] + elif fs=='bottom': + mpath = mpaths[(2+skip) % 4] + mpath_alt = mpaths[(0+skip) % 4] + elif fs=='left': + mpath = mpaths[(1+skip) % 4] + mpath_alt = mpaths[(3+skip) % 4] + else: + mpath = mpaths[(3+skip) % 4] + mpath_alt = mpaths[(1+skip) % 4] + + renderer.draw_markers(gc, mpath, transform, + path, path_trans, rgbFace) + renderer.draw_markers(gc, mpath_alt, transform, + path, path_trans, rgbFace_alt) + + + def _draw_triangle_up(self, renderer, gc, path, path_trans): + self._draw_triangle(renderer, gc, path, path_trans, 'up') + + def _draw_triangle_down(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') + self._draw_triangle(renderer, gc, path, path_trans, 'down') - gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) - offset = 0.5*renderer.points_to_pixels(self._markersize) - transform = Affine2D().scale(offset, -offset) - rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, self._triangle_path, transform, - path, path_trans, rgbFace) - def _draw_triangle_left(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') + self._draw_triangle(renderer, gc, path, path_trans, 'left') - gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) - offset = 0.5*renderer.points_to_pixels(self._markersize) - transform = Affine2D().scale(offset, offset).rotate_deg(90) - rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, self._triangle_path, transform, - path, path_trans, rgbFace) - def _draw_triangle_right(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') + self._draw_triangle(renderer, gc, path, path_trans, 'right') - gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) - offset = 0.5*renderer.points_to_pixels(self._markersize) - transform = Affine2D().scale(offset, offset).rotate_deg(-90) - rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, self._triangle_path, transform, - path, path_trans, rgbFace) - def _draw_square(self, renderer, gc, path, path_trans): gc.set_snap(renderer.points_to_pixels(self._markersize) >= 2.0) side = renderer.points_to_pixels(self._markersize) @@ -1071,6 +1146,7 @@ renderer.draw_markers(gc, Path.unit_rectangle(), transform, path, path_trans, rgbFace) else: + rgbFace_alt = self._get_rgb_face(alt=True) # build a bottom filled square out of two rectangles, one # filled. Use the rotation to support left, right, bottom # or top @@ -1080,86 +1156,226 @@ else: rotate = 90. bottom = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 0.5], [0.0, 0.5], [0.0, 0.0]]) - top = Path([[0.0, 0.5], [1.0, 0.5], [1.0, 1.0], [0.0, 1.0], [0.0, 0.05]]) + top = Path([[0.0, 0.5], [1.0, 0.5], [1.0, 1.0], [0.0, 1.0], [0.0, 0.5]]) transform = transform.rotate_deg(rotate) renderer.draw_markers(gc, bottom, transform, path, path_trans, rgbFace) renderer.draw_markers(gc, top, transform, - path, path_trans, None) + path, path_trans, rgbFace_alt) + def _draw_diamond(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) side = renderer.points_to_pixels(self._markersize) transform = Affine2D().translate(-0.5, -0.5).rotate_deg(45).scale(side) + rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, Path.unit_rectangle(), transform, - path, path_trans, rgbFace) + fs = self.get_fillstyle() + if fs=='full': + renderer.draw_markers(gc, Path.unit_rectangle(), transform, + path, path_trans, rgbFace) + else: + right = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]) + left = Path([[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [0.0, 0.0]]) + if fs=='bottom': rotate = 270. + elif fs=='top': rotate = 90. + elif fs=='left': rotate = 180. + else: rotate = 0. + transform = transform.rotate_deg(rotate) + rgbFace_alt = self._get_rgb_face(alt=True) + + renderer.draw_markers(gc, right, transform, + path, path_trans, rgbFace) + renderer.draw_markers(gc, left, transform, + path, path_trans, rgbFace_alt) + + def _draw_thin_diamond(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') gc.set_snap(renderer.points_to_pixels(self._markersize) >= 3.0) offset = renderer.points_to_pixels(self._markersize) transform = Affine2D().translate(-0.5, -0.5) \ - .rotate_deg(45).scale(offset * 0.6, offset) + .rotate_deg(45) + rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, Path.unit_rectangle(), transform, - path, path_trans, rgbFace) + fs = self.get_fillstyle() + if fs=='full': + transform = transform.scale(offset * 0.6, offset) + renderer.draw_markers(gc, Path.unit_rectangle(), transform, + path, path_trans, rgbFace) + else: + right = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]) + left = Path([[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [0.0, 0.0]]) + if fs=='bottom': rotate = 270. + elif fs=='top': rotate = 90. + elif fs=='left': rotate = 180. + else: rotate = 0. + # scale after rotation + transform = transform.rotate_deg(rotate).scale(offset * 0.6, offset) + rgbFace_alt = self._get_rgb_face(alt=True) + + renderer.draw_markers(gc, right, transform, + path, path_trans, rgbFace) + renderer.draw_markers(gc, left, transform, + path, path_trans, rgbFace_alt) + + def _draw_pentagon(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) offset = 0.5 * renderer.points_to_pixels(self._markersize) transform = Affine2D().scale(offset) + rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, Path.unit_regular_polygon(5), transform, - path, path_trans, rgbFace) + fs = self.get_fillstyle() + polypath = Path.unit_regular_polygon(5) + + if fs == 'full': + renderer.draw_markers(gc, polypath, transform, + path, path_trans, rgbFace) + else: + verts = polypath.vertices + + y = (1+np.sqrt(5))/4. + top = Path([verts[0], verts[1], verts[4], verts[0]]) + bottom = Path([verts[1], verts[2], verts[3], verts[4], verts[1]]) + left = Path([verts[0], verts[1], verts[2], [0,-y], verts[0]]) + right = Path([verts[0], verts[4], verts[3], [0,-y], verts[0]]) + + if fs == 'top': + mpath, mpath_alt = top, bottom + elif fs == 'bottom': + mpath, mpath_alt = bottom, top + elif fs == 'left': + mpath, mpath_alt = left, right + else: + mpath, mpath_alt = right, left + + rgbFace_alt = self._get_rgb_face(alt=True) + renderer.draw_markers(gc, mpath, transform, + path, path_trans, rgbFace) + renderer.draw_markers(gc, mpath_alt, transform, + path, path_trans, rgbFace_alt) + + def _draw_star(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) offset = 0.5 * renderer.points_to_pixels(self._markersize) transform = Affine2D().scale(offset) + rgbFace = self._get_rgb_face() - _starpath = Path.unit_regular_star(5, innerCircle=0.381966) - renderer.draw_markers(gc, _starpath, transform, - path, path_trans, rgbFace) + fs = self.get_fillstyle() + polypath = Path.unit_regular_star(5, innerCircle=0.381966) + if fs == 'full': + renderer.draw_markers(gc, polypath, transform, + path, path_trans, rgbFace) + else: + verts = polypath.vertices + + top = Path(np.vstack((verts[0:4,:], verts[7:10,:], verts[0]))) + bottom = Path(np.vstack((verts[3:8,:], verts[3]))) + left = Path(np.vstack((verts[0:6,:], verts[0]))) + right = Path(np.vstack((verts[0], verts[5:10,:], verts[0]))) + + if fs == 'top': + mpath, mpath_alt = top, bottom + elif fs == 'bottom': + mpath, mpath_alt = bottom, top + elif fs == 'left': + mpath, mpath_alt = left, right + else: + mpath, mpath_alt = right, left + + rgbFace_alt = self._get_rgb_face(alt=True) + renderer.draw_markers(gc, mpath, transform, + path, path_trans, rgbFace) + renderer.draw_markers(gc, mpath_alt, transform, + path, path_trans, rgbFace_alt) + + def _draw_hexagon1(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') - gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) + gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) offset = 0.5 * renderer.points_to_pixels(self._markersize) transform = Affine2D().scale(offset) + rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, Path.unit_regular_polygon(6), transform, - path, path_trans, rgbFace) + fs = self.get_fillstyle() + polypath = Path.unit_regular_polygon(6) + if fs == 'full': + renderer.draw_markers(gc, polypath, transform, + path, path_trans, rgbFace) + else: + verts = polypath.vertices + + # not drawing inside lines + x = abs(np.cos(5*np.pi/6.)) + top = Path(np.vstack(([-x,0],verts[(1,0,5),:],[x,0]))) + bottom = Path(np.vstack(([-x,0],verts[2:5,:],[x,0]))) + left = Path(verts[(0,1,2,3),:]) + right = Path(verts[(0,5,4,3),:]) + + if fs == 'top': + mpath, mpath_alt = top, bottom + elif fs == 'bottom': + mpath, mpath_alt = bottom, top + elif fs == 'left': + mpath, mpath_alt = left, right + else: + mpath, mpath_alt = right, left + + rgbFace_alt = self._get_rgb_face(alt=True) + renderer.draw_markers(gc, mpath, transform, + path, path_trans, rgbFace) + renderer.draw_markers(gc, mpath_alt, transform, + path, path_trans, rgbFace_alt) + + def _draw_hexagon2(self, renderer, gc, path, path_trans): - fs = self.get_fillstyle() - if fs!='full': - raise NotImplementedError('non-full markers have not been implemented for this marker style yet; please contribute') - gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) + gc.set_snap(renderer.points_to_pixels(self._markersize) >= 5.0) offset = 0.5 * renderer.points_to_pixels(self._markersize) transform = Affine2D().scale(offset).rotate_deg(30) + rgbFace = self._get_rgb_face() - renderer.draw_markers(gc, Path.unit_regular_polygon(6), transform, - path, path_trans, rgbFace) + fs = self.get_fillstyle() + polypath = Path.unit_regular_polygon(6) + if fs == 'full': + renderer.draw_markers(gc, polypath, transform, + path, path_trans, rgbFace) + else: + verts = polypath.vertices + + # not drawing inside lines + x, y = np.sqrt(3)/4, 3/4. + top = Path(verts[(1,0,5,4,1),:]) + bottom = Path(verts[(1,2,3,4),:]) + left = Path(np.vstack(([x,y],verts[(0,1,2),:],[-x,-y],[x,y]))) + right = Path(np.vstack(([x,y],verts[(5,4,3),:],[-x,-y]))) + + if fs == 'top': + mpath, mpath_alt = top, bottom + elif fs == 'bottom': + mpath, mpath_alt = bottom, top + elif fs == 'left': + mpath, mpath_alt = left, right + else: + mpath, mpath_alt = right, left + + rgbFace_alt = self._get_rgb_face(alt=True) + renderer.draw_markers(gc, mpath, transform, + path, path_trans, rgbFace) + renderer.draw_markers(gc, mpath_alt, transform, + path, path_trans, rgbFace_alt) + + _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]]) def _draw_vline(self, renderer, gc, path, path_trans): gc.set_snap(renderer.points_to_pixels(self._markersize) >= 1.0) @@ -1314,6 +1530,7 @@ self._color = other._color self._markersize = other._markersize self._markerfacecolor = other._markerfacecolor + self._markerfacecoloralt = other._markerfacecoloralt self._markeredgecolor = other._markeredgecolor self._markeredgewidth = other._markeredgewidth self._fillstyle = other._fillstyle @@ -1329,8 +1546,8 @@ self._drawstyle = other._drawstyle - def _get_rgb_face(self): - facecolor = self.get_markerfacecolor() + def _get_rgb_face(self, alt=False): + facecolor = self._get_markerfacecolor(alt=alt) if is_string_like(facecolor) and facecolor.lower()=='none': rgbFace = None else: @@ -1369,8 +1586,11 @@ def set_mfc(self, val): 'alias for set_markerfacecolor' - self.set_markerfacecolor(val) + self.set_markerfacecolor(val, alt=alt) + def set_mfcalt(self, val): + 'alias for set_markerfacecoloralt' + self.set_markerfacecoloralt(val) def set_ms(self, val): 'alias for set_markersize' @@ -1409,6 +1629,9 @@ 'alias for get_markerfacecolor' return self.get_markerfacecolor() + def get_mfcalt(self, alt=False): + 'alias for get_markerfacecoloralt' + return self.get_markerfacecoloralt() def get_ms(self): 'alias for get_markersize' @@ -1577,6 +1800,7 @@ lineStyles = Line2D._lineStyles lineMarkers = Line2D._markers drawStyles = Line2D.drawStyles +fillStyles = Line2D.fillStyles docstring.interpd.update(Line2D = artist.kwdoc(Line2D)) Modified: trunk/matplotlib/lib/matplotlib/path.py =================================================================== --- trunk/matplotlib/lib/matplotlib/path.py 2010-02-17 02:15:13 UTC (rev 8137) +++ trunk/matplotlib/lib/matplotlib/path.py 2010-02-17 02:33:01 UTC (rev 8138) @@ -500,7 +500,55 @@ cls._unit_circle = cls(vertices, codes) return cls._unit_circle + _unit_circle_righthalf = None + @classmethod + def unit_circle_righthalf(cls): + """ + (staticmethod) Returns a :class:`Path` of the right half + of a unit circle. The circle is approximated using cubic Bezier + curves. This uses 4 splines around the circle using the approach + presented here: + + Lancaster, Don. `Approximating a Circle or an Ellipse Using Four + Bezier Cubic Splines <http://www.tinaja.com/glib/ellipse4.pdf>`_. + """ + if cls._unit_circle_righthalf is None: + MAGIC = 0.2652031 + SQRTHALF = np.sqrt(0.5) + MAGIC45 = np.sqrt((MAGIC*MAGIC) / 2.0) + + vertices = np.array( + [[0.0, -1.0], + + [MAGIC, -1.0], + [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45], + [SQRTHALF, -SQRTHALF], + + [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45], + [1.0, -MAGIC], + [1.0, 0.0], + + [1.0, MAGIC], + [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45], + [SQRTHALF, SQRTHALF], + + [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45], + [MAGIC, 1.0], + [0.0, 1.0], + + [0.0, -1.0]], + + np.float_) + + codes = cls.CURVE4 * np.ones(14) + codes[0] = cls.MOVETO + codes[-1] = cls.CLOSEPOLY + + cls._unit_circle_righthalf = cls(vertices, codes) + return cls._unit_circle_righthalf + + @classmethod def arc(cls, theta1, theta2, n=None, is_wedge=False): """ (staticmethod) Returns an arc on the unit circle from angle This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |