Skip to content Skip to sidebar Skip to footer

How To Use Matplotlib Quiver Scale

I need to do a series of vector plots. I can get any number of plots with matplotlib's quiver routine. The thing is, quiver autoscales each plot, but I need the vectors in each p

Solution 1:

import matplotlib
import numpy as np
import matplotlib.pyplotas plt

x, y = np.mgrid[0:20, 0:25]
u = np.sin(2 *x * np.pi / 20)
v = np.cos(2 * y * np.pi / 25)

fig, (ax_l, ax_r) = plt.subplots(1, 2, figsize=(8, 4))

ax_r.quiver(x, y, u, v, scale=5, scale_units='inches')
ax_l.quiver(x, y, 2*u, 2*v, scale=5, scale_units='inches')

ax_l.set_title('2x')
ax_r.set_title('1x')

enter image description here

See the documentation for explainations of the scale and scale_units kwargs.

Solution 2:

The answer above matches the scales of the two plots a priori.

The solution below matches the scales a posteri by taking the automatically determined scale from the first plot and applying it to the second.

This may not always work as it uses private calls, but solved my problem.

import matplotlib
import numpy as np
import matplotlib.pyplot as plt

x, y = np.mgrid[0:20, 0:25]
u = np.sin(2 *x * np.pi / 20)
v = np.cos(2 * y * np.pi / 25)

fig, (ax_l, ax_r) = plt.subplots(1, 2, figsize=(8, 4))

Q = ax_r.quiver(x, y, u, v, scale=None, scale_units='inches')

Q._init()
assertisinstance(Q.scale, float)

ax_l.quiver(x, y, 2*u, 2*v, scale=Q.scale, scale_units='inches')

ax_l.set_title('2x')
ax_r.set_title('1x')

Image showing the two plots with matching scales.

Solution 3:

This issue of scaling confused me for ages. In general, I want to have a key that says, "this length of arrow is equivalent to this velocity" , and this means:

  1. Nice to use quiverkey to add the key
  2. Sometimes it can be helpful to set angles='xy', scale_units='xy', to plot the arrows scaling with x and y units, rather than fixed units. For example, if the axes are in meters and you want m/s

Thus if we assume the fake u,v data has units of m/s, I adapted the answer of tacaswell as follows (here the scale is fixed to 1).

import matplotlib
import numpy as np
import matplotlib.pyplot as plt

x, y = np.mgrid[0:20, 0:25]

u = np.sin(2 *x * np.pi / 20)
v = np.cos(2 * y * np.pi / 25)

fig, (ax_l, ax_r) = plt.subplots(1, 2, figsize=(8, 4))

# set the key length
lkey=1#set the scale factor
scalef=1

q_l=ax_l.quiver(x, y, 2*u, 2*v, angles='xy', scale_units='xy' , scale=scalef)
ax_l.quiverkey(q_l, X=0.3, Y=1.1, U=lkey,
             label='Quiver key, length = '+str(lkey)+' m/s', labelpos='E')

q_r=ax_r.quiver(x, y, u, v, angles='xy', scale_units='xy', scale=scalef )

ax_r.quiverkey(q_r, X=0.3, Y=1.1, U=lkey,
             label='Quiver key, length = '+str(lkey)+' m/s', labelpos='E')

ax_l.set_title('2x')
ax_r.set_title('1x')

giving:

enter image description here

That said, in general you might want to use the automatic scale factor and then adjust the key as this prevents overlap of arrows and manual fiddling with the scale factor. To illustrate this further, I'll scale the data by a factor of 5:

u = 5*np.sin(2 *x * np.pi / 20)
v = 5*np.cos(2 * y * np.pi / 25)

Now the left panel will have max velocity of 10 m/s (it is doubled)

So if we set the following options:

lkey=10#set the scale factor to None for autoscalingscalef=None

Then we get the following:

enter image description here

so here the plots look the same but the arrow on the left key is correctly half the length of that on the right.

Post a Comment for "How To Use Matplotlib Quiver Scale"