Search code examples
pythonvectorangle

Drawing a 315 degree angle from peak data point in python


I am trying to get the red line (Vector) to originate from the yellow peak data point (at 100) in the data set in a 315 degree angle towards the right side of the chart.

Just cant figure how to do it.

import matplotlib.pyplot as plt
import numpy as np
from scipy import signal

data = np.array([19.639999,19.049999,19.959999,19.950001,21.549999,21.110001,20.73,19.139999,20,20.280001,20.41,       21.190001,22.82,23.799999,23.190001,20.92,19.700001,18.85,21.67,22.75,22.549999])

for number in data:

    signal_max = (data > np.roll(data,1)) & (data > np.roll(data,-1))
    signal_min = (data < np.roll(data,1)) & (data < np.roll(data,-1))


degree = range(len(data))

line = np.poly1d(np.polyfit(degree, data, 1))(degree)

slope = (degree[-1] - degree[0]) / (data[-1] - data[0])

#angle = np.rad2deg(slope)
angle = np.rad2deg(np.arctan2(degree[-1] - degree[0], data[-1] -data[0]))


plt.figure(figsize=(8,6))
plt.plot(data)
plt.plot(line, '--', color='r')
plt.plot(signal_max.nonzero()[0], data[signal_max], 'yv')
plt.plot(signal_min.nonzero()[0], data[signal_min], 'r^')
plt.show()

Solution

  • Not sure I get why do you want the 315, so I made 2 versions: one that does the 315 angle from the highest point (version1, see below) and one that makes the regression line going through the maximum (version2, see below). Please comment if something is not clear.

    version1:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy import signal
    from math import pi
    
    data = np.array([19.639999,19.049999,19.959999,19.950001,21.549999,21.110001,20.73,19.139999,20,20.280001,20.41,
             21.190001,22.82,23.799999,23.190001,20.92,19.700001,18.85,21.67,22.75,22.549999,22.889999,24.139999,
             25.02,24.77,24.469999,24.84,24.299999,33.669998,46.98,52.669998,55.419998,55.23,57.830002,61.299999,
             61.880001,59.689999,73.949997,75.330002,81.410004,99.019997,89.980003,86.870003])
    
    for number in data:
    
        signal_max = (data > np.roll(data,1)) & (data > np.roll(data,-1))
        signal_min = (data < np.roll(data,1)) & (data < np.roll(data,-1))
    
    
    degree = range(len(data))
    
    line = np.poly1d(np.polyfit(degree, data, 1))(degree)
    
    plt.figure(figsize=(8,6))
    plt.plot(data)
    
    xm = np.argmax(data)
    ym = np.amax(data)
    angle = 315
    plt.plot( [ xm - ym/np.tan(angle/(2*pi)), xm ], [0, ym ], '--', color='r')
    
    plt.plot(signal_max.nonzero()[0], data[signal_max], 'yv')
    plt.plot(signal_min.nonzero()[0], data[signal_min], 'r^')
    plt.show()
    

    version2:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy import signal
    from math import pi
    
    data = np.array([19.639999,19.049999,19.959999,19.950001,21.549999,21.110001,20.73,19.139999,20,20.280001,20.41,
             21.190001,22.82,23.799999,23.190001,20.92,19.700001,18.85,21.67,22.75,22.549999,22.889999,24.139999,
             25.02,24.77,24.469999,24.84,24.299999,33.669998,46.98,52.669998,55.419998,55.23,57.830002,61.299999,
             61.880001,59.689999,73.949997,75.330002,81.410004,99.019997,89.980003,86.870003])
    
    for number in data:
    
        signal_max = (data > np.roll(data,1)) & (data > np.roll(data,-1))
        signal_min = (data < np.roll(data,1)) & (data < np.roll(data,-1))
    
    
    degree = range(len(data))
    
    line = np.poly1d(np.polyfit(degree, data, 1))(degree)
    
    plt.figure(figsize=(8,6))
    plt.plot(data)
    
    xm = np.argmax(data)
    line = line - (line[xm] - data[xm])
    plt.plot( line, '--', color='g')
    
    plt.plot(signal_max.nonzero()[0], data[signal_max], 'yv')
    plt.plot(signal_min.nonzero()[0], data[signal_min], 'r^')
    plt.show()