gpt4 book ai didi

python - 在 'uv' 模式下绘图时获取箭袋箭头(尖端和底部)的坐标

转载 作者:行者123 更新时间:2023-12-02 11:17:51 25 4
gpt4 key购买 nike

我想做什么
我希望能够在“uv”模式下绘图时获得箭袋箭头的坐标,以便重新使用这些数据来绘制其他形状(例如椭圆)。
问题
此问题也与this post有关.在这篇文章中,答案提到使用 ._paths quiver 变量以获取箭头的坐标。但是,没有迹象表明如何做到这一点。
有人有解决方案可以在“uv”绘图模式下访问与箭头顶部和底部关联的坐标吗? q._paths中有很多变量我看不出哪个是相关的。
复制代码
下面的代码在“xy”模式下工作得很好:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib.patches import Ellipse
import matplotlib.transforms as transforms

#-------------------------------------
# Variable definition
colsec = 'royalblue'
colvec = 'salmon'
colellipse = 'limegreen'
x = np.array([ 0.00789308, -0.0773587 , 0.03353797, -0.06185714, -0.13095092,
0.03280368, 0.04775701, -0.08124051, -0.02894444, -0.02834356,
-0.1457362 , -0.00628834, 0.09627607])
y = np.array([-0.03668553, 0.05931522, -0.04041772, -0.00866234, -0.00539877,
-0.14787117, -0.21553271, -0.15741139, -0.1417963 , -0.00887117,
0.02207362, -0.11979755, -0.28635583])
meanx = np.mean(x)
meany = np.mean(y)

# ellipse parameter
ell_radius_x = 0.54
ell_radius_y = 1.30
scale_x = 0.07
scale_y = 0.1

#-------------------------------------
# 'xy' plot

posx1 = 0
posy1 = 0

# Plot
fig, ax = plt.subplots(figsize=(8, 8))
plt.scatter(x,y,color='blue')

# Quiver plot
Qv = ax.quiver(posx1, posy1, meanx, meany,
angles='xy', scale_units='xy', scale=1,
color='black')

# Basic ellipse definition
ellipse = Ellipse((0, 0),
width=ell_radius_x * 2,
height=ell_radius_y * 2,
facecolor='none',
edgecolor='red')

center=(meanx + posx1, meany + posy1)

# Transformation of the ellipse according to external parameters (obtained from various statistics on the data)
transf = transforms.Affine2D() \
.rotate_deg(45) \
.scale(scale_x, scale_y) \
.translate(*center)
ellipse.set_transform(transf + ax.transData)

# Plot of the ellipse
ax.plot(*center,'x',color='g',markersize=12)

ax.add_patch(ellipse)

我们得到了预期的结果:
ellipse and quiver 'xy' mode
现在,当我切换到 'uv' 模式时(我的箭袋位置有不同的单位),虽然我尝试使用缩放因子,但我无法重现相同的图。下面的代码给了我这个结果:
enter image description here
#-------------------------------------
# 'uv' plot (variables are defined previously)

# Scale factor for quiver and ellipse plot
scalefac = 2

posx1 = np.array(-12.633)
posy1 = np.array(57.533)

# Plot
fig, ax = plt.subplots(figsize=(8, 8))
plt.scatter(posx1,posy1,color='blue')

Qv = ax.quiver(posx1, posy1, meanx*scalefac, meany*scalefac,
scale=1, scale_units='width',
color='black')

# Basic ellipse definition
ellipse = Ellipse((0, 0),
width=ell_radius_x * 2,
height=ell_radius_y * 2,
facecolor='none',
edgecolor='red')

# Transformation of the ellipse according to external parameters (obtained from various statistics on the data)
center=(meanx*scalefac + posx1, meany*scalefac + posy1)
transf = transforms.Affine2D() \
.rotate_deg(45) \
.scale(scale_x*scalefac, scale_y*scalefac) \
.translate(*center)
ellipse.set_transform(transf + ax.transData)

# Plot of the ellipse
ax.plot(*center,'x',color='g',markersize=12)

ax.add_patch(ellipse)

Qv._paths不返回一个易于理解的变量:
print(Qv._paths)
[Path(array([[ 0.00357682, -0.00112643],
[-0.03897025, -0.13622912],
[-0.03069018, -0.13490515],
[-0.05268492, -0.1672941 ],
[-0.05215112, -0.12814659],
[-0.0461239 , -0.13397627],
[-0.00357682, 0.00112643],
[ 0.00357682, -0.00112643]]), None)]
我想我需要的缩放信息在 Qv._paths 中。但我不清楚在哪里。这个想法是有一个健壮的方法,所以我可以改变与我的变量相关的缩放 scalefac .有什么建议?

最佳答案

又看了一遍文档,突然明白了。让我绘制一个虚拟示例,以便于理解。

fig, ax = plt.subplots(figsize=(8, 8))
plt.xlim(-12.8,-12.6)
plt.ylim(57.2,57.6)

x1, y1 = -12.633, 57.533
x2, y2 = -12.7, 57.4
angle = np.arctan((y2-y1)/(x2-x1))
D = np.sqrt((x2-x1)**2 + (y2-y1)**2)
U, V = D*np.cos(angle), D*np.sin(angle)
ax.scatter(x2, y2, marker='x', s=100, color='k')
Qv1 = ax.quiver(x1, y1, -U, -V, angles='uv', scale=1, scale_units='xy', color='black')
Qv2 = ax.quiver(x1, y1, -U, -V, angles='xy', scale=1, scale_units='xy', color='red')
考虑 (x2, y2)类似于假设椭圆的中心。我们可以用简单的矢量数学计算角度和 U、V 分量。绘制上面给出:
Qv1 and Qv2
请注意 uv 角度中的颤动如何略微偏离,与问题中的示例相同。但是,如果您阅读 matplotlib 文档中的文档,它会说:

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


在 uv 模式下,箭头的轴独立于 x,y 轴,并且该轴的纵横比为 1。所以很自然地,如果您的绘图的纵横比为 1,箭头应该完美匹配!
plt.xlim(-12.8,-12.4)
plt.ylim(57.2,57.6)
在这个 xlim 和 ylim 设置下,如果我运行我之前的虚拟图,我们会得到:
Matching Qv
回到您的示例,您需要将 scale_units 更改为 'xy' 并简单地设置纵横比为 1 的 xlim、ylim。
#-------------------------------------
# 'uv' plot (variables are defined previously)

# Scale factor for quiver and ellipse plot
scalefac = 2

posx1 = np.array(-12.633)
posy1 = np.array(57.533)

# Plot
fig, ax = plt.subplots(figsize=(8, 8))
plt.scatter(posx1,posy1,color='blue')

Qv = ax.quiver(posx1, posy1, meanx*scalefac, meany*scalefac,
angles='uv', scale=1, scale_units='xy',
color='black')

# Basic ellipse definition
ellipse = Ellipse((0, 0),
width=ell_radius_x * 2,
height=ell_radius_y * 2,
facecolor='none',
edgecolor='red')

# Transformation of the ellipse according to external parameters (obtained from various statistics on the data)
center=(meanx*scalefac + posx1, meany*scalefac + posy1)
transf = transforms.Affine2D() \
.rotate_deg(45) \
.scale(scale_x*scalefac, scale_y*scalefac) \
.translate(*center)
ellipse.set_transform(transf + ax.transData)

# Plot of the ellipse
ax.plot(*center,'x',color='g',markersize=12)

ax.add_patch(ellipse)
plt.xlim(-13,-12.5)
plt.ylim(57.1, 57.6)
Correct Qv
也许应该在 matplotlib 文档中添加额外的警告或注释,因为我认为这乍一看并不是很明显。

关于python - 在 'uv' 模式下绘图时获取箭袋箭头(尖端和底部)的坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62793436/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com