Ajustar la distribución lognormal a los datos ya almacenados en python

Me gustaría hacer un ajuste lognormal a mis datos ya agrupados. La ttwig de la barra se ve así: introduzca la descripción de la imagen aquí

Desafortunadamente, cuando trato de usar el lognorm.pdf() estándar, la forma de la distribución ajustada es muy diferente. Supongo que es porque mis datos ya están agrupados. Aquí está el código:

 times, data, bin_points = ReadHistogramFile(filename) xmin = 200 xmax = 800 x = np.linspace(xmin, xmax, 1000) shape, loc, scale = stats.lognorm.fit(data, floc=0) pdf = stats.lognorm.pdf(x, shape, loc=loc, scale=scale) area=data.sum() plt.bar(bars, data, width=10, color='b') plt.plot(x*area, pdf, 'k' ) 

Así es como se ve la distribución ajustada: introduzca la descripción de la imagen aquí Obviamente, hay algo mal con la escala. Aunque estoy menos preocupado por eso. Mi principal problema es, la forma de la distribución. Esto podría ser duplicado para: esta pregunta, pero no pude encontrar una solución correcta. Lo intenté y todavía tengo una forma muy similar a la de hacer lo anterior. ¡Gracias por cualquier ayuda!

Actualización: Al usar curve_fit() pude obtener algo de ajuste. Pero todavía no estoy satisfecho. Me gustaría tener los contenedores originales y no los contenedores de unidades. Tampoco estoy seguro de qué está sucediendo exactamente y si no hay una mejor opción. Aquí está el código:

 def normalize_integral(data, bin_size): normalized_data = np.zeros(size(data)) print bin_size sum = data.sum() integral = bin_size*sum for i in range(0, size(data)-1): normalized_data[i] = data[i]/integral print 'integral:', normalized_data.sum()*bin_size return normalized_data def pdf(x, mu, sigma): """pdf of lognormal distribution""" return (np.exp(-(np.log(x) - mu)**2 / (2 * sigma**2)) / (x * sigma * np.sqrt(2 * np.pi))) bin_points=np.linspace(280.5, 1099.55994, len(bin_points)) data=[9.78200000e+03 1.15120000e+04 1.18000000e+04 1.79620000e+04 2.76980000e+04 2.78260000e+04 3.35460000e+04 3.24260000e+04 3.16500000e+04 3.30820000e+04 4.84560000e+04 5.86500000e+04 6.34220000e+04 5.11880000e+04 5.13180000e+04 4.74320000e+04 4.35420000e+04 4.13400000e+04 3.60880000e+04 2.96900000e+04 2.66640000e+04 2.58720000e+04 2.57560000e+04 2.20960000e+04 1.46880000e+04 9.97200000e+03 5.74200000e+03 3.52000000e+03 2.74600000e+03 2.61800000e+03 1.50000000e+03 7.96000000e+02 5.40000000e+02 2.98000000e+02 2.90000000e+02 2.22000000e+02 2.26000000e+02 1.88000000e+02 1.20000000e+02 5.00000000e+01 5.40000000e+01 5.80000000e+01 5.20000000e+01 2.00000000e+01 2.80000000e+01 6.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] normalized_data_unitybins = normalize_integral(data,1) plt.figure(figsize=(9,4)) ax1=plt.subplot(121) ax2=plt.subplot(122) ax2.bar(unity_bins, normalized_data_unitybins, width=1, color='b') fitParams, fitCov = curve_fit(pdf, unity_bins, normalized_data_unitybins, p0=[1,1],maxfev = 1000000) fitData=pdf(unity_bins, *fitParams) ax2.plot(unity_bins, fitData,'g-') ax1.bar(bin_points, normalized_data_unitybins, width=10, color='b') fitParams, fitCov = curve_fit(pdf, bin_points, normalized_data_unitybins, p0=[1,1],maxfev = 1000000) fitData=pdf(bin_points, *fitParams) ax1.plot(bin_points, fitData,'g-') 

introduzca la descripción de la imagen aquí

    Como mencionó, no puede usar lognorm.fit en los datos agrupados. Así que todo lo que necesita hacer es restaurar los datos sin procesar del histogtwig. Obviamente, esto no es “sin pérdida”, cuantos más contenedores mejor.

    Código de muestra con algunos datos generados:

     import numpy as np import scipy.stats as stats import matplotlib.pylab as plt # generate some data ln = stats.lognorm(0.4,scale=100) data = ln.rvs(size=2000) counts, bins, _ = plt.hist(data, bins=50) # note that the len of bins is 51, since it contains upper and lower limit of every bin # restre data from histogram: counts multiplied bin centers restred = [[d]*int(counts[n]) for n,d in enumerate((bins[1:]+bins[:-1])/2)] # flatten the result restred = [item for sublist in restred for item in sublist] print stats.lognorm.fit(restred, floc=0) dist = stats.lognorm(*stats.lognorm.fit(restred, floc=0)) x = np.arange(1,400) y = dist.pdf(x) # the pdf is normalized, so we need to scale it to match the histogram y = y/y.max() y = y*counts.max() plt.plot(x,y,'r',linewidth=2) plt.show() 

    histograma ajustado