Matplotlib绘制带误差棒条形图 如何显示y轴负半轴适配RectangleSelector
问题说明
我已经成功绘制各年度数据分布均值的条形图,附带95% CI置信区间标准误差棒。为了后续使用RectangleSelector矩形选择器,需要同时显示y轴的负半轴部分。
原有代码
%matplotlib qt from matplotlib.widgets import RectangleSelector import numpy as np import matplotlib.pyplot as plt import pandas as pd import math np.random.seed(12345) df = pd.DataFrame([np.random.normal(32000,200000,3650), np.random.normal(43000,100000,3650), np.random.normal(43500,140000,3650), np.random.normal(48000,70000,3650)], index=[1992,1993,1994,1995]) mean = [] ci95 = [] for i in range(len(df)): globals()['avg%s' % (i+92)] = np.mean(df.iloc[i]) globals()['semci%s' % (i+92)] = np.std(df.iloc[i])*1.96/math.sqrt(len(df.iloc[i])) mean.append(globals()['avg%s' % (i+92)]) ci95.append(globals()['semci%s' % (i+92)]) year = np.array(['1992','1993','1994','1995']) x_pos = np.arange(len(year)) def line_select_callback(eclick, erelease): 'eclick and erelease are the press and release events' global x1, x2, y1, y2 x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata print("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2)) probs = [] for i in range(len(df)): globals()['btw%s' % (i+92)] = 0 for j in range(len(df.iloc[i])): if (df.iloc[i,j] > y1) & (df.iloc[i,j] < y2): globals()['btw%s' % (i+92)] += 1 globals()['probs%s' % (i+92)] = globals()['btw%s' % (i+92)]/len(df.iloc[i]) probs.append(globals()['probs%s' % (i+92)]) my_cm = plt.get_cmap("Greens") ax.bar(x_pos, mean, yerr=ci95, align='center', alpha=0.5, ecolor='black', capsize=10, color = my_cm(np.array(probs))) ax.set_ylabel('') ax.set_xticks(x_pos) ax.set_xticklabels(year) ax.set_title('Assignment 3') ax.yaxis.grid(True) def toggle_selector(event): print(' Key pressed.') if event.key in ['Q', 'q'] and toggle_selector.RS.active: print(' RectangleSelector deactivated.') toggle_selector.RS.set_active(False) if event.key in ['A', 'a'] and not toggle_selector.RS.active: print(' RectangleSelector activated.') toggle_selector.RS.set_active(True) fig, ax = plt.subplots() ax.bar(x_pos, mean, yerr=ci95, align='center', alpha=0.5, ecolor='black', capsize=10) ax.set_ylabel('') ax.set_xticks(x_pos) ax.set_xticklabels(year) ax.set_title('Assignment 3') ax.yaxis.grid(True) print("\n click --> release") toggle_selector.RS = RectangleSelector(ax, line_select_callback, drawtype='box', useblit=False, button=[1, 3], minspanx=5, minspany=5, spancoords='pixels', interactive=True) plt.connect('key_press_event', toggle_selector) plt.show()
解决方法
在两个位置新增y轴范围设置代码即可实现负半轴显示:
- 初始化绘制条形图后添加
ax.set_ylim(bottom=-20000),可根据需要调整bottom的数值,控制负半轴的显示长度 - 回调函数
line_select_callback中每次重绘条形图后,也要添加同样的y轴范围设置代码,避免重绘后y轴自动回弹为默认范围
修改后的核心代码示例
初始化绘图部分
fig, ax = plt.subplots() ax.bar(x_pos, mean, yerr=ci95, align='center', alpha=0.5, ecolor='black', capsize=10) ax.set_ylim(bottom=-20000) # 新增行 ax.set_ylabel('') ax.set_xticks(x_pos) ax.set_xticklabels(year) ax.set_title('Assignment 3') ax.yaxis.grid(True)
回调函数重绘部分
my_cm = plt.get_cmap("Greens") ax.bar(x_pos, mean, yerr=ci95, align='center', alpha=0.5, ecolor='black', capsize=10, color = my_cm(np.array(probs))) ax.set_ylim(bottom=-20000) # 新增行 ax.set_ylabel('') ax.set_xticks(x_pos) ax.set_xticklabels(year) ax.set_title('Assignment 3') ax.yaxis.grid(True)
内容的提问来源于stack exchange,提问作者adrenaline245
相关产品推荐
相关产品推荐

