Thoughts on quiver2

Eric-

I had a chance to play around with the new quiver this morning. Here are some thoughts:

1. I read that somebody thought it was a bit slow, but this is not my experience. I tried to quiver my model data (128x128 with masking), and it rendered in a few seconds. I tried to look at images with more arrows, but I could not actually see the arrows with so many points. In my experience you can't put more than about O(100000) (i.e., about 100x100) arrows on a figure and have it make any sense anyways.

2. It seems to handle masking fine. I gave it masked arrays and arrays with nans (it complained a bit about the masked array, but rendered anyways). This is key for me.

3. It handles colors nicely, but there is no apparent way to set the color limits. Perhaps adding vmin and vmax as kwargs (matching pcolor) would make some sense.

4. I *really* like how the arrows get gray (and don't try to render at a whole pixel) when they get small. I agree with the other person that it might be nice to have a small dot to indicate zero velocity. No dot should be rendered *ever* for values masked or NaNed, however.

5. It's a bit of a pain to find values of scale and width that work well, and quiver doesn't seem to make very good choices by default. I don't think this is a big deal, but rather simply the price of the added functionality. Making some more intelligent default choices might not be a bad idea, though. In particular, smaller arrows when there are more arrows to be rendered would be a good place to start.

Some ideas for future work:

1. I'm pretty happy with the polygons, but it would be nice to have line collections instead. This would also facilitate my next idea:

2. I would love to have a 'curly vector' tool. However, I'm not sure how much to put into the curly_quiver package, and how much work must be done by the user. I think that at a minimum, it would be nice to give curly lines (i.e., an additional dimension to u and v)that have arrows on the end of them, and leave it to the user to define what those lines are somehow. If these lines could change color along their track, then it would be the best thing ever made!

-Rob.

ยทยทยท

-----
Rob Hetland, Assistant Professor
Dept of Oceanography, Texas A&M University
p: 979-458-0096, f: 979-845-6331
e: hetland@...345..., w: http://pong.tamu.edu

Robert,

Thanks for the feedback. Comments are below. I think I addressed some items over the weekend, so the version in svn should work better than the one you tested, assuming you tested the original one I sent out as a diff.

Robert Hetland wrote:

Eric-

I had a chance to play around with the new quiver this morning. Here are some thoughts:

1. I read that somebody thought it was a bit slow, but this is not my experience. I tried to quiver my model data (128x128 with masking), and it rendered in a few seconds. I tried to look at images with more arrows, but I could not actually see the arrows with so many points. In my experience you can't put more than about O(100000) (i.e., about 100x100) arrows on a figure and have it make any sense anyways.

2. It seems to handle masking fine. I gave it masked arrays and arrays with nans (it complained a bit about the masked array, but rendered anyways). This is key for me.

Interesting. I did nothing to explicitly deal with masked arrays or nans, so how well this works may be backend-dependent and/or platform dependent. If this turns out to be a problem, I can put in more explicit handling of masks and nans, but it is likely to add overhead.

Question: should handling of masks apply to all input arrays, or is it enough to have it apply to U, V, and C? It doesn't matter so much for Quiver, but it is one of the differences between pcolor and pcolormesh--support of masked X, Y complicates the former and might be hard to add to the latter. I hope it is unnecessary.

3. It handles colors nicely, but there is no apparent way to set the color limits. Perhaps adding vmin and vmax as kwargs (matching pcolor) would make some sense.

This brings up a more general design question: when should functionality like this be added via kwargs versus other mechanisms? It would be nice to have more uniformity among classes and functions, so that the general strategy could be documented once for a whole bunch of functions, instead of being repeated, with variations, for each. This would go along with better factoring out of chunks of functionality. In the absence of a big push, all this is going to have to happen piecemeal if at all, and complicated by the demands of backwards compatibility.

Returning to the specific question, however, I left vmin and vmax out to keep things simple, with the idea that there are other standard ways of setting them: via an explicit norm kwarg, via the clim method of any scalar mappable (which the Quiver is, since it inherits from PolyCollection), and via the pylab clim command. If there is a consensus that scalar mappables should uniformly support the vmin and vmax kwargs directly, then I don't mind adding that. I can see the argument for uniformity, given that this is common among scalar mappables. Probably it could be factored out by inclusion in ScalarMappable.__init__.

4. I *really* like how the arrows get gray (and don't try to render at a whole pixel) when they get small. I agree with the other person that it might be nice to have a small dot to indicate zero velocity. No dot should be rendered *ever* for values masked or NaNed, however.

The graying is a function of the backend--specifically, whether rendering is antialiased.

The optional dot (actually a hexagon) for arrows below a threshold size is in svn, one of the changes I made over the weekend.

5. It's a bit of a pain to find values of scale and width that work well, and quiver doesn't seem to make very good choices by default. I don't think this is a big deal, but rather simply the price of the added functionality. Making some more intelligent default choices might not be a bad idea, though. In particular, smaller arrows when there are more arrows to be rendered would be a good place to start.

I changed the autoscaling so that both the length scale and the shaft width (and therefore the head size, which scales with shaft width) vary with the square root of the number of arrows, but with limits to prevent arrows from getting too large and fat or too small and thin. So I think you will find the svn version much improved in this regard.

Some ideas for future work:

1. I'm pretty happy with the polygons, but it would be nice to have line collections instead. This would also facilitate my next idea:

Not "line collections instead", but "in addition": the functionality and appearance are very different with polygons than with lines. I think I can add a line alternative with only a little extra code, but I won't even look at it again until this weekend, at the very earliest.

2. I would love to have a 'curly vector' tool. However, I'm not sure how much to put into the curly_quiver package, and how much work must be done by the user. I think that at a minimum, it would be nice to give curly lines (i.e., an additional dimension to u and v)that have arrows on the end of them, and leave it to the user to define what those lines are somehow. If these lines could change color along their track, then it would be the best thing ever made!

You can make curly lines with mapped colors using a LineCollection (recent change: it now inherits from ScalarMappable). Curly_quiver sounds like quite a different animal, though, and potentially much more difficult to do well; I don't think there would be much overlap with the present code in quiver, or with the code even after I add the line version.

Eric