collection initializer color handling vs quiver

from collections import LineCollection
class Arrow(LineCollection):
    """
    An arrow
    """
    def __init__( self, x, y, dx, dy, width=1.0, arrowstyle='solid', **kwargs ):
        """Draws an arrow, starting at (x,y), direction and length
        given by (dx,dy) the width of the arrow is scaled by width.
        arrowstyle may be 'solid' or 'barbed'
        """
        L = math.hypot(dx,dy) or 1 # account for div by zero
        S = 0.1
        arrow = {'barbed': array([[0.,0.], [L,0.], [L-S,S/3],
                                  [L,0.], [L,-S/3], [L,0.]]),
                 'solid': array([[0.,0.], [L-S,0.], [L-S,S/3],
                                  [L,0.], [L-S,-S/3], [L-S,0.]])
                }[arrowstyle]

        cx = float(dx)/L
        sx = float(dy)/L
        M = array([[cx, sx], [-sx, cx]])
        verts = matrixmultiply(arrow, M) + [x,y]
        LineCollection.__init__(self, [tuple(t) for t in verts], **kwargs)

I've found one problem with your Arrow LineCollection; it's not actually a line collection. It's one line, so some of the LineCollection functions fail on it. You need to break up the arrow into segments, like this:

'barbed': array([ [ [0.,0.], [L,0.] ],
                          [ [L,0.], [L-S,S/3] ],
                          [ [L,0.], [L-S,-S/3] ] ]

Except just doing this will break the matrixmultiply. Just a heads-up.

Jordan

Hi Jordan,

Thanks for your heads-up. I actually left this and went back to using polygon patches for the arrows, mainly because I thought I'd have more control over the size without having to do any fancy line collection stuff. Re. your change, the call to the LineCollection__init__ function in axes.py just needs an extra set of 's around the list comprehension and all is OK, but your solution could work too.
I do intend to look again at the transform stuff to try to get arrows transforming properly - just very busy at the moment, but then I usually am.

Gary R.

···

I've found one problem with your Arrow LineCollection; it's not actually a line collection. It's one line, so some of the LineCollection functions fail on it. You need to break up the arrow into segments, like this:

'barbed': array([ [ [0.,0.], [L,0.] ],
                         [ [L,0.], [L-S,S/3] ],
                         [ [L,0.], [L-S,-S/3] ] ]

Except just doing this will break the matrixmultiply. Just a heads-up.

Jordan