如何在Matplotlib中实现带断裂Y轴但连续异常值柱的柱状图
解决Matplotlib断裂Y轴柱状图异常值柱子连续显示问题
关键修改点:
- 缩小子图间距:通过
subplots的hspace参数设为0,让上下子图紧密贴合 - 拆分柱子绘制:仅在上子图绘制异常值柱子,下子图绘制所有柱子并让异常值柱子顶到子图上边界,实现视觉连续
- 添加断裂标记:在轴的断裂处绘制斜线,明确展示轴断裂效果
修改后的完整代码:
import matplotlib.pyplot as plt import numpy as np # 生成模拟数据 x = np.arange(1, 6) y = np.exp(x) y[2] = 15000 # 设置异常值 # 创建上下子图,关闭间距,共享X轴 f, (ax, ax2) = plt.subplots(2, 1, sharex=True, facecolor='w', hspace=0) # ---------------------- 下子图(显示常规值和异常值下半部分) ---------------------- # 绘制所有柱子,异常值柱子顶到下子图的Y轴上限 bars2 = ax2.bar(x, y) # 手动设置异常值柱子的高度为下子图Y轴上限,确保顶到子图顶部 bars2[2].set_height(ax2.get_ylim()[1]) ax2.set_ylim(0, 100) # ---------------------- 上子图(仅显示异常值上半部分) ---------------------- # 仅绘制异常值柱子,底部对齐上子图Y轴下限,高度为异常值超出下限的部分 ax.bar(x[2], y[2] - ax.get_ylim()[0], bottom=ax.get_ylim()[0]) ax.set_ylim(10000, 20000) # ---------------------- 隐藏轴脊,调整刻度 ---------------------- # 隐藏上下子图相邻的轴脊 ax.spines['bottom'].set_visible(False) ax2.spines['top'].set_visible(False) # 上子图不显示X轴刻度,下子图显示X轴刻度 ax.xaxis.tick_top() ax.tick_params(labeltop=False) # ---------------------- 添加断裂标记(斜线) ---------------------- d = .015 # 斜线的倾斜程度 kwargs = dict(transform=ax.transAxes, color='k', clip_on=False) ax.plot((-d, +d), (-d, +d), **kwargs) # 左上角斜线 ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) # 右上角斜线 kwargs.update(transform=ax2.transAxes) # 转换到下子图的坐标系 ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # 左下角斜线 ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # 右下角斜线 plt.savefig('broken-axis-barplot.png', dpi=100, bbox_inches='tight') plt.show()
代码说明:
- 子图间距控制:
hspace=0直接消除了上下子图之间的默认间距,让两个子图紧密连接 - 柱子拆分绘制:
- 下子图中,异常值柱子被强制设置为下子图Y轴上限高度,确保顶部对齐子图上边界
- 上子图仅绘制异常值柱子,底部从Y轴下限开始,高度为异常值超出下限的部分,底部对齐子图下边界
- 断裂标记:通过绘制4条斜线,清晰标示出Y轴的断裂位置,避免误解数据连续性
内容的提问来源于stack exchange,提问作者user1221
相关产品推荐
相关产品推荐

