Home > database >  How to find x-value of maximum in a certain range?
How to find x-value of maximum in a certain range?

Time:09-24

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.

Plot

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()

enter image description here

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()

enter image description here

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()

enter image description here

  • Related