Python:用X和Y值画图

Python: using X and Y values to draw a picture

我有一系列方法可以拍摄 89x22 像素的图像(尽管理论上大小无关紧要)并为每行像素拟合一条曲线以找到最重要信号的位置。最后,我有一个 Y 值列表,每行一个像素,还有一个 X 值列表,每行最重要的峰值位置。

我想测试不同类型的曲线,看看哪种模型的数据更好,为此,我希望能够打印出一张新图像,也是 89x22 像素,位置为最显着的峰每条线用一个红色像素标记。 A 附上了一个输入示例和一个(画得不好的)示例,说明我希望好的输出看起来像这样:

关于开始研究哪些模块有什么建议吗?

class image :

    def importImage (self) :
        """Open an image and sort all pixel values into a list of lists"""
        from PIL import Image               #imports Image from PIL library

        im = Image.open("testTop.tif")      #open the file
        size = im.size                      #size object is a tuple with the pixel width and pixel height
        width = size[0]                     #defines width object as the image width in pixels
        height = size[1]                    #defines the height object as the image height in pixels

        allPixels = list(im.getdata())      #makes a list of all pixels values
        pixelList = [allPixels[width*i : width * (i+1)] for i in range(height)]     #takes mega-list and makes a list of lists by row
        return(pixelList)                   #returns list of lists

    def fitCurves (self) :
        """
        Iterate through a list of lists and fit a curve to each list of integers. 
        Append the position of the list and the location of the vertex to a growing list.
        """
        from scipy.optimize import curve_fit
        import numpy as np
        from matplotlib import pyplot as pp
        from scipy.misc import factorial

        image = self.importImage()
        xList = []
        yList = []
        position = 0

        for row in image :
            #Gaussian fit equations kindly provided by user mcwitt
            x = np.arange(len(row))
            ffunc = lambda x, a, x0, s: a*np.exp(-0.5*(x-x0)**2/s**2)   # define function to fit
            p, _ = curve_fit(ffunc, x, row, p0=[100,5,2])           # fit with initial guess a=100, x0=5, s=2
            x0 = p[1]
            yList.append(position)
            position = position + 1
            xList.append(x0)
        print(yList)
        print(xList)

newImage = image()
newImage.fitCurves()

马拜:

import numpy as np
from matplotlib import pyplot as plt
from scipy import ndimage
from scipy import optimize
%matplotlib inline

# just a gaussian (copy paste from lmfit, another great package)
def my_gaussian(p,x):
    amp = p[0]
    cen = p[1]
    wid = p[2]
    return amp * np.exp(-(x-cen)**2 /wid)

# I do like to write a cost function separately. For the leastsquare algorithm it should return a vector.
def my_cost(p,data):
    return data - my_gaussian(p,data)

# i load the image and generate the x values
image = ndimage.imread('2d_gaussian.png',flatten=True)
x = np.arange(image.shape[1])
popt = []

# enumerate is a convenient way to loop over an iterable and keep track of the index.
y = []
for index,data in enumerate(image):
    ''' this is the trick to make the algorithm robust. 
    I do plug the index of the maximum value of the current row as
    initial guess for the center. Maybe it would be enough to do
    just that and the fit is unnecessary. Haven`t checked that.
    '''
    max_index = np.argmax(data)
    # initial guess.
    x0 = [1.,max_index,10]
    # call to the solver
    p,_ = optimize.leastsq(my_cost, x0, args = data)
    popt.append(p)
    y.append(index)
''' 
I do transpose the data.
As a consequence the values are stored row, not columnwise.
It is often easier to store the reusults inside a loop and 
convert the data later into a numpy array.
'''
gaussian_hat = np.array(popt).T
# without the transpose, it would be center = gaussian_hat[:,1]
center = gaussian_hat[1]
y = np.array(y)

''' i do like to use an axis handle for the plot. 
Not necessary, but gives me the opportunity to add new axis if necessary.
'''
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.imshow(image)
# since it is just a plot, I can plot the x, y coordinates
ax.plot(center,y,'k-')

# fitt of a 3th order polynomial
poly = np.polyfit(y,center,3)
# evaluation at points y
x_hat = np.polyval(poly,y)

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.imshow(image)
ax.plot(x_hat,y,'k-')
plt.savefig('2d_gaussian_fit.png')