Matplotlib单图绘制多组并列箱线图的代码修改方法
同刻度下并列展示多组箱线图的实现方法
你可以通过给每组数据增加X轴偏移量的方式实现需求,核心是控制每组箱线图的宽度和横向偏移,避免同位置的图形重叠,最后将X轴刻度对齐到每组的中心位置即可。
以下是适配你提供的数据集结构的修改后完整代码:
import matplotlib.pyplot as plt import matplotlib.font_manager as font_manager import numpy as np import pandas as pd from io import StringIO font_prop = font_manager.FontProperties(size=18) # 配置分组参数:4个类别、箱线图宽度、每组对应偏移量 class_list = ['L', 'C', 'W', 'B'] box_width = 0.2 offset = [-0.3, -0.1, 0.1, 0.3] color_list = ['#2ecc71', '#3498db', '#f1c40f', '#9b59b6'] def plot(df): df = df.dropna() pos_cols = [f'P{i}' for i in range(1,11)] # 10个点位列 plt.figure(figsize=(14, 6)) for class_idx, class_name in enumerate(class_list): # 提取当前类别的所有点位数据 class_data = df[df['Class'] == class_name][pos_cols].values # 计算当前组箱线图的X坐标:基础点位+偏移量 x_pos = np.arange(1, 11) + offset[class_idx] # 绘制箱线图 bp = plt.boxplot( class_data, positions=x_pos, widths=box_width, patch_artist=True, label=class_name ) # 设置中位数线样式,和原有代码保持一致 for median in bp['medians']: median.set(color='r', linewidth=2) # 给箱线图设置填充色方便区分 for patch in bp['boxes']: patch.set_facecolor(color_list[class_idx]) patch.set_alpha(0.3) # 绘制对应散点,和箱线图位置对齐 for col_idx, col in enumerate(pos_cols): y_val = df[df['Class'] == class_name][col].values plt.scatter( [x_pos[col_idx]]*len(y_val), y_val, color=color_list[class_idx], alpha=0.6, s=15 ) # 调整X轴刻度,对齐到每个点位4个箱线图的中间位置 plt.xticks(np.arange(1,11), pos_cols, fontproperties=font_prop) plt.yticks(fontproperties=font_prop) plt.xlabel('点位', fontproperties=font_prop) plt.ylabel('对象尺寸', fontproperties=font_prop) plt.legend(prop=font_prop) plt.tight_layout() plt.show() # 读取示例数据,本地使用时替换为pd.read_csv('你的本地数据路径.csv', index_col=0)即可 data_str = """,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,Class 1,7.6,1.0,1.0,1.0,1.0,6.0,49.0,1.0,1.0,40.0,L 2,9.7,2.7,5.6,1.0,1.0,1.0,34.0,1.0,1.0,1.0,L 3,1.0,6.0,1.0,1.0,1.0,3.0,39.0,1.0,28.0,1.0,L 4,8.0,25.5,1.0,1.0,1.0,1.0,24.0,1.0,1.0,1.0,L 5,1.0,29.0,1.0,1.0,1.0,1.0,38.0,29.0,20.0,1.0,L 6,4.0,34.0,1.0,1.0,1.0,39.0,14.0,1.0,12.0,1.0,L 7,1.0,17.0,1.0,1.0,1.0,1.0,20.8,1.0,14.6,1.0,L 8,1.0,1.0,1.0,1.0,1.0,1.0,19.0,17.5,1.0,1.0,L 9,1.0,30.0,1.0,1.0,1.0,3.0,23.0,1.0,1.0,1.0,L 10,1.0,5.0,25.0,1.0,1.0,17.0,6.3,1.0,17.0,1.0,L 1,11.8,19.0,1.0,1.0,1.0,11.3,2.0,4.0,5.0,1.0,C 2,12.0,17.0,20.0,9.0,1.0,23.0,4.0,7.0,1.0,1.0,C 3,14.0,30.0,8.0,1.0,11.0,24.0,38.0,1.0,3.5,1.0,C 4,10.5,10.4,11.5,20.5,1.0,22.0,3.0,15.0,5.6,3.7,C 5,1.0,13.5,8.0,6.6,1.0,37.0,1.0,1.0,1.0,4.0,C 6,12.4,22.0,1.0,1.0,1.0,29.0,17.0,11.0,1.0,1.0,C 7,1.0,43.0,1.0,1.0,1.0,10.0,18.0,8.6,1.0,1.0,C 8,15.0,12.0,1.0,35.0,1.0,1.0,1.0,10.0,3.0,1.0,C 9,1.0,24.0,8.0,1.0,1.0,1.0,4.0,1.0,1.0,1.0,C 10,4.6,2.0,7.4,1.0,1.0,22.0,5.6,1.0,25.0,1.0,C 1,1.0,39.0,11.0,13.0,1.0,1.0,28.0,7.0,1.0,7.0,W 2,8.0,52.0,22.0,10.0,1.0,1.0,33.0,13.0,1.0,4.8,W 3,1.0,28.0,1.0,10.0,1.0,1.0,24.0,3.0,1.0,4.0,W 4,8.8,11.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,W 5,1.0,42.0,1.0,1.0,1.0,69.0,1.0,31.0,1.0,49.0,W 6,9.0,36.0,11.0,14.0,24.0,1.0,8.0,1.0,1.0,15.8,W 7,13.0,33.0,12.7,8.7,1.0,1.0,7.8,38.0,1.0,1.0,W 8,1.0,36.0,12.0,1.0,1.0,12.0,1.0,1.0,1.0,1.0,W 9,1.0,10.0,12.0,1.0,1.0,1.0,64.0,13.0,1.0,14.0,W 10,8.0,31.0,19.0,1.0,24.0,1.0,48.0,1.0,1.0,1.0,W 1,1.0,9.7,6.8,53.0,1.0,57.0,1.0,9.5,1.0,1.0,B 2,5.8,16.3,1.0,10.8,1.0,58.0,1.0,1.0,1.0,1.0,B 3,1.0,38.0,17.0,34.0,1.0,55.0,1.0,8.0,1.0,1.0,B 4,1.0,42.0,1.0,26.0,1.0,1.0,65.0,44.0,1.0,1.0,B 5,41.0,43.0,16.0,9.7,1.0,36.0,61.0,1.0,1.0,1.0,B 6,47.0,20.0,1.0,1.0,1.0,1.0,28.0,7.7,1.0,1.0,B 7,22.0,92.0,1.0,1.0,1.0,20.0,15.0,1.0,1.0,1.0,B 8,31.0,72.0,1.0,1.0,1.0,1.0,20.0,1.0,1.0,1.0,B """ df = pd.read_csv(StringIO(data_str), index_col=0) plot(df)
关键修改点说明
- 移除了原代码中重复导入
matplotlib.pyplot的冗余语句 - 按数据集的
Class列拆分4组独立数据,不再把所有数据合并到同一个分组 - 给每组箱线图设置固定横向偏移,单组箱线图宽度设为0.2,4组在同一点位下总占宽0.8,不会和相邻点位的图形重叠
- 散点绘制位置和所属组的箱线图位置对齐,避免所有散点叠在同一竖线上
- 增加了图例、坐标轴标签配置,同时保留了你原代码中红色中位数线的样式
- 最后将X轴刻度设置在1-10的整数位置,正好对齐每个点位下4个箱线图的中心,和你原有单组图的X轴刻度逻辑一致
如果需要调整箱线图间距,直接修改box_width和offset的数值即可:宽度越小、偏移量差值越大,同组箱线图的间隙就越大。
内容的提问来源于stack exchange,提问作者A.E
相关产品推荐
相关产品推荐

