Skip to main content
 首页 » 编程设计

python之以与轴的纵横比一致的物理单位重新缩放箭矢箭头

2025年05月04日13exmyth

在过去的几个小时中,我一直在尝试自定义matplotlib.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 

任何帮助,将不胜感激。谢谢!

请您参考如下方法:

quiver documentation说:

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


因此,使用此参数可以解决您的问题。这是因为关键字 units会影响箭头尺寸 (长度除外),而 scale_units仅会影响长度,而不影响长度。
编辑:
matplotlib颤抖的参数行为示例
确实,文档还不是很清楚,并且还有许多具有类似名称的参数,这些参数对于颤振器来说是唯一的。
下面有许多不同参数行为的示例,尤其是该问题感兴趣的参数: angles, units和 scale_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文档中的条目为:

angles : [ ‘uv’ | ‘xy’ ], array, optional

Method for determining the angle of the arrows. Default is ‘uv’.

‘uv’: the arrow axis aspect ratio is 1 so that if U*==*V the orientation of the arrow on the plot is 45 degrees counter-clockwise from the horizontal axis (positive to the right).

‘xy’: arrows point from (x,y) to (x+u, y+v). Use this for plotting a gradient field, for example.


在我们的情况下,U与V之比为1,因此在“uv”情况下箭头将指向45度,但是在“xy”情况下,由于y和x轴的范围不同,因此箭头箭头不会指向45度,以保持从(x,y)到(x + u,y + v)的位移。考虑到这一点很重要,因为根据轴的纵横比,坡度(u,v)=(1,1)不会具有45度角。
units该文档的条目是:

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

The arrow dimensions (except for length) are measured in multiples of this unit.

‘width’ or ‘height’: the width or height of the axis

‘dots’ or ‘inches’: pixels or inches, based on the figure dpi

‘x’, ‘y’, or ‘xy’: respectively X, Y, or in data units

The arrows scale differently depending on the units. For ‘x’ or ‘y’, the arrows get larger as one zooms in; for other units, the arrow size is independent of the zoom state. For ‘width or ‘height’, the arrow size increases with the width and height of the axes, respectively, when the window is resized; for ‘dots’ or ‘inches’, resizing does not change the arrows.


如上所述,此参数定义了单位,在其中测量除箭头长度以外的所有尺寸。但是,参数width(由于箭头的headwidth和headlength等被定义为其倍数,因此是最相关的)具有默认值,具体取决于所使用的单位。
下面是一个不同单位的示例,将宽度固定为可比较的情况。参数点或英寸几乎相等,因此在示例中仅考虑其中之一。因此,将“宽度”和“高度”的宽度设置为0.01,将“点”设置为3,将“x”,“y”和“xy”设置为2。不固定相同的宽度会产生不同的结果,具体取决于后端:即jupyter中的 matplotlib inline在任何情况下都没有差异,而 Qt5则有一些差异,但是由于宽度未知而难以解释。

可以看出,随着绘图轴的宽度大于高度,将单位设置为“宽度”会比“长度”产生更粗的箭头,因为宽度是相同的。比较“x”,“y”和“xy”时也是如此,根据x轴测得的距离1远大于根据y轴测得的距离1。 scale_units文档中的条目是:

scale_units : [ ‘width’ | ‘height’ | ‘dots’ | ‘inches’ | ‘x’ | ‘y’ | ‘xy’ ], None, optional

If the scale kwarg is None, the arrow length unit. Default is None.

e.g. scale_units is ‘inches’, scale is 2.0, and (u,v) = (1,0), then the vector will be 0.5 inches long.

If scale_units is ‘width’/’height’, then the vector will be half the width/height of the axes.

If scale_units is ‘x’ then the vector will be 0.5 x-axis units. 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.


调整图大小时有关缩放的说明与单位相同。但是,“如果刻度kwarg为None”的陈述是完全不清楚的,并会导致错误。
如果scale为None,则箭头的长度将根据scale_units设置为默认值,以保持宽度和高度之间的合理比例并保持箭头的形状良好(即合理的头部)。然后,在调整图的大小之前(由于缩放比例取决于scale_units的不同),scale_units才能得到正确的欣赏。
如果小数位数不同于无,则箭头长度不再设置为其默认值,它遵循文档中的示例。
下面是一个比较scale_units不同值的图,其中scale = 1,单位设置为其默认值“width”。

可以看到,由于U,V向量之间的大小差异约为5,而y尺度介于-150和150之间,因此“y”情况使arros看起来像点。表示“宽度”和“长度”的大小,是绘图轴大小的5倍,因此箭头很大。