python - Interactive Slider Bar Chart Color Control -
i have 4 sets of random normal distributed numbers. means used plot bar chart each set's 95% confidence intervals plotted errorbar.
given value y, 4 different colors set bars corresponding 4 ranges y in: 1. lower bound avg; 2. avg upper bound; 3. below lower; 4. above upper.
i want use slider control y value , update bar color each time slide, tried use following code bar charts cannot plotted every update.
could give me ideas?
import matplotlib.pyplot plt import pandas pd import numpy np import scipy.stats st matplotlib.widgets import slider np.random.seed(12345) df = pd.dataframe([np.random.normal(33500,150000,3650), np.random.normal(41000,90000,3650), np.random.normal(41000,120000,3650), np.random.normal(48000,55000,3650)], index=[1992,1993,1994,1995]) n = len(df.columns)-1 # degree of freedom avg = df.mean(axis=1) # mean each row std = df.sem(axis=1) # unbiased standard deviation year = df.index.map(str) # convert string conf95 = st.t.ppf(0.95, n)*std # 95% confidence interval upper = avg + conf95 lower = avg - conf95 colormap = ['blue', 'aqua', 'orange', 'brown'] ini = 39900 chk1 = ini>upper # check if y greater upper bound: blue chk2 = ini<lower # check if y smaller lower bound: brown chk3 = (ini>=lower) & (ini<=avg) # check if y in between avg , lower: orange chk4 = (ini>avg) & (ini<=upper) # check if y in between avg , upper: aqua fig, ax =plt.subplots() ax.bar(df.index[chk1.values], avg.iloc[chk1.values], width=1, edgecolor='k', color='blue') ax.bar(df.index[chk2.values], avg.iloc[chk2.values], width=1, edgecolor='k', color='brown') ax.bar(df.index[chk3.values], avg.iloc[chk3.values], width=1, edgecolor='k', color='orange') ax.bar(df.index[chk4.values], avg.iloc[chk4.values], width=1, edgecolor='k', color='aqua') ax.axhline(y=ini,xmin=0,xmax=10,linewidth=1,color='k') ax.errorbar(df.index, avg, yerr=conf95, fmt='.',capsize=15, color='k') plt.subplots_adjust(left=0.1, bottom=0.2) plt.xticks(df.index, year) # map xlabel string plt.yticks(np.arange(0,max(avg)+1,max(avg)/5)) axcolor = 'lightgoldenrodyellow' axy = plt.axes([0.1, 0.1, 0.7, 0.03], axisbg=axcolor) sy = slider(axy, 'y', 0.1, int(max(upper)+1), valinit=ini)
until step color works fine. update func not work thou.
def update(val): ax.cla() yy = sy.val chk1 = yy>upper chk2 = yy<lower chk3 = (yy>=lower) & (yy<=avg) chk4 = (yy>avg) & (yy<=upper) ax.bar(df.index[chk1.values], avg.iloc[chk1.values], width=1, edgecolor='k', color='blue') ax.bar(df.index[chk2.values], avg.iloc[chk2.values], width=1, edgecolor='k', color='brown') ax.bar(df.index[chk3.values], avg.iloc[chk3.values], width=1, edgecolor='k', color='orange') ax.bar(df.index[chk4.values], avg.iloc[chk4.values], width=1, edgecolor='k', color='aqua') ax.bar(df.index, avg, width=1, edgecolor='k', color='silver') ax.errorbar(df.index, avg, yerr=conf95, fmt='.',capsize=15, color='k') ax.axhline(y=yy,xmin=0,xmax=10,linewidth=1,color='k') fig.canvas.draw_idle() sy.on_changed(update)
really appreciate insights , thank guys much!
best shawn
simply delete line
ax.bar(df.index, avg, width=1, edgecolor='k', color='silver')
i don't know why put there, plot complete unicolor barchart on top of colored bars , hide them.
in order make interaction possible, interactive backend needs used. not work out of box in ipython when
%matplotlib inline
mode set. options have: - using
%matplotlib notebook
in ipython qt console or jupyter notebook. - using gui backend when running code script, adding
plt.show()
. in spyder can ensured running script in new dedicated window sketched here.
Comments
Post a Comment