在Matplotlib中绘制两条线之间的夹角的最佳方法 [英] Best way to plot an angle between two lines in 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屋!