Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python : fit a curve to a list of integers

I have a list of integers.

intList = [96, 98, 120, 163, 158, 166, 201, 201, 159, 98, 93, 73, 77, 72]

These numbers represent the grey values of a strip of 14 pixels, I would like to fit a curve to the distribution and save the x location of the vertex.

For the sake of context: I'm really working with a (much larger) lists of lists, each list containing the grey value of a row of pixel from an image. For each row of pixels, I would like to plot a curve to the data and append the x-location of the vertex to a growing list. Each row of pixels will have some noise, but one and only one broad, clear peak of pixel intensity (sample image below)

the image from which I am extracting data

I have NumPy, SciPy, matplotlib, and pillow, but I don't know very much about the many functions found within each. Can anybody point me towards a module or functions that can likely do this?

like image 666
Zac Avatar asked Feb 01 '26 23:02

Zac


1 Answers

To fit a polynomial, e.g. quadratic, use polyfit:

from pylab import *

x = arange(len(intList))
p = polyfit(x, intList, 2)
a, b, c = p
x0 = -0.5*b/a # x coordinate of vertex

# plot
x = arange(len(intList))
plot(x, intList)
plot(x, polyval(p, x))
axvline(x0, color='r', ls='--')

quadratic fit

To fit a more complicated function, e.g. a Gaussian, you can use curve_fit:

from scipy.optimize import curve_fit

# define function to fit
ffunc = lambda x, a, x0, s: a*exp(-0.5*(x-x0)**2/s**2)

# fit with initial guess a=100, x0=5, s=2
p, _ = curve_fit(ffunc, x, intList, p0=[100,5,2])

x0 = p[1] # location of the mean

# plot
plot(x, intList)
plot(x, ffunc(x, *p))
axvline(x0, color='r', ls='--')

Gaussian fit

(Although to fit a Gaussian you're probably better off directly calculating the mean and variance of the distribution.)

like image 119
mcwitt Avatar answered Feb 03 '26 12:02

mcwitt