将箭头重新缩放为与坐标轴纵横比一致的物理单位

8

我已经花了几个小时来尝试自定义matplotlib.quiver,但是一直没有成功。文档非常令人困惑,我无法解析如何设置每个参数。在我的轴中,一个垂直像素比一个水平像素的物理距离小得多,我希望quiver可以根据这个纵横比自动缩放箭头。使用以下代码时,我目前得到的是水平箭头:

Tlevs = np.arange(-1.,8.5,.5) + 0.
yy, zz = np.meshgrid(ds.YC, ds.Z)

fig, ax = plt.subplots(figsize=(8,5))
fig.set_tight_layout(True)
im = ax.contourf(T_clim.YC, T_clim.Z, T_clim, levels=Tlevs)
ax.quiver(yy[::3,::10], zz[::3,::10], 
          vpFep_b[::3,::10], wpFep_b[::3,::10], 
          pivot='mid', angles='xy', units='xy')
ax.set_xlabel('Y [m]', fontsize=13)
ax.set_ylabel('Depth [m]', fontsize=13)
cbar = fig.colorbar(im, ax=ax)
cbar.set_label(r"[$^\circ$C]")

等高线图与箭头叠加的示意图

将 quiver 选项设置为以下内容,只会显示箭头的点:

ax.quiver(yy[::3,::10], zz[::3,::10], 
              vpFep_b[::3,::10], wpFep_b[::3,::10], 
              pivot='mid', angles='xy', scale_units='xy', scales=1.)

这里输入图片描述

并且:

ax.quiver(yy[::3,::10], zz[::3,::10], 
              vpFep_b[::3,::10], wpFep_b[::3,::10], 
              pivot='mid', angles='xy', scale_units='xy')

显示以下错误:

/home/takaya/miniconda3/envs/uptodate/lib/python3.6/site-packages/matplotlib/quiver.py:666: RuntimeWarning: divide by zero encountered in double_scalars
  length = a * (widthu_per_lenu / (self.scale * self.width))
/home/takaya/miniconda3/envs/uptodate/lib/python3.6/site-packages/matplotlib/quiver.py:666: RuntimeWarning: invalid value encountered in multiply
  length = a * (widthu_per_lenu / (self.scale * self.width))
/home/takaya/miniconda3/envs/uptodate/lib/python3.6/site-packages/matplotlib/quiver.py:719: RuntimeWarning: invalid value encountered in less
  short = np.repeat(length < minsh, 8, axis=1)
/home/takaya/miniconda3/envs/uptodate/lib/python3.6/site-packages/matplotlib/quiver.py:733: RuntimeWarning: invalid value encountered in less
  tooshort = length < self.minlength

非常感谢您的帮助。谢谢!


你想在相同的单位和比例尺下绘制箭头吗?我不明白所需的输出是什么。 - OriolAbril
是的,与轴的实际物理单位相同的比例尺。 - takachanbo
1个回答

18

quiver文档中写道:

要在x-y平面上绘制向量,使u和v具有与x和y相同的单位,请使用angles='xy'scale_units='xy'scale=1

因此,使用这些参数即可解决问题。这是因为关键字units影响箭头尺寸除了长度外,而scale_units仅影响长度

编辑:

matplotlib's quiver参数行为示例

确实,文档并不完全清晰,还有许多具有类似名称的参数,而且这些参数对于quiver来说是唯一的。

下面有许多不同参数行为的示例,特别是与本问题相关的参数:anglesunitsscale_units。每个示例都有一个可以通过单击扩展的图像。

所有绘图的数据都相同,可以使用以下代码重现:

x = np.linspace(0,50,5)
y = np.linspace(-150,150,7)
X,Y = np.meshgrid(x,y)
U = 3.5*np.ones_like(X)
V = 3.5*np.ones_like(Y)

角度

文档中的条目为:

angles : [ ‘uv’ | ‘xy’ ], 数组, 可选

确定箭头角度的方法。默认值为 'uv'。

'uv': 箭轴长宽比为1,因此如果U*==*V,则箭头在绘图上的方向与水平轴逆时针45度(向右为正)。

'xy': 箭头从(x,y)指向(x+u,y+v)。例如,用于绘制梯度场。

在我们的情况下,U和V之间的比率为1,因此在'uv'情况下箭头将指向45度,但是在'xy'情况下,由于y和x轴的范围不同,箭头不会指向45度以保持从(x,y)到(x+u,y+v)的位移。这很重要要考虑,因为根据轴长宽比,梯度(u,v)=(1,1)的角度不一定为45度。

angles

单位

文档中的条目为:

units : [ ‘width’ | ‘height’ | ‘dots’ | ‘inches’ | ‘x’ | ‘y’ | ‘xy’ ]

箭头的尺寸(除了长度)以此单位的倍数来衡量。

‘width’或‘height’:轴的宽度或高度

‘dots’或‘inches’:基于图形dpi的像素或英寸

‘x’、‘y’或‘xy’:分别是X、Y或数据单位

箭头的大小因单位不同而有所不同。对于‘x’或‘y’,随着缩放,箭头变得越来越大;对于其他单位,箭头大小与缩放状态无关。对于‘width’或‘height’,当窗口大小调整时,箭头大小分别随轴的宽度和高度增加;对于‘dots’或‘inches’,调整大小不会改变箭头。

如上所述,该参数定义了除箭头长度外的所有尺寸的单位。然而,参数宽度(最相关的参数,因为箭头头宽和头长等都是它的倍数定义的)具有依赖于所使用的单位的默认值。

下面是不同单位的示例,将宽度固定为可比较的情况。参数“dots”或“inches”几乎等效,因此在示例中仅考虑其中一个。因此,“width”和“height”的宽度设置为0.01,“dots”设置为3,“x”,“y”和“xy”设置为2。如果不固定相同的宽度,则会根据后端产生不同的结果:即在jupyter中使用matplotlib inline时,在任何情况下都没有区别,在Qt5中有些区别,但很难解释,因为宽度未知。

units

可以看到,由于绘图坐标轴的宽度大于高度,将单位设置为“width”会得到比“length”更粗的箭头,因为宽度相同。同样,比较“x”、“y”和“xy”,根据x轴测量的1的距离要比根据y轴测量的1的距离大得多。
“scale_units”
文档中的条目是:
- scale_units : [ ‘width’ | ‘height’ | ‘dots’ | ‘inches’ | ‘x’ | ‘y’ | ‘xy’ ],None,可选 - 如果scale kwarg为None,则箭头长度单位。默认值为None。 - 例如,scale_units为“inches”,scale为2.0,(u,v)=(1,0),则矢量长度为0.5英寸。 - 如果scale_units为“width”/“height”,则矢量将是轴宽度/高度的一半。 - 如果scale_units为“x”,则矢量将是0.5 x轴单位。要在x-y平面上绘制具有与x和y相同单位的u和v的矢量,请使用angles ='xy',scale_units ='xy',scale = 1。
关于调整绘图大小时缩放的解释与单位相同。但是,“如果scale kwarg为None”语句完全不清楚,并导致错误。
如果scale为None,则箭头的长度将根据比例单位设置为默认值,以保持宽度和高度之间的合理比例,并保持箭头的良好形状(即合理的箭头头部)。然后,在调整图表大小时才能正确使用比例单位(由于不同比例单位的缩放差异)。
如果scale不等于None,则箭头长度不再设置为其默认值,而是遵循文档中的示例。
下面有一个图,比较了不同比例单位的值,其中scale=1,单位设置为其默认值'width'。

scale_units

可以看到,对于'y'这种情况,箭头由于U、V向量的大小与y轴范围之间的差异(约为5),看起来像是点;而对于'width'和'length'这两种情况,绘图轴的大小增加了5倍,箭头变得巨大。

我在上面的问题中添加了更多细节,但我认为选项并没有按照我想要的方式工作。无论我给出什么“比例”,箭头的大小似乎都不会改变。 - takachanbo
你能否发布用于生成图形的数据(最好是显示相同问题的最小示例)?如果它们是点,也许箭头非常小(y轴比例尺的顺序为1e6,因此,米级别的箭头看起来像是图形)。 - OriolAbril
我已将数据上传至此处:https://www.dropbox.com/sh/id4moyv6pbnxdaw/AABOgy48Qe1EIuxKcfLX2lJta?dl=0 - takachanbo
vFe是箭头图向量的x分量,wFe是y分量。变量vFewFe的物理坐标轴分别为yz - takachanbo
你能以csv格式发布它吗?或者只需复制矩阵的3x3或4x4部分即可?我从未使用过.nc文件,也不打算仅为此学习。 - OriolAbril
显示剩余2条评论

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