如何在Python/Numpy中旋转一维线性图数组?

3

我想将一条折线图水平旋转。目前,我已经有了目标角度,但是我无法旋转图形数组(在图表中的蓝色图形)。

import matplotlib.pyplot as plt
import numpy as np

x = [5, 6.5, 7, 8, 6, 5, 3, 4, 3, 0]
y = range(len(x))
best_fit_line = np.poly1d(np.polyfit(y, x, 1))(y)

angle = np.rad2deg(np.arctan2(y[-1] - y[0], best_fit_line[-1] - best_fit_line[0]))
print("angle: " + str(angle))

plt.figure(figsize=(8, 6))
plt.plot(x)
plt.plot(best_fit_line, "--", color="r")
plt.show()

enter image description here

数组的目标计算应该像这样(请忽略红线):

enter image description here

如果您有建议,请告诉我。谢谢。
2个回答

4

这个问题非常有帮助,特别是@Mr Tsjolder的回答。根据您的问题进行适应,您需要从计算出的角度中减去90才能获得想要的结果:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import transforms

x = [5, 6.5, 7, 8, 6, 5, 3, 4, 3, 0]
y = range(len(x))
best_fit_line = np.poly1d(np.polyfit(y, x, 1))(y)

angle = np.rad2deg(np.arctan2(y[-1] - y[0], best_fit_line[-1] - best_fit_line[0]))
print("angle: " + str(angle))

plt.figure(figsize=(8, 6))

base = plt.gca().transData
rotation = transforms.Affine2D().rotate_deg(angle - 90)

plt.plot(x, transform = rotation + base)
plt.plot(best_fit_line, "--", color="r", transform = rotation + base)

旋转的图形


后续问题:如果我们只需要旋转后点的数值呢?

这时候,使用matplotlib的方法仍然很有用。根据我们前面介绍的rotation对象,matplotlib可以提取变换矩阵,我们可以用它来转换任何点:

# extract transformation matrix from the rotation object
M = transforms.Affine2DBase.get_matrix(rotation)[:2, :2]

# example: transform the first point
print((M * [0, 5])[:, 1])

[-2.60096617 4.27024297]

对所需的维度进行了切片,因为旋转只发生在二维平面上。您可以看到,原始数据中的第一个点被转换为(-2.6,4.3),与我上面旋转图形的绘制结果一致。

通过这种方式,您可以旋转任何感兴趣的点,或编写循环以捕获它们全部。


你好Arne,谢谢 - 看起来不错,但我正在寻找一种直接转换数组以进行未来计算的方法。不幸的是,matplotlib的功能在这里对我没有帮助:( - g.breeze
啊,不过Matplotlib仍然可以帮助你。我已经在上面的答案中添加了一些内容。 - Arne

1

如果您想使用matplotlib旋转图形,那么Arne的答案非常完美。如果不想,您可以查看以下代码:

import matplotlib.pyplot as plt
import numpy as np


def rotate_vector(data, angle):
    # source: 
    # https://datascience.stackexchange.com/questions/57226/how-to-rotate-the-plot-and-find-minimum-point    
    # make rotation matrix
    theta = np.radians(angle)
    co = np.cos(theta)
    si = np.sin(theta)
    rotation_matrix = np.array(((co, -si), (si, co)))
    # rotate data vector
    rotated_vector = data.dot(rotation_matrix)
    return rotated_vector


x = [5, 6.5, 7, 8, 6, 5, 3, 4, 3, 0]
y = range(len(x))
best_fit_line = np.poly1d(np.polyfit(y, x, 1))(y)

angle = np.rad2deg(np.arctan2(y[-1] - y[0], best_fit_line[-1] - best_fit_line[0]))
print("angle:", angle)

# rotate blue line
d = np.hstack((np.vstack(y), np.vstack(x)))
xr = rotate_vector(d, -(angle - 90))

# rotate red line
dd = np.hstack((np.vstack(y), np.vstack(best_fit_line)))
xxr = rotate_vector(dd, -(angle - 90))

plt.figure(figsize=(8, 6))
plt.plot(xr[:, 1]) # or plt.plot(xr[:, 0], xr[:, 1])
plt.plot(xxr[:, 1], "--", color="r")
plt.show()

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接