I'm producing a histogram with an overlaid normal distribution, using scipy.stats.norm.
This MWE
import pandas as pd
import matplotlib.pyplot as plt
import scipy.stats as stats
import numpy as np
length = 1000
np.random.seed(100)
dictOne = {
"A": np.random.randn(length),
"B": np.random.randn(length),
"C": np.random.randn(length)}
df2 = pd.DataFrame(dictOne)
column = 'B'
df = df2[df2[column] > -999]
fig, ax = plt.subplots()
h, edges, _ = ax.hist(df[column], alpha = 0.5, density = True, bins = 50)
param = stats.norm.fit(df2[column].dropna()) # Fit a normal distribution to the data
x = np.linspace(*df2[column].agg([min, max]), 1000) # x-values
#pdf_fitted = (x, stats.norm.pdf(df2[column], *param))
binwidth = np.diff(edges).mean()
ax.plot(x, stats.norm.pdf(x, *param)*h.sum()*binwidth, color = 'r')
produces
but when I apply basically the same code:
fig, ax = plt.subplots()
h, edges, _ = ax.hist(df['delta z'], alpha = 0.5, density = True, bins = 50)
param = stats.norm.fit(df['delta z'].dropna()) # Fit a normal distribution to the data
#pdf_fitted = stats.norm.pdf(df['delta z'], *param)
x = np.linspace(*df['delta z'].agg([min, max]), 1000) # x-values
binwidth = np.diff(edges).mean()
ax.plot(x, stats.norm.pdf(x, *param)*h.sum()*binwidth, color = 'r')
plt.grid(which = 'both')
plt.title(r'$\Delta z$ distribution for %s against %s'%(graph_title, xname), fontsize = 25)
plt.xlabel(r'$\Delta z = z_{spec} - z_{photo}$', fontsize = 25)
plt.ylabel('Number', fontsize = 25)
plt.xticks(fontsize = 25)
plt.yticks(fontsize = 25)
xmin, xmax = min(df['delta z']), max(df['delta z'])
plt.xlim(xmin, xmax)
plt.annotate(
r'''$\mu_{\Delta z}$ = %.3f
$\sigma_{\Delta z}$ = %.3f'''%(param[0], param[1]),
fontsize = 25, color = 'r', xy=(0.85, 0.85), xycoords='axes fraction')
to my actual data (which is in a large text file), I get a fit like this:
The data is in a large text file, so I can't include it here. But my question is, the fit in the toy example is pretty good to the numbers, but with the real data, I would have expected the red curve to fit closer to the histogram. Is there anything I can do to improve the fit, maybe bin size or something? I don't know enough about scipy.stats to know how to make it a better fit.
