[英]Calculate angle (degrees) in Python between line (with slope x) and horizontal
I need to calculate the angle between a line and the horizontal.我需要计算一条线与水平线之间的角度。 My high school maths seems to be failing me.我的高中数学似乎不及格。
import matplotlib.pyplot as plt
import numpy as np
x = [8450.0, 8061.0, 7524.0, 7180.0, 8247.0, 8929.0, 8896.0, 9736.0, 9658.0, 9592.0]
y = range(len(x))
best_fit_line = np.poly1d(np.polyfit(y, x, 1))(y)
slope = (y[-1] - y[0]) / (x[-1] - x[0])
angle = np.arctan(slope)
print 'slope: ' + str(slope)
print 'angle: ' + str(angle)
plt.figure(figsize=(8,6))
plt.plot(x)
plt.plot(best_fit_line, '--', color='r')
plt.show()
The results are as follow:结果如下:
slope: 0.00788091068301
angle: 0.00788074753125
I need the angle between the horizontal and the red dotted line.我需要水平线和红色虚线之间的角度。 Just by looking at it, it should probably be something between 30-45 degrees.光看它,它可能应该在 30-45 度之间。 What am I doing wrong?我究竟做错了什么?
* regarding slope = (y[-1] - y[0]) / (x[-1] - x[0])
, I have also tried numpy.diff
and scipy.stats.linregress
, but no success either. * 关于slope = (y[-1] - y[0]) / (x[-1] - x[0])
,我也尝试过numpy.diff
和scipy.stats.linregress
,但也没有成功。
The line goes in x-direction from 0 to 9 and in y-direction from 7500 to 9500. Therefore your slope
is only 0.00788091068301 and not 0.57 for about 30°.这条线在 x 方向从 0 到 9,在 y 方向从 7500 到 9500。因此,您的slope
只有 0.00788091068301,而不是 0.57,大约 30°。 Your calculations are correct, but better use arctan2:您的计算是正确的,但最好使用 arctan2:
angle = np.rad2deg(np.arctan2(y[-1] - y[0], x[-1] - x[0]))
Not so much an answer, but more of an explanation of the problems you faced.与其说是答案,不如说是对您面临的问题的解释。
so, you are using x[-1] = 9592.0, and x[0] = 8450.0 for the end and start of your vertical 'run' (y-axis / variable 'x').因此,您使用 x[-1] = 9592.0 和 x[0] = 8450.0 作为垂直“运行”(y 轴/变量“x”)的结束和开始。
In fact, your (red-dotted) line starts at 7500 and ends at 9500 as stated by Daniel above.事实上,您的(红色虚线)线从 7500 开始,到 9500 结束,如 Daniel 上面所述。 this is shown in your variable 'best_fit_line' when calculated using your 'x' and 'y' data points.当使用“x”和“y”数据点计算时,这会显示在变量“best_fit_line”中。
>>>print('best_fit_line = ',best_fit_line)
>>>best_fit_line = [7581.47272727 7813.87878788 8046.28484848 8278.69090909 8511.0969697 8743.5030303 8975.90909091 9208.31515152 9440.72121212 9673.12727273]
to calculate the rise,run and slope of the 'red dotted line':计算“红色虚线”的上升、运行和斜率:
rise = best_fit_line[-1] - best_fit_line[0]
run = y[-1] - y[0] # note: this is your variable for the x-axis
slope = rise / run
angle = np.rad2deg(np.arctan2(rise,run)) # in degrees from horizontal
which gives the following values when run using your data points and calculating the line slope:当使用您的数据点运行并计算线斜率时,它会给出以下值:
best_fit_line = [7581.47272727 7813.87878788 8046.28484848 8278.69090909 8511.0969697 8743.5030303 8975.90909091 9208.31515152 9440.72121212 9673.12727273]
rise = 2091.654545454541
run = 9
slope: 232.40606060606012
angle = 89.75346845184545 degrees
which brings to the 2nd problem jtbandes pointed out when figuring out slope.这带来了 jtbandes 在计算斜率时指出的第二个问题。
eg.例如。 slope of a ramp (best_fit_line) is the amount of rise (change in vertical height: y-axis) / the amount of run (length of horizontal distance ramp covers: x-axis)坡道的坡度 (best_fit_line) 是上升量(垂直高度的变化:y 轴)/运行量(坡道覆盖的水平距离长度:x 轴)
A ramp which rises 1m over a length of 10m has a slope of 1/10 or 0.1 This is the same as saying a 10% incline or grade (0.1 * 100) Or 5.71 degrees up from the horizontal.在 10m 的长度上上升 1m 的坡道的坡度为 1/10 或 0.1 这与说从水平方向向上倾斜 10% 或坡度 (0.1 * 100) 或 5.71 度相同。
The problem with using the number of datapoints for the horizontal (run) is that you are not using the same units in the vertical (y-axis, your variable 'x') as the horizontal (x-axis, your variable 'y')使用水平(运行)的数据点数量的问题是您在垂直(y轴,变量'x')中使用的单位与水平(x轴,变量'y')不同)
So, the calculated slope of 89.7 degrees of your line using your data points (rise) and number of data points (run) is correct, but the scale of the graph is off.因此,使用您的数据点(上升)和数据点数(运行)计算的 89.7 度线的斜率是正确的,但图表的比例是关闭的。
Run the code above again and look at the graph.再次运行上面的代码并查看图表。 the graph is roughly square when matplotlib displays it.当 matplotlib 显示它时,该图大致是正方形的。 On my monitor, the x-axis of your graph which is a total of 9 units (0 -> 9) long, measures 15cm.在我的显示器上,图表的 x 轴总共有 9 个单位(0 -> 9)长,长度为 15 厘米。 The y-axis which has a total of 3,000 units (7,000 -> 10,000) long, measures 12cm. y 轴共有 3,000 个单位(7,000 -> 10,000)长,长度为 12 厘米。
If the units were the same (days, $, km, etc) on both axis, then the line would have a slope of 232, or 89.7 degrees.如果两个轴上的单位相同(天、美元、公里等),则该线的斜率为 232 或 89.7 度。
but the units are not the same, and matplotlib does not know this, it just displays a pretty graph within the confines of the figsize you asked it to print.但是单位不一样,matplotlib 不知道这一点,它只是在您要求它打印的 figsize 范围内显示一个漂亮的图形。
plt.figure(figsize=(8,6))
change the figsize numbers around and see what happens to the slope of the line when you run the code again.改变 figsize 数字,看看当你再次运行代码时线的斜率会发生什么。
8,1 displays an almost horizontal line. 8,1 显示一条几乎水平的线。
1,6 displays an almost vertical line. 1,6 显示一条几乎垂直的线。
change back to 8,6 and re-size the graph manually using your mouse.更改回 8,6 并使用鼠标手动重新调整图形大小。 Changing the aspect ratio of the graph changes the displayed slope of the line from almost vertical to almost horizontal and everything in between.更改图形的纵横比会将显示的线斜率从几乎垂直更改为几乎水平以及介于两者之间的所有内容。
Answers what you did wrong, but probably doesn't help.回答你做错了什么,但可能没有帮助。
Need to find a way to compare 'apples' to 'apples' to have the slope of a line mean anything.需要找到一种将“苹果”与“苹果”进行比较的方法,以使直线的斜率具有任何意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.