以与轴的纵横比一致的物理单位重新缩放箭袋箭头 [英] Rescaling quiver arrows in physical units consistent to the aspect ratio of the axes

查看:36
本文介绍了以与轴的纵横比一致的物理单位重新缩放箭袋箭头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去几个小时,我一直在尝试自定义 matplotlib.quiver,但运气不佳.文档非常混乱,我无法解析如何设置每个参数.在我的轴中,一个垂直像素比一个水平像素的物理距离小得多,我希望 quiver 将箭头自动缩放到这个纵横比.我目前得到的是带有以下代码的水平箭头:

Tlevs = np.arange(-1.,8.5,.5) + 0.yy, zz = np.meshgrid(ds.YC, ds.Z)图, ax = plt.subplots(figsize=(8,5))fig.set_tight_layout(真)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],枢轴='mid',角度='xy',单位='xy')ax.set_xlabel('Y [m]', fontsize=13)ax.set_ylabel('深度 [m]', fontsize=13)cbar = fig.colorbar(im, ax=ax)cbar.set_label(r"[$^\circ$C]")

将箭袋选项设置为以下只会给出箭头应该是什么的点:

ax.quiver(yy[::3,::10], zz[::3,::10],vpFep_b[::3,::10], wpFep_b[::3,::10],枢轴='mid', 角度='xy', scale_units='xy', scales=1.)

和:

ax.quiver(yy[::3,::10], zz[::3,::10],vpFep_b[::3,::10], wpFep_b[::3,::10],枢轴='mid', 角度='xy', scale_units='xy')

给出以下错误:

/home/takaya/miniconda3/envs/uptodate/lib/python3.6/site-packages/matplotlib/quiver.py:666: RuntimeWarning: 在 double_scalars 中遇到除以零长度 = a * (widthu_per_lenu/(self.scale * self.width))/home/takaya/miniconda3/envs/uptodate/lib/python3.6/site-packages/matplotlib/quiver.py:666: RuntimeWarning: 在乘法中遇到无效值长度 = a * (widthu_per_lenu/(self.scale * self.width))/home/takaya/miniconda3/envs/uptodate/lib/python3.6/site-packages/matplotlib/quiver.py:719: RuntimeWarning: 在less中遇到无效值short = np.repeat(length 

任何帮助将不胜感激.谢谢!

解决方案

单位

文档入口为:

<块引用>

单位:[‘宽度’|‘高度’ |点" |'英寸' |'x' |'y' |'xy']

箭头尺寸(长度除外)以该单位的倍数测量.

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

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

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

箭头的比例因单位而异.对于x"或y",箭头随着放大而变大;对于其他单位,箭头大小与缩放状态无关.对于宽度"或高度",当调整窗口大小时,箭头大小分别随着轴的宽度和高度而增加;对于点"或英寸",调整大小不会改变箭头.

如上所述,此参数定义了测量除箭头长度以外的所有尺寸的单位.然而,参数宽度(这是最相关的,因为箭头 headwidth 和 headlength 等被定义为它的倍数)有一个默认值,这取决于使用的单位.

下面是不同单位的示例,将宽度固定为可比较的情况.参数点或英寸几乎相等,因此在示例中仅考虑其中之一.因此,宽度"和高度"的宽度设置为 0.01,点"设置为 3,x"、y"和xy"设置为 2.不固定相同的宽度会产生不同的结果,具体取决于后端:即在 jupyter 中使用

可以看出,由于绘图轴的宽度大于高度,与长度"相比,将单位设置为宽度"会产生更粗的箭头,因为宽度相同.比较'x'、'y'和'xy'时也是如此,根据x轴测量的距离1远大于根据y轴测量的距离1.

scale_units

文档中的条目是:

<块引用>

scale_units : [‘宽度’|‘高度’ |点" |'英寸' |'x' |'y' |‘xy’],无,可选

如果 scale kwarg 为 None,则箭头长度单位.默认为无.

例如scale_units 是‘英寸’,比例是 2.0,并且 (u,v) = (1,0),那么向量将是 0.5 英寸长.

如果 scale_units 是‘width’/‘height’,那么向量将是坐标区宽度/高度的一半.

如果 scale_units 是x",那么向量将为 0.5 个 x 轴单位.要在 x-y 平面中绘制向量,使 u 和 v 具有与 x 和 y 相同的单位,请使用angles='xy', scale_units='xy', scale=1.

关于调整绘图大小时缩放的解释与单位相同.然而,如果规模 kwarg 是无"语句完全不清楚并导致错误.

如果 scale 为 None,则箭头的长度将根据 scale_units 设置为默认值,以保持宽度和高度之间的合理比例并使箭头保持良好的形状(即合理的头部).然后,在调整绘图大小之前,不会正确理解 scale_units(由于缩放的差异取决于 scale_units).

如果 scale 与 None 不同,则箭头长度不再设置为其默认值,它遵循文档中的示例.

下面是一个比较 scale_units 的不同值的图,其中 scale=1 并且单位设置为其默认值宽度".

可以看出,'y' 的情况使 arros 看起来像点,这是因为 U、V 向量之间的大小差异约为 5,而 y 比例介于 -150 和 150 之间,而在 'width' 和 'lenght' 的情况下,绘图轴的 5 倍大小使箭头变大.

I've been spending the past couple of hours trying to customize matplotlib.quiver without much luck. The documentation is quite confusing and I haven't been able to parse out how to set each parameter. In my axes, one vertical pixel is much less physical distance than one horizontal pixel, and I want quiver to autoscale the arrows to this aspect ratio. What I'm currently getting are horizontal arrows with the following code:

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]")

Setting the quiver options to the following only gives dots for what the arrows should be:

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

and:

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

gives the following error:

/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

Any help would be appreciated. Thanks!

解决方案

The quiver documentation says:

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

Thus, using this arguments your problem will be solved. That is because the keyword units affects the arrow dimensions except for length, and scale_units affects only the lenght.

Edit:

Examples of parameter behaviour of matplotlib's quiver

It is true that the documentation is not completely clear, and there are many parameters with similar names which in addition to that, are unique to quiver.

Below there are many examples of the behaviour of different parameters, in particular the ones of interest to this question: angles, units and scale_units. Each example has an image that can be expanded by clicking on it.

The data for all the plots is the same, and can be reproduced using this code:

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

The entry in the documenatation is:

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.

In our case, the ratio between U and V is one, therefore the arrows will point in 45 degrees in the 'uv' case, however, in the 'xy' case, as the range of the y and x axis is different, the arrows won't point in 45 degrees in order to preserve the displacement from (x,y) to (x+u, y+v). This is important to take into account, since depending on the axis aspect ratio, a gradient (u,v)=(1,1) won't have a 45 degrees angle.

units

The entry of the documentation is:

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.

As explained above, this parameters defines the units in which all dimensions except the length of the arrow are measured. However, the parameter width (which is the most rellevant since the arrow headwidth and headlength and so on are defined as multiples of it) has a default values which depends on what units are used.

Below there is an example of different units, fixing the width to comparable cases. The parameter dots or inches is nearly equivalent, and therefore only one of them is considered in the example. Thus, width is set to 0.01 for 'width' and 'height', 3 for 'dots' and 2 for 'x','y' and 'xy'. Not fixing the same width yields different result depending on the backend: i.e. with matplotlib inline in jupyter there is no difference in any case and with Qt5 there are some, but its hard to interpret as the width is unknown.

It can be seen that as the plot axes are wider than taller, setting units to 'width' yields thicker arrows compared to 'length', because the width is the same. The same goes when comparing 'x', 'y' and 'xy', a distance of 1 measured according to the x axis is much larger than a distance of 1 according to the y axis.

scale_units

The entry in the documentation is:

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.

The explanation about scaling when resizing the plot is the same as in units. However, the "If the scale kwarg is None" statment is completely unclear and leads to error.

If scale is None, then the lenght of the arrows will be set to a default value depending on scale_units in order to keep a reasonable ratio between width and height and to keep the arrows in good shape (i.e. a reasonable head). Then, scale_units won't be propperly appreciated until the plot is resized (due to the differences in scaling depending on scale_units).

If scale is different than None, then the arrow lenght is not set to its default anymore, it follows the examples in the documentation.

Below there is a plot comparing different values of scale_units, with scale=1 and units set to its default value 'width'.

It can be seen that the 'y' case, makes the arros look like dots, due to the difference in size between the U,V vectors which is around 5 and the y scale which goes between -150 and 150, whereas in the case of 'width' and 'lenght', 5 times the size of the plot axes makes the arrows huge.

这篇关于以与轴的纵横比一致的物理单位重新缩放箭袋箭头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆