Abel Gutiérrez
Abel Gutiérrez

Reputation: 189

Weird matplotlib histogram: a change in x limit spoils histogram

I'm doing a histogram related to a $\chi^2$ distribution.

The values I want to represent are a probability, in this case, almost all probabilities are 1. This is the histogram I get without modifying x limit:

First histogram

The values are calculated properly, the histogram has the form it should have. The problem is the x axis. The ticks are difficult to read and limits don't have sense since the probabilities are between 0 and 1. So I add the line ax1.set_xlim([0, 1]), and the result is:

Second histogram

Where are the bins? Why is this not working? I tried to change the number of bins, the limits...

Here the full code:

import numpy as np
import numpy.random as rnd
import matplotlib.pyplot as plt
from scipy.special import gamma as gamma
import scipy.integrate as inte


rnd.seed(1)


def chi2(mu, sig, x):
    if sig  != 0:
        return np.sum(((x-mu)/sig)**2)


def chi2PDF(n):
    cte = 2**(n/2)*gamma(n/2)
    noCTE = lambda x : x**(n/2-1)*np.exp(-x/2)
    pdf = lambda chi2 : noCTE(chi2)/cte
    return pdf


# returns the normal distribution of the experiment
def experiment(mean, sig, n):
    return rnd.normal(mean, sig, n)


mTeo = 130
mTeoNew = 145
sigTeo = 10

n = 10 # measurements in one experiment
N = int(1e4) # number of experiments

bins = 100 # number of bins in plots

# calculate chi2 from experiments
chi2Exp = np.array([chi2(mTeo, mTeoNew, experiment(mTeo, sigTeo, n)) for i in range(N)])
# determine 0 and max values of chi2 obtained
rangeChi2 = np.linspace(0, np.max(chi2Exp), bins)
# theorecial chi2 PDF
chi2PDFTeo = chi2PDF(n)
# values of the theoretical chi2 PDF
chi2Teo = chi2PDFTeo(rangeChi2)

def p_x_bigger_x0(n, x0):
    return inte.quad(chi2PDF(n), x0, np.inf)[0]


probs = []
for i in range(len(chi2Exp)):
    probs.append(p_x_bigger_x0(n, chi2Exp[i]))
probs = np.array(probs)

#plot

fig = plt.figure()

ax1 = plt.subplot2grid(shape = (1, 1),
                       loc = (0, 0),
                       rowspan = 1,
                       colspan = 1,
                       fig = fig)

hist = ax1.hist(probs,
                bins = bins)

ax1.set_xlabel('$P(\chi^2\geq\chi^2_0)$')
ax1.set_ylabel('Cuentas')

#ax1.set_xlim([0, 1]) # problem here

plt.show()

Upvotes: 1

Views: 251

Answers (1)

AfterFray
AfterFray

Reputation: 1851

You can use symlog for your plot.

code

plt.rcParams['figure.figsize'] = [10,5]
fig = plt.figure()
ax1 = plt.subplot2grid(shape = (1, 1),
                       loc = (0, 0),
                       rowspan = 1,
                       colspan = 1,
                       fig = fig)

hist = ax1.hist(probs, bins = bins)

ax1.set_xlabel('$P(\chi^2\geq\chi^2_0)$')
ax1.set_ylabel('Cuentas')
plt.yscale("symlog")
plt.show()

result enter image description here

Upvotes: 1

Related Questions