在Matplotlib中绘制两条线之间的角度的最佳方法

Mic*_*ina 15 python matplotlib

我对使用matplotlib相当新,并且找不到任何显示两条线的示例,并且它们之间的角度被绘制.

这是我目前的形象: 在此输入图像描述

这是我想要实现的一个例子:

在此输入图像描述

我通常会看看Matplotlib画廊,以了解如何执行某些任务,但似乎没有任何相似之处.

Rag*_* RV 21

您可以使用matplotlib.patches.Arc绘制相应角度测量的弧.

绘制角度弧:

定义一个可以获取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")
Run Code Online (Sandbox Code Playgroud)

要打印角度值:

如果您希望角度值以内联方式显示,请参阅 SO问题以了解如何在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]       
Run Code Online (Sandbox Code Playgroud)

或者您可以始终手动预先计算标签点并使用它text来显示角度值.你可以从该角度值label的的 Arc使用对象get_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)
Run Code Online (Sandbox Code Playgroud)

如果您不关心角度文本的内联放置.您可以使用plt.legend()打印角度值.

最后:

plt.legend()
plt.show()
Run Code Online (Sandbox Code Playgroud)

角度图有2条线

offset函数中的参数get_angle_plot用于指定弧的psudo-radius值.

当角度弧可能彼此重叠时,这将非常有用.

(在此图中,就像我说的,我的get_angle_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
Run Code Online (Sandbox Code Playgroud)

角度图有3条线

  • 愚蠢的问题,matplotlib API 改变了吗?在计算斜率时,我总是得到一个错误,即索引 2 超出范围...... (3认同)