Как повернуть массив линейных графиков в Python / numpy на угол? - PullRequest
2 голосов
/ 08 апреля 2020

Я бы хотел повернуть линейный график по горизонтали. Пока у меня есть целевой угол, но я не могу повернуть массив графиков (синий график в пятне).

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 голосов
/ 08 апреля 2020

Этот вопрос очень полезен, в частности, ответ @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)

rotated plot


Дополнительный вопрос : Что если нам просто понадобятся числовые значения повернутых точек?

Тогда подход 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]

Разрезание выполнено чтобы получить интересующие нас размеры, так как поворот происходит только в 2D. Вы можете видеть, что первая точка из ваших исходных данных преобразуется в (-2.6, 4.3), что согласуется с моим графиком повернутого графика выше.

Таким образом, вы можете вращать любую точку, которая вас интересует или напишите al oop, чтобы поймать их всех.

1 голос
/ 09 апреля 2020

Awnser Арне идеально подходит, если вы хотите вращать график с помощью matplotlib. Если нет, вы можете посмотреть этот код:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...