我使用matplotlib
和matplotlib widgets
编写了这段代码,当单击单选按钮时,它们在同一图形上显示4个分布直方图。每个分布函数具有不同的参数,因此,当单击特定分布函数的单选按钮时,图形底部的滑块也会被重新初始化(滑块标题以及最小和最大值),但是此更新的滑块变得无响应。使用滑块更改值时,图形不会更新。用于控制样本数量的n_sample
滑块在所有分布直方图中都可以正常工作,但是当图从正态分布切换到任何其他分布时,其他滑块则无响应。但是,mean
和std
滑块在正态分布下工作正常。请帮助我解决如何使滑块与其他3个分布直方图一起使用的问题。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.32, bottom=0.25)
m0 = -2.5
std0 = 5
n0 = 1000
nd = np.random.normal(m0, std0, n0)
ax.hist(nd, normed=True, bins = 20, alpha=0.5)
axcolor = 'lightgray'
axmean = plt.axes([0.25, 0.01, 0.65, 0.03], facecolor=axcolor)
axstd = plt.axes([0.25, 0.06, 0.65, 0.03], facecolor=axcolor)
axssize = plt.axes([0.25, 0.11, 0.65, 0.03], facecolor=axcolor)
smean = Slider(axmean, 'Mean', -5, 5, valinit=m0)
sstd = Slider(axstd, 'Std', 0.1, 10.0, valinit=std0)
sn = Slider(axssize, 'n_sample', 10, 10000, valinit=n0, valfmt='%d')
rax = plt.axes([0.025, 0.5, 0.2, 0.2], facecolor=axcolor)
radio = RadioButtons(rax, ('Normal', 'Gamma', 'Exponential', 'Uniform'), active=0)
def change_dist(label):
if label == 'Normal':
normal_dist()
elif label == 'Gamma':
gamma_dist()
elif label == 'Exponential':
exp_dist()
else:
uni_dist()
radio.on_clicked(change_dist)
def normal_dist():
axmean.clear()
axstd.clear()
m0 = -2.5
std0 = 5
n0 = 1000
nd = np.random.normal(m0, std0, n0)
ax.cla()
ax.hist(nd, normed=True, bins = 20, alpha=0.5)
plt.draw()
smean.__init__(axmean, 'Mean', -5, 5, valinit=m0)
sstd.__init__(axstd, 'Std', 0.1, 10.0, valinit=std0)
def gamma_dist():
axmean.clear()
axstd.clear()
gamma_sh0 = 1.0
gamma_sc0 = 1.0
gamma_n0 = 1000
nd = np.random.gamma(gamma_sh0, gamma_sc0, gamma_n0)
ax.cla()
ax.hist(nd, normed=True, bins=20, color='orange', alpha=0.5)
plt.draw()
#sh = Slider(axmean, 'Shape', 0.1, 10.0, valinit=sh0)
#sc = Slider(axstd, 'Scale', 0.1, 10.0, valinit=sc0)
axmean.spines['left'].set_color('k')
axmean.spines['right'].set_color('k')
axmean.spines['bottom'].set_color('k')
axmean.spines['top'].set_color('k')
axmean.set_facecolor('lightgray')
smean.__init__(axmean, 'Shape', 0.1, 10.0, valinit=gamma_sh0)
sstd.__init__(axstd, 'Scale', 0.1, 10.0, valinit=gamma_sc0)
def exp_dist():
axmean.clear()
axstd.clear()
exp_sc0 = 1.0
exp_n0 = 1000
nd = np.random.exponential(exp_sc0, exp_n0)+7
ax.cla()
ax.hist(nd, normed=True, bins=20, color='green', alpha=0.5)
plt.draw()
smean.__init__(axstd, 'Scale', 0.1, 10.0, valinit=exp_sc0)
axmean.spines['left'].set_color('w')
axmean.spines['right'].set_color('w')
axmean.spines['bottom'].set_color('w')
axmean.spines['top'].set_color('w')
axmean.set_facecolor('w')
axmean.set_axis_off()
sstd.__init__(axstd, '', )
def uni_dist():
axmean.clear()
axstd.clear()
low0 = 0.1
high0 = 1.0
uni_n0 = 10000
nd = np.random.uniform(low0, high0, uni_n0)
ax.cla()
ax.hist(nd, normed=True, bins=20, color='r', alpha=0.5)
plt.draw()
axmean.spines['left'].set_color('k')
axmean.spines['right'].set_color('k')
axmean.spines['bottom'].set_color('k')
axmean.spines['top'].set_color('k')
axmean.set_facecolor('lightgray')
smean.__init__(axmean, 'High', 0.1, 10.0, valinit=high0)
sstd.__init__(axstd, 'Low', -1.0, 10.0, valinit=low0)
def update(val):
mv = smean.val
stdv = sstd.val
n_sample = round(sn.val)
nd = np.random.normal(loc=mv, scale=stdv, size=n_sample)
#Redraw histogram
ax.cla()
ax.hist(nd, normed=True, bins=20, alpha=0.5)
plt.draw()
if radio.value_selected == 'Gamma':
gamma_sh = smean.val
gamma_sc = sstd.val
gamma_n = round(sn.val)
nd = np.random.gamma(gamma_sh, gamma_sc, gamma_n)
ax.cla()
ax.hist(nd, normed=True, bins=20, color='orange', alpha=0.5)
plt.draw()
elif radio.value_selected == 'Exponential':
exp_sc = smean.val
exp_n = round(sn.val)
nd = np.random.exponential(exp_sc, exp_n)+7
ax.cla()
ax.hist(nd, normed=True, bins=20, color='green', alpha=0.5)
plt.draw()
elif radio.value_selected == 'Uniform':
low = sstd.val
high = smean.val
uni_n = round(sn.val)
nd = np.random.uniform(low, high, uni_n)
ax.cla()
ax.hist(nd, normed=True, bins=20, color='r', alpha=0.5)
plt.draw()
smean.on_changed(update)
sstd.on_changed(update)
sn.on_changed(update)
plt.show()