Hi,

We found we needed to draw a partial ring, but didn't see one in patches.py.

Attached is a generalization of Wedge to accept an inner and an outer radius.

Should I add this to patches?

Note that rather saving the unit ring and constructing a transform as in Wedge:

    def get_patch_transform(self):
        x = self.convert_xunits(self.center[0])
        y = self.convert_yunits(self.center[1])
        rx = self.convert_xunits(self.r2)
        ry = self.convert_yunits(self.r2)
        self._patch_transform = transforms.Affine2D() \
            .scale(rx, ry).translate(x, y)
        return self._patch_transform

I just transform the coordinates directly:

        v *= r2
        v += numpy.array(center)
        self._path = Path(v,c)
        self._patch_transform = transforms.IdentityTransform()

Any reason to prefer one over the other?

  - Paul


from math import fmod
import numpy

import matplotlib.cbook as cbook
import matplotlib.transforms as transforms
import matplotlib.artist as artist
import matplotlib.patches as patches
from matplotlib.path import Path


class Ring(patches.Patch):
    """
    Ring patch.
    """
    def __str__(self):
        return "Ring(%g,%g,%g,%g)"%(self.r1,self.r2,self.theta1,self.theta2)

    def __init__(self,
                 center=(0,0),
                 r1=0,
                 r2=None,
                 theta1=0,
                 theta2=360,
                 **kwargs
                 ):
        """
        Draw a ring centered at *x*, *y* center with inner radius *r1* and
        outer radius *r2* that sweeps *theta1* to *theta2* (in degrees).

        Valid kwargs are:

        %(Patch)s
        """
        patches.Patch.__init__(self, **kwargs)
        self.center = center
        self.r1, self.r2 = r1,r2
        self.theta1, self.theta2 = theta1,theta2

        # Inner and outer rings are connected unless the annulus is complete
        delta=abs(theta2-theta1)
        if fmod(delta,360)<=1e-12*delta:
            theta1,theta2 = 0,360
            connector = Path.MOVETO
        else:
            connector = Path.LINETO

        # Form the outer ring
        arc = Path.arc(theta1,theta2)

        if r1 > 0:
            # Partial annulus needs to draw the outter ring
            # followed by a reversed and scaled inner ring
            v1 = arc.vertices
            v2 = arc.vertices[::-1]*float(r1)/r2
            v = numpy.vstack([v1,v2,v1[0,:],(0,0)])
            c = numpy.hstack([arc.codes,arc.codes,connector,Path.CLOSEPOLY])
            c[len(arc.codes)]=connector
        else:
            # Wedge doesn't need an inner ring
            v = numpy.vstack([arc.vertices,[(0,0),arc.vertices[0,:],(0,0)]])
            c = numpy.hstack([arc.codes,[connector,connector,Path.CLOSEPOLY]])

        v *= r2
        v += numpy.array(center)
        self._path = Path(v,c)
        self._patch_transform = transforms.IdentityTransform()
    __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd

    def get_path(self):
        return self._path


def demo():
    import pylab
    axes = pylab.gca()

    # Full ring
    axes.add_patch(Ring(center=(3,3),r1=4, r2=7,theta1=70,theta2=70,
                        fill=True,fc='yellow',ec='darkblue',alpha=0.5))
    # Full circle
    axes.add_patch(Ring(center=(-3,-3),r2=4,
                        fill=True,fc='purple',ec='darkblue',alpha=0.6))
    # Filled segment
    axes.add_patch(Ring(r1=5,r2=10,theta1=0,theta2=90,
                        fill=True,fc='gray',ec='black',alpha=0.2))
    # Unfilled segment
    axes.add_patch(Ring(r1=6,r2=8,theta1=30,theta2=280,fill=False,ec='black'))
    # Overlapping segment
    axes.add_patch(Ring(r1=3,r2=9,theta1=80,theta2=130,
                        fill=True,fc='orange',ec='black',alpha=0.2))
    # Unfilled wedge
    axes.add_patch(Ring(r2=7,theta1=170,theta2=220,
                        fill=False,fc='orange',ec='green',alpha=0.2))
    # Wedge
    axes.add_patch(Ring(r2=7,theta1=70,theta2=220,
                        fill=False,fc='blue',ec='darkblue',alpha=0.6))

#    # Wedge
#    from matplotlib.patches import Wedge
#    axes.add_patch(Wedge((0,0),r=7,theta1=70,theta2=220,
#                       fill=False,fc='blue',ec='darkblue',alpha=0.6))

    pylab.axis('equal')
#    pylab.axis([-10,10,-10,10])
    pylab.show()


if __name__ == "__main__": demo()



One problem is that I had to explicitly set the axes limits 1because add_patch
wasn't updating the limits to include the bounds of the new patch.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to