Python 在Matplotlib中绘制两条直线之间的角度的最佳方法
我对使用matplotlib相当陌生,找不到任何显示两条线之间夹角的示例 这是我当前的图像: 这是我想要实现的一个例子: 我通常会看一看,以了解如何执行某些任务,但似乎没有类似的内容 您可以使用绘制相应角度测量的圆弧 绘制角度弧:Python 在Matplotlib中绘制两条直线之间的角度的最佳方法,python,matplotlib,Python,Matplotlib,我对使用matplotlib相当陌生,找不到任何显示两条线之间夹角的示例 这是我当前的图像: 这是我想要实现的一个例子: 我通常会看一看,以了解如何执行某些任务,但似乎没有类似的内容 您可以使用绘制相应角度测量的圆弧 绘制角度弧: fig = plt.figure() line_1 = Line2D([0,1], [0,4], linewidth=1, linestyle = "-", color="green") line_2 = Line2D([0,4.5], [0,3], linew
fig = plt.figure()
line_1 = Line2D([0,1], [0,4], linewidth=1, linestyle = "-", color="green")
line_2 = Line2D([0,4.5], [0,3], linewidth=1, linestyle = "-", color="red")
ax = fig.add_subplot(1,1,1)
ax.add_line(line_1)
ax.add_line(line_2)
angle_plot = get_angle_plot(line_1, line_2, 1)
angle_text = get_angle_text(angle_plot)
# Gets the arguments to be passed to ax.text as a list to display the angle value besides the arc
ax.add_patch(angle_plot) # To display the angle arc
ax.text(*angle_text) # To display the angle value
ax.set_xlim(0,7)
ax.set_ylim(0,5)
plt.legend()
plt.show()
定义一个函数,该函数可以接受2个matplotlib.lines.Line2D
对象,计算角度并返回一个matplotlib.patches.Arc
对象,可以将该对象与线一起添加到绘图中
def get_angle_plot(line1, line2, offset = 1, color = None, origin = [0,0], len_x_axis = 1, len_y_axis = 1):
l1xy = line1.get_xydata()
# Angle between line1 and x-axis
slope1 = (l1xy[1][1] - l1xy[0][2]) / float(l1xy[1][0] - l1xy[0][0])
angle1 = abs(math.degrees(math.atan(slope1))) # Taking only the positive angle
l2xy = line2.get_xydata()
# Angle between line2 and x-axis
slope2 = (l2xy[1][3] - l2xy[0][4]) / float(l2xy[1][0] - l2xy[0][0])
angle2 = abs(math.degrees(math.atan(slope2)))
theta1 = min(angle1, angle2)
theta2 = max(angle1, angle2)
angle = theta2 - theta1
if color is None:
color = line1.get_color() # Uses the color of line 1 if color parameter is not passed.
return Arc(origin, len_x_axis*offset, len_y_axis*offset, 0, theta1, theta2, color=color, label = str(angle)+u"\u00b0")
打印角度值:
fig = plt.figure()
line_1 = Line2D([0,1], [0,4], linewidth=1, linestyle = "-", color="green")
line_2 = Line2D([0,4.5], [0,3], linewidth=1, linestyle = "-", color="red")
ax = fig.add_subplot(1,1,1)
ax.add_line(line_1)
ax.add_line(line_2)
angle_plot = get_angle_plot(line_1, line_2, 1)
angle_text = get_angle_text(angle_plot)
# Gets the arguments to be passed to ax.text as a list to display the angle value besides the arc
ax.add_patch(angle_plot) # To display the angle arc
ax.text(*angle_text) # To display the angle value
ax.set_xlim(0,7)
ax.set_ylim(0,5)
plt.legend()
plt.show()
如果希望角度值以内联方式显示,请参阅问题,了解如何在matplotlib中打印内联标签。请注意,必须打印弧的标签
我制作了一个小函数,用于提取弧的顶点,并尝试计算角度文本的坐标
这可能不是最优的,也可能无法很好地处理所有角度值
def get_angle_text(angle_plot):
angle = angle_plot.get_label()[:-1] # Excluding the degree symbol
angle = "%0.2f"%float(angle)+u"\u00b0" # Display angle upto 2 decimal places
# Get the vertices of the angle arc
vertices = angle_plot.get_verts()
# Get the midpoint of the arc extremes
x_width = (vertices[0][0] + vertices[-1][0]) / 2.0
y_width = (vertices[0][5] + vertices[-1][6]) / 2.0
#print x_width, y_width
separation_radius = max(x_width/2.0, y_width/2.0)
return [ x_width + separation_radius, y_width + separation_radius, angle]
或者,您也可以始终手动预计算标签点,并使用来显示角度值。您可以使用get_label()
方法从Arc
对象的label
获取角度值(因为我们已经将标签设置为角度值+unicode度符号)
上述函数的示例用法:
fig = plt.figure()
line_1 = Line2D([0,1], [0,4], linewidth=1, linestyle = "-", color="green")
line_2 = Line2D([0,4.5], [0,3], linewidth=1, linestyle = "-", color="red")
ax = fig.add_subplot(1,1,1)
ax.add_line(line_1)
ax.add_line(line_2)
angle_plot = get_angle_plot(line_1, line_2, 1)
angle_text = get_angle_text(angle_plot)
# Gets the arguments to be passed to ax.text as a list to display the angle value besides the arc
ax.add_patch(angle_plot) # To display the angle arc
ax.text(*angle_text) # To display the angle value
ax.set_xlim(0,7)
ax.set_ylim(0,5)
plt.legend()
plt.show()
如果您不关心角度文本的内联放置。您可以使用plt.legend()
打印角度值
最后:
fig = plt.figure()
line_1 = Line2D([0,1], [0,4], linewidth=1, linestyle = "-", color="green")
line_2 = Line2D([0,4.5], [0,3], linewidth=1, linestyle = "-", color="red")
ax = fig.add_subplot(1,1,1)
ax.add_line(line_1)
ax.add_line(line_2)
angle_plot = get_angle_plot(line_1, line_2, 1)
angle_text = get_angle_text(angle_plot)
# Gets the arguments to be passed to ax.text as a list to display the angle value besides the arc
ax.add_patch(angle_plot) # To display the angle arc
ax.text(*angle_text) # To display the angle value
ax.set_xlim(0,7)
ax.set_ylim(0,5)
plt.legend()
plt.show()
函数get\u angle\u plot
中的offset
参数用于指定圆弧的psudo半径值
当角弧可能相互重叠时,这将非常有用
(在这个图中,正如我所说,我的get\u angle\u text
函数在放置文本值时不是很理想,但应该可以让您了解如何计算该点)
添加第三行:
line_3 = Line2D([0,7], [0,1], linewidth=1, linestyle = "-", color="brown")
ax.add_line(line_3)
angle_plot = get_angle_plot(line_1, line_3, 2, color="red") # Second angle arc will be red in color
angle_text = get_angle_text(angle_plot)
ax.add_patch(angle_plot) # To display the 2nd angle arc
ax.text(*angle_text) # To display the 2nd angle value
从@user3197452中汲取灵感,我就是这么用的。此版本结合了
文本
,还考虑了成比例的轴比
def add_corner_arc(ax, line, radius=.7, color=None, text=None, text_radius=.5, text_rotatation=0, **kwargs):
''' display an arc for p0p1p2 angle
Inputs:
ax - axis to add arc to
line - MATPLOTLIB line consisting of 3 points of the corner
radius - radius to add arc
color - color of the arc
text - text to show on corner
text_radius - radius to add text
text_rotatation - extra rotation for text
kwargs - other arguments to pass to Arc
'''
lxy = line.get_xydata()
if len(lxy) < 3:
raise ValueError('at least 3 points in line must be available')
p0 = lxy[0]
p1 = lxy[1]
p2 = lxy[2]
width = np.ptp([p0[0], p1[0], p2[0]])
height = np.ptp([p0[1], p1[1], p2[1]])
n = np.array([width, height]) * 1.0
p0_ = (p0 - p1) / n
p1_ = (p1 - p1)
p2_ = (p2 - p1) / n
theta0 = -get_angle(p0_, p1_)
theta1 = -get_angle(p2_, p1_)
if color is None:
# Uses the color line if color parameter is not passed.
color = line.get_color()
arc = ax.add_patch(Arc(p1, width * radius, height * radius, 0, theta0, theta1, color=color, **kwargs))
if text:
v = p2_ / np.linalg.norm(p2_)
if theta0 < 0:
theta0 = theta0 + 360
if theta1 < 0:
theta1 = theta1 + 360
theta = (theta0 - theta1) / 2 + text_rotatation
pt = np.dot(rotation_transform(theta), v[:,None]).T * n * text_radius
pt = pt + p1
pt = pt.squeeze()
ax.text(pt[0], pt[1], text,
horizontalalignment='left',
verticalalignment='top',)
return arc
要使用它,可以执行以下操作:
ax = gca()
line, = ax.plot([0, 0, 2], [-1, 0, 0], 'ro-', lw=2)
add_corner_arc(ax, line, text=u'%d\u00b0' % 90)
我已经编写了一个函数来创建matplotlib Arc对象,该对象包含几个有用的参数。它也适用于在原点不相交的直线。对于一组给定的两条直线,用户可能需要绘制许多可能的圆弧。此函数允许指定使用参数的参数。文本在圆弧和原点之间的中点绘制。在评论或网站上,我们非常欢迎改进
将numpy导入为np
导入matplotlib
将matplotlib.pyplot作为plt导入
Arc=matplotlib.patches.Arc
def半角(a、b):
获取从a增加到b时a和b之间的中间角度
如果b270或一半<90,则角度=一半,否则180+一半
textkwargs={
“x”:xy[0],
“y”:xy[1],
“s”:str(圆(角,dec))+“°”,
‘哈’:‘中’,
‘va’:‘center’,
“fontsize”:fontsize,
“旋转”:textangle
}
返回弧,textkwargs
它使用附加的脚本创建如下图所示的圆弧:
将numpy导入为np
将matplotlib.pyplot作为plt导入
从matplotlib.patches导入圆弧
#行的格式如下:[(x0,y0),(x1,y1)]
line1=np.数组([(1,-2),(3,2)])
line2=np.数组([(2,2),(2,-2)])
行=[line1,line2]
图,AX=plt子批次(nrows=2,ncols=2)
对于ax.flatte()中的ax:
对于行中的行:
x、 y=line.T
轴图(x,y)
ax.轴(“相等”)
ax1、ax2、ax3、ax4=AX.flatten()
A.