Search code examples
pythonmatplotlibipython

quiver wind arrows are too lengthy for scale=1 and does not match the key arrow


All,

The argument scale=1 of the matplotlib quiver (wind plot) function produces lengthy arrows extending beyond the figure limits. On the other hand, using scale=None seems to yield a logical arrow length. Any insights on this?

Beside print(ax_left.scale), which must print None, yields 127.27 if only executed inside the IPython console. Any ideas?

Lastly, given that the U=5, which should have the same constant length as the plotted arrows, 5, the length of the arrow key, surprisingly, does not match exactly the length of the wind arrows.

Thanks

enter image description here

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,200,9)
y = np.linspace(0,100,5)
X,Y = np.meshgrid(x,y)
U = 5*np.ones_like(X)
V = 5*np.ones_like(Y)

#%% understanding "scale"
plt.close('all')
fig, ax = plt.subplots(1,2)
ax_left=ax[0].quiver(x, y, U, V,scale=None)
ax[0].quiverkey(ax_left,X=0.8,Y=1.05,U=3.5,label='unit',labelpos='W')
ax[0].set_title('')
print('scale is '+str(ax_left.scale))

ax_right=ax[1].quiver(x, y, U, V,scale=1)
ax[0].quiverkey(ax_right,X=0.8,Y=1.05,U=3.5,label='unit',labelpos='W')
ax[1].set_title('')
print('scale is '+str(ax_right.scale))
plt.savefig('test.png')

Solution

  • As per the documentation under the scale_units section:

    To plot vectors in the x-y plane, with u and v having the same units as x and y, use angles='xy', scale_units='xy', scale=1.

    I also adjusted the width to make the arrows look nicer.

    import numpy as np
    import matplotlib.pyplot as plt
    
    plt.close("all")
    
    x = np.linspace(0, 200, 9)
    y = np.linspace(0, 100, 5)
    X, Y = np.meshgrid(x, y)
    U = 5*np.ones_like(X)
    V = 5*np.ones_like(Y)
    
    plt.close("all")
    fig, ax = plt.subplots(figsize=(10,5))
    
    ax_right = ax.quiver(X, Y, U, V, scale=1, scale_units="xy", angles="xy", width=4e-3)
    ax.quiverkey(ax_right, X=0.8, Y=1.05, U=5, label="unit", labelpos="W")
    print(f"scale is: {ax_right.scale}")
    

    Results:

    As for the key, it looks to be correct.