在Matplotlib中绘制两条线之间的夹角的最佳方法 [英] Best way to plot an angle between two lines in Matplotlib

查看:128
本文介绍了在Matplotlib中绘制两条线之间的夹角的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am fairly new to using matplotlib and cannot find any examples that show two lines with the angle between them plotted.

这是我当前的图像:

This is my current image:

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

And this is an example of what I want to achieve:

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

I usually take a look at the Matplotlib gallery to get an idea of how to perform certain tasks but there does not seem to be anything similar.

推荐答案

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

You could use matplotlib.patches.Arc to plot an arc of the corresponding angle measure.

绘制角度弧:

定义一个函数,该函数可以使用2个matplotlib.lines.Line2D对象,计算角度并返回matplotlib.patches.Arc对象,您可以将其与线条一起添加到绘图中.

Define a function that could take 2 matplotlib.lines.Line2D objects, calculate the angle and return a matplotlib.patches.Arc object, which you can add to your plot along with the lines.

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

要打印角度值:

如果您希望角度值以内联方式显示,请参考 SO问题在matplotlib中打印内联标签.请注意,您必须打印圆弧的标签.

Incase you want the angle value to be displayed inline, refer this SO Question for how to print inline labels in matplotlib. Note that you must print the label for the arc.

我做了一个小函数,提取圆弧的顶点并尝试计算角度文本的坐标.

I made a small function which extracts the vertices of the arc and tries to compute the coordinate of the angle text.

这可能不是最佳选择,并且可能不适用于所有角度值.

This may not be optimal and may not work well with all angle values.

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]       

或者您始终可以手动预先计算标签点,并使用 text 以显示角度值.您可以使用get_label()方法从Arc对象的label获取角度值(因为我们已经将标签设置为角度值+ unicode度符号).

Or you could always precompute the label point manually and use text to display the angle value. You can get the angle value from the label of the Arc object using the get_label() method (Since we had set the label to the angle value + the unicode degree symbol).

上述功能的使用示例:

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()打印角度值.

If you do not care about inline placement of the angle text. You could use plt.legend() to print the angle value.

最后:

plt.legend()
plt.show()

函数get_angle_plot中的offset参数用于为圆弧指定伪半径值.

The offset parameter in the function get_angle_plot is used to specify a psudo-radius value to the arc.

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

This will be useful when angle arcs may overlap with each other.

(在这个图中,就像我说的那样,我的get_angle_text函数在放置文本值时不是很理想,但是应该让您了解如何计算点)

( In this figure, like I said, my get_angle_text function is not very optimal in placing the text value, but should give you an idea on how to compute the point )

添加第三行:

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

这篇关于在Matplotlib中绘制两条线之间的夹角的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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