How can I determine the x-value of a maximum of a data set within a certain range?
For context, these records the datasets look like this:
value['Wavelength']
:PixelNo 0 1167.467506 1 1167.219570 2 1166.971628 3 1166.723680 4 1166.475725 ... 3635 233.904486 3636 233.641110 3637 233.377731 3638 233.114350 3639 232.850967 Name: Wavelength, Length: 3640, dtype: float64
value['Calib_1']
:PixelNo 0 1.000000e 00 1 5.500000e 01 2 3.500000e 01 3 1.000000e-07 4 4.600000e 01 ... 3635 4.000000e 01 3636 7.400000e 01 3637 1.000000e-07 3638 3.000000e 00 3639 1.600000e 01 Name: Calib_1, Length: 3640, dtype: float64
This is an example of the corresponding plot of all data sets.
CodePudding user response:
You can use argmax
method which returns the index of the maximum value.
Let's suppose you have a curve like this:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
value = pd.DataFrame({'Wavelength': np.linspace(250, 600, 10000)})
value['Calib_1'] = (np.sin(2*np.pi/20*value['Wavelength'])*np.exp(-(value['Wavelength']-455)**2/20/(600-250)))**2
fig, ax = plt.subplots()
ax.plot(value['Wavelength'], value['Calib_1'], color = 'blue')
ax.set_xlabel('Wavelength')
ax.set_ylabel('Calib_1')
plt.show()
The above curve is designed to have a maximum in 455
.
You can find the index of the maximum with:
value['Calib_1'].argmax()
# 5857
and use it to get the corresponding x axis value through loc
method:
value.loc[value['Calib_1'].argmax(), 'Wavelength']
# 455.015501550155
As you can see, it returns a value approximately close to the exact value of 455
. The error is to be addressed to the x axis discretization with numpy.linspace
.
You can plot the maximum on the above plot with:
id_max = value['Calib_1'].argmax()
x_max = value.loc[id_max, 'Wavelength']
y_max = value.loc[id_max, 'Calib_1']
fig, ax = plt.subplots()
ax.plot(value['Wavelength'], value['Calib_1'], color = 'blue')
ax.plot(x_max, y_max, marker = 'o', color = 'red')
ax.set_xlabel('Wavelength')
ax.set_ylabel('Calib_1')
plt.show()
If you need a maximum only on a specific range, let's say [500, 550]
, then first of all you have to filter the dataframe, then compute the index of the maximum:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
value = pd.DataFrame({'Wavelength': np.linspace(250, 600, 10000)})
value['Calib_1'] = (np.sin(2*np.pi/20*value['Wavelength'])*np.exp(-(value['Wavelength']-455)**2/20/(600-250)))**2
value_filt = value[(value['Wavelength'] >= 500) & (value['Wavelength'] <= 550)].reset_index()
id_max = value_filt['Calib_1'].argmax()
x_max = value_filt.loc[id_max, 'Wavelength']
y_max = value_filt.loc[id_max, 'Calib_1']
fig, ax = plt.subplots()
ax.plot(value['Wavelength'], value['Calib_1'], color = 'blue')
ax.plot(x_max, y_max, marker = 'o', color = 'red')
ax.axvline(x = 500, color = 'black', linestyle = '--')
ax.axvline(x = 550, color = 'black', linestyle = '--')
ax.set_xlabel('Wavelength')
ax.set_ylabel('Calib_1')
plt.show()