奇怪的 matplotlib 直方图:x 限制的变化破坏了直方图
Posted
技术标签:
【中文标题】奇怪的 matplotlib 直方图:x 限制的变化破坏了直方图【英文标题】:Weird matplotlib histogram: a change in x limit spoils histogram 【发布时间】:2021-12-23 03:50:08 【问题描述】:我正在做一个与 $\chi^2$ 分布相关的直方图。
我要表示的值是一个概率,在这种情况下,几乎所有的概率都是1。这是我在不修改x限制的情况下得到的直方图:
值计算正确,直方图具有应有的形式。问题是x轴。由于概率在 0 和 1 之间,刻度很难阅读,限制没有意义。所以我添加了 ax1.set_xlim([0, 1])
行,结果是:
垃圾箱在哪里?为什么这不起作用?我试图改变垃圾箱的数量,限制......
这里是完整的代码:
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()
【问题讨论】:
如果您检查直方图跨度 (~ 2e-8),问题是您的 bin 太小了,它们甚至在[0,1]
.. 范围内都没有 1 个像素宽度。当您的值跨度非常小时,显示不在 0,1 范围内的值的方法
@UlisesBussi 我不确定这是否是问题所在。如果我在范围为[0,1]
时设置bins=1
,则应显示包含所有数据的单箱直方图,但它是(或看起来)空的。
即使有一个 bin,这个 bim 的“大”也是 4e-8.... 问题是我确定.. 试试看:做 1 个 bin 直方图,将范围设置为 [0,1]
(你什么也看不到),然后把它改成[0.9,1.1]
(还是什么都没有)。最后放[0.99999,1.00001]
,在那里你会看到一条小线(如果没有分别添加9和0,直到你看到栏)
【参考方案1】:
您可以将symlog
用于您的情节。
代码
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()
结果
【讨论】:
这个想法是为了搭上 1e-8+1。最后,数据也有问题,所以这不是正确的数据;用对了就没有这个问题了。以上是关于奇怪的 matplotlib 直方图:x 限制的变化破坏了直方图的主要内容,如果未能解决你的问题,请参考以下文章