Matplotlib:绘制带多段断裂X轴的多箱线图
嘿,我来帮你搞定这个多段断裂X轴的箱线图!既然你已经把数据按X的整数部分分组到my_data里了,那接下来用Python的matplotlib配合合适的工具就能轻松实现需求。下面是两种可行的方案,你可以根据自己的偏好选择:
方案1:使用
brokenaxes库(推荐,快速实现多段断裂) 这个第三方库专门为matplotlib设计,能一键处理多段断裂轴,省去手动拼接子图的麻烦。
1. 先安装依赖(如果还没装)
pip install matplotlib brokenaxes
2. 核心代码实现
import matplotlib.pyplot as plt from brokenaxes import brokenaxes # 第一步:过滤my_data中的空组,提取有数据的X整数标签和对应数据 x_labels = [i for i, group in enumerate(my_data) if len(group) > 0] valid_data = [group for group in my_data if len(group) > 0] # 第二步:设置X轴的连续区间(根据你的实际数据调整) # 比如如果你的X整数有效标签是[0,1,2,5,6,9],那么连续区间是(0,3)、(5,7)、(9,10) # 中间的3-5、7-9会自动显示为断裂 x_continuous_ranges = [(0, 3), (5, 7), (9, 10)] # 第三步:初始化断裂轴对象 bax = brokenaxes(xlims=x_continuous_ranges, hspace=0.05) # hspace控制断裂处的间距 # 第四步:绘制箱线图,设置位置和刻度 positions = list(range(len(valid_data))) # 每个箱线图在轴上的位置索引 bax.boxplot(valid_data, positions=positions) # 绑定实际的X整数标签到刻度 bax.set_xticks(positions) bax.set_xticklabels(x_labels) # 添加图表标注 bax.set_title('Boxplot with Multi-Broken X-axis') bax.set_xlabel('X Integer Part') bax.set_ylabel('Y Values') plt.tight_layout() plt.show()
关键细节说明
- 确定连续区间:你需要根据
x_labels(有数据的X整数部分)来设置xlims,把连续的X值区间列出来。比如如果X有效标签是[0,1,3,4,6],那么连续区间就是[(0,2), (3,5), (6,7)],中间的2-3、5-6会自动显示断裂。 - 空组过滤:代码自动跳过
my_data中的空列表,避免绘制无意义的空箱线图。 - 位置对齐:
positions确保每个箱线图的位置和x_labels一一对应,保证X轴刻度显示正确。
方案2:手动拼接子图(无需第三方库,高度自定义)
如果你不想依赖第三方库,可以手动创建多个子图拼接,模拟断裂轴效果,适合需要高度定制化的场景。
import matplotlib.pyplot as plt # 同样先过滤空组,提取有效数据和标签 x_labels = [i for i, group in enumerate(my_data) if len(group) > 0] valid_data = [group for group in my_data if len(group) > 0] # 创建3个子图(根据断裂数量调整),共享Y轴保证对齐 fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(10, 5), sharey=True) d = 0.015 # 断裂标记的大小参数 # 第一个子图:显示X=0,1,2的数据 ax1.boxplot(valid_data[0:3], positions=[0,1,2]) ax1.set_xlim(-0.5, 2.5) ax1.set_xticks([0,1,2]) ax1.set_xticklabels(x_labels[0:3]) # 隐藏右侧边框,添加断裂标记 ax1.spines['right'].set_visible(False) kwargs = dict(transform=ax1.transAxes, color='k', clip_on=False) ax1.plot((1-d, 1+d), (-d, +d), **kwargs) ax1.plot((1-d, 1+d), (1-d, 1+d), **kwargs) # 第二个子图:显示X=5,6的数据 ax2.boxplot(valid_data[3:5], positions=[5,6]) ax2.set_xlim(4.5, 6.5) ax2.set_xticks([5,6]) ax2.set_xticklabels(x_labels[3:5]) # 隐藏左右边框,添加双向断裂标记 ax2.spines['left'].set_visible(False) ax2.spines['right'].set_visible(False) ax2.plot((-d, +d), (-d, +d), **kwargs) ax2.plot((-d, +d), (1-d, 1+d), **kwargs) ax2.plot((1-d, 1+d), (-d, +d), **kwargs) ax2.plot((1-d, 1+d), (1-d, 1+d), **kwargs) # 第三个子图:显示X=9的数据 ax3.boxplot(valid_data[5:6], positions=[9]) ax3.set_xlim(8.5, 9.5) ax3.set_xticks([9]) ax3.set_xticklabels(x_labels[5:6]) # 隐藏左侧边框,添加断裂标记 ax3.spines['left'].set_visible(False) ax3.plot((-d, +d), (-d, +d), **kwargs) ax3.plot((-d, +d), (1-d, 1+d), **kwargs) # 调整子图间距,让断裂处看起来连贯 plt.subplots_adjust(wspace=0.05) # 添加全局标注 fig.suptitle('Boxplot with Multi-Broken X-axis (Manual Setup)') fig.text(0.5, 0.04, 'X Integer Part', ha='center') fig.text(0.04, 0.5, 'Y Values', va='center', rotation='vertical') plt.show()
内容的提问来源于stack exchange,提问作者GRquanti
相关产品推荐
相关产品推荐

