How does Python's matplotlib.pyplot.quiver exactly work?
matplotlib quiver does auto scaling. Set the scale to 1
to get your 0.2 units in x an y:
x = np.linspace(0,1,11)
y = np.linspace(1,0,11)
u = v = np.zeros((11,11))
u[5,5] = 0.2
plt.quiver(x, y, u, v, scale=1)
If you don't set scale
, matplotlib uses an auto scaling algorithm based on the average vector length and the number of vectors. Since you only have one vector with a length greater zero, it becomes really big. Adding more vectors makes the arrows successively smaller.
To have equal x and y extensions of your arrow a few more adjustments are needed:
x = np.linspace(0,1,11)
y = np.linspace(1,0,11)
u = v = np.zeros((11,11))
u[5,5] = 0.2
plt.axis('equal')
plt.quiver(x, y, u, v, scale=1, units='xy')
Both axes need to be equal and the units need to be set to xy
.
Not related to your problem, but interesting to mention: Funny thing is that by writing u[5, 5] = 0.2
you are implyingv[5, 5] = 0.2
as well (as shown in your diagonal arrow), since before you wrote u = v = np.zeros((11, 11))
. You could avoid that by writing
u = np.zeros((11, 11))
v = np.zeros((11, 11))
to make u
and v
independent from each other.
The quiver function visualizes a vector field, like this:
(from the examples page). In this type of plot, the vector at a point represents the magnitude of the field vector at that point. For example, if you're visualizing velocity of a fluid, the length of the arrow represents the speed of the fluid.
You can think of a vector field as a function mapping input (position) to output (the vector, e.g. velocity). The output values have no relation to the input positions; in particular, they may not even be measured in the same units! So a quiver plot can only show the relative magnitude of the field at different points - only the relative lengths of the arrows are meaningful, not their absolute lengths.
In other words, you shouldn't expect a field value of 0.2 to be represented by an arrow of length 0.2 in data units.
However, matplotlib provides an option you can specify to do that: the scale_units
option to quiver
. According to the documentation, you can give scale_units = 'xy'
and it will render the arrow lengths using the same units as the axes.