如何使用Matplotlib中的箭头比例尺(Quiver Scale)

9
我需要制作一系列矢量图。我可以使用Matplotlib的quiver例程来获得任意数量的绘图。问题是,quiver会自动缩放每个图,但我需要每个图中的向量都表示相同的比例尺。例如,如果在一个图中,10 km/hr由1cm向量表示,则所有图中10 km/hr都应由1cm向量表示。(我并不关心向量具体是1cm。那只是一个例子。)我认为通过分别调整每个图的比例尺参数可以实现这一点。但似乎行不通。
例如,我找到第一个图中的最大速度mxs1,然后对于每个图,我执行如下操作:
mxspd = np.max(speed[n])
pylab.quiver(x,y,vx[n],vy[n],scale=mxs1/mxspd)

但是这样并不能够充分地调整向量长度。例如,在我尝试的情况下,mxspd 大约是 mxs1 的一半,因此在第二个图中的向量长度应该是第一个图中的向量长度的一半。但是,两个图中的向量长度差不多。


1
你能提供一个最小化的工作示例吗? - nicoguaro
3个回答

9
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))

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')

在此输入图片描述

请参阅文档了解scalescale_units参数的说明。


3
这个答案没有提供一种仍然利用自动缩放的解决方案,例如通过将后续箭头图的比例尺链接到第一个箭头图的自动缩放值。 - uayebforever

8

上面的答案事先匹配了两个图的比例。

下面的解决方案通过从第一个图中自动确定的比例并将其应用于第二个图来匹配后期的比例。

这种方法可能并不总是有效,因为它使用了私有调用,但解决了我的问题。

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()
assert isinstance(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.


1
这个关于比例尺的问题困扰了我很长时间。一般来说,我想要一个键,它表示“这个箭头长度相当于这个速度”,这意味着:
  1. 使用quiverkey添加键非常方便
  2. 有时候设置angles='xy', scale_units='xy'可以帮助绘制箭头按照x和y轴的单位进行缩放,而不是固定的单位。例如,如果坐标轴的单位是米,而你想要的是m/s
因此,假设虚构的u,v数据具有m/s的单位,我根据tacaswell的答案进行了改进(这里比例尺被固定为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')

提供:

enter image description here

总的来说,通常情况下您可能希望使用自动缩放因子,然后调整关键因子,以防止箭头重叠和手动调整缩放因子。为了进一步说明这一点,我将把数据缩放5倍:

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

现在左侧面板的最大速度为10米/秒(增加了一倍)。
因此,如果我们设置以下选项:
lkey=10

#set the scale factor to None for autoscaling
scalef=None

然后我们得到以下内容:

enter image description here

所以这里的图表看起来相同,但左侧箭头的长度正确地是右侧箭头的一半。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接