distorted patches

I've been rewriting the Arrow class in patches.py to improve the look of quiver plots and am getting generally good results. The problems with current quiver plots are that arrows representing very small values are scaled along their length but not in width and also that arrowheads are not of a constant size. I have addressed both of these problems and getting results much more like Matlab quiver plots now. However, now that I am scaling arrow patches down to very small sizes, I see weird shaped arrows at some zoom levels but when I zoom in close enough to see the shape properly they look nicely formed. Is there a known problem, perhaps with Agg doing some fancy truncation in order to achieve good speed, where patches are distorted if their vertices are very close together at a particular magnification? I can provide code and graphic examples if it would help.

Gary R.

Gary Ruben wrote:

I've been rewriting the Arrow class in patches.py to improve the look of quiver plots and am getting generally good results. The problems with current quiver plots are that arrows representing very small values are scaled along their length but not in width and also that arrowheads are not of a constant size. I have addressed both of these problems and getting results much more like Matlab quiver plots now. However, now that I am scaling arrow patches down to very small sizes, I see weird shaped arrows at some zoom levels but when I zoom in close enough to see the shape properly they look nicely formed. Is there a known problem, perhaps with Agg doing some fancy truncation in order to achieve good speed, where patches are distorted if their vertices are very close together at a particular magnification? I can provide code and graphic examples if it would help.

Wow, serendipitously I'm working on exactly the same thing at the moment. Question: when you zoom, do you ensure that the x-direction in your window is the same length as the y-direction? My current theory on this is the distorted arrows are the result of quiver measuring everything in the x-y space of the plot, instead of in absolute terms. Setting axis('equal') or axis('scaled') seems to improve the arrow appearance...

Jordan

Hi Jordan,
When I zoom, if the x and y zooms are not locked you will still get the problem you mention with my modified arrows. They're still just patches locked to the current x and y coordinates.
I've attached my modified Arrow() in case you want to look at it. It requires a change to quiver in axes.py too to add the arrowstyle parameter and pass it through but you can just ignore that stuff and remove the arrowstyle references if you want to try it out. The changes just keep the arrow head length fixed and adjust the length of the arrow shaft until it gets so short that it becomes necessary to start scaling down the width in proportion with the length (I'm not sure if that makes sense).
Gary

Jordan Dawe wrote:
<snip>

modarrow.txt (1.14 KB)

···

Wow, serendipitously I'm working on exactly the same thing at the moment. Question: when you zoom, do you ensure that the x-direction in your window is the same length as the y-direction? My current theory on this is the distorted arrows are the result of quiver measuring everything in the x-y space of the plot, instead of in absolute terms. Setting axis('equal') or axis('scaled') seems to improve the arrow appearance...

Jordan

Gary Ruben wrote:

Hi Jordan,
When I zoom, if the x and y zooms are not locked you will still get the problem you mention with my modified arrows. They're still just patches locked to the current x and y coordinates.
I've attached my modified Arrow() in case you want to look at it. It requires a change to quiver in axes.py too to add the arrowstyle parameter and pass it through but you can just ignore that stuff and remove the arrowstyle references if you want to try it out. The changes just keep the arrow head length fixed and adjust the length of the arrow shaft until it gets so short that it becomes necessary to start scaling down the width in proportion with the length (I'm not sure if that makes sense).
Gary

That makes a lot of sense. I've just been changing this line:

    arrow[:,1] *= width

to

    arrow[:,1] *= L*width

but this, of course, ends up with some weird looking arrows at the ends of the data range

The main problem with quiver as it currently exists is that, if say you plot:

quiver(ones([1,2]),ones([1,2]))

You end up with arrows that are twice as tall as they are wide, instead of 45 degree arrows. This is definitely a bug, not a feature.

Here's a reference talking about the different coordinate systems accessible in matplotlib:

http://www.scipy.org/Cookbook/Matplotlib/Transformations

I think what we need is to set the coordinate transform to be in and absolute, instead of relative, coordinate system, or to build one ourselves. But I don't know enough about matplotlib's internals to know if this is right. Comments?

Jordan