1

The graph produced uses the array named w as the x axis and the array named A1 as the y axis.I have to find and print the maximum point on the resulting graph. To do this I use the max() function to find the maximum value in the array named A1. To find the corresponding X value I am using the np.interp() function and swapping the x and y input axes so the value returned is effectively an x value for the graph produced (np.interp uses an x value to find a y, I am using a y value to find an x). However, no matter what value I give the np.interp function it always returns 4.99. I assume the issue must lie in the fact that in swapping the axes? But this is the only way to get the function to return an x value for a given y.

    import numpy as np
    import matplotlib.pyplot as plt

    F = 10
    m = 5
    w0 = 1

    w = np.array(np.arange(0.01, 5, 0.01))

    b1 = 0.25*m*w0
  

    G1 = np.array(np.sqrt((m**2)*(((w**2)-(w0**2))**2)+(b1**2)*(w**2)))

    A1 = np.array(F/G1)       

    A1_Max = max(A1)

Here I am printing the value just to test if it is right. As you can see the x axis should be w and the y A1 in the np.interp function however as previously stated the axes are swapped:

    w1_Max = np.interp(A1_Max, A1, w)
    print(w1_Max)

    plt.figure(figsize=(20, 20))

    plt.plot(w, A1, '-', label='b=0.25*m*w0')
    plt.xlabel('Frequency (rad/s)')
    plt.ylabel('Amplitude (a.u.)')
    plt.title('F = {0} m = {1}'.format(F,m))
    plt.legend()

1 Answers1

0

np.interp needs its second parameter to be monotonically increasing. You can use np.argmax() instead, to find the index of the maximum.

To find the interpolated w-values corresponding to an arbitrary amplitude, you could use the find_roots function from How to find the exact intersection of a curve (as np.array) with y==0?

import numpy as np
import matplotlib.pyplot as plt

def find_roots(x, y):
    s = np.abs(np.diff(np.sign(y))).astype(bool)
    return x[:-1][s] + np.diff(x)[s] / (np.abs(y[1:][s] / y[:-1][s]) + 1)

F = 10
m = 5
w0 = 1
w = np.arange(0.01, 5, 0.01)

b1 = 0.25 * m * w0
G1 = np.sqrt((m ** 2) * (((w ** 2) - (w0 ** 2)) ** 2) + (b1 ** 2) * (w ** 2))

A1 = F / G1
A1_Max = max(A1)
w1_Max = w[np.argmax(A1)]

A_special = 5
w_special = find_roots(w, A1 - A_special)

plt.figure(figsize=(20, 20))
plt.plot(w, A1, '-', label='b=0.25*m*w0')
plt.plot(w1_Max, A1_Max, 'ro', label='Maximum amplitude')
plt.plot(w_special, np.repeat(A_special, len(w_special)), 'go', label=f'Special amplitude ({A_special})')
plt.xlabel('Frequency (rad/s)')
plt.ylabel('Amplitude (a.u.)')
plt.title(f'F = {F}  m = {m}')
plt.legend()
plt.margins(x=0)
plt.tight_layout()
plt.show()

plotting the maximum of a curve

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • Could you please explain what the 'w[]' is around np.argmax(). I couldn't find anything about it online. – Chris Neill Jan 03 '22 at 11:59
  • `np.argmax(A1)` gives the index ("arg") of the maximum of `A1`. In this example that index would be `97. `w` is an array of frequency values (going from `0.01` to `5`). `w[np.argmax(A1)]` will be `w[97]` or `0.98`, being the frequency corresponding to the maximum of `A1`. – JohanC Jan 03 '22 at 13:36