如何用Pandas+Matplotlib实现两组boxplot并排展示(禁用Seaborn)
解决两组箱线图重叠问题(无Seaborn)
直接在同一轴上调用两次boxplot会导致重叠,因为两组数据的LABEL对应的x轴位置完全相同。通过手动指定每组箱线图的位置,就能实现并排展示,具体方案如下:
方案1:合并数据集后绘制
先给两个数据集添加来源标识,合并后按分组提取数据,再指定位置绘制:
import matplotlib.pyplot as plt import pandas as pd # 读取两个文件的数据 df1 = pd.read_csv("file1", sep=r'\s+', header=0) df2 = pd.read_csv("file2", sep=r'\s+', header=0) # 添加来源区分列 df1['Source'] = 'File1' df2['Source'] = 'File2' # 合并数据集 combined_df = pd.concat([df1, df2], ignore_index=True) # 获取所有唯一的LABEL标签 labels = combined_df['LABEL'].unique() n_labels = len(labels) # 设置箱线图宽度和位置偏移,保证每组两个箱子并排 box_width = 0.35 file1_positions = [i - box_width/2 for i in range(n_labels)] file2_positions = [i + box_width/2 for i in range(n_labels)] # 提取每个LABEL对应的数据 data_file1 = [combined_df[(combined_df['LABEL'] == lbl) & (combined_df['Source'] == 'File1')]['VAL'].values for lbl in labels] data_file2 = [combined_df[(combined_df['LABEL'] == lbl) & (combined_df['Source'] == 'File2')]['VAL'].values for lbl in labels] # 创建画布并绘制箱线图 fig, ax = plt.subplots() # 绘制File1的箱线图,设置填充色区分 box1 = ax.boxplot(data_file1, positions=file1_positions, widths=box_width, patch_artist=True, label='File1') for patch in box1['boxes']: patch.set_facecolor('#1f77b4') # 绘制File2的箱线图 box2 = ax.boxplot(data_file2, positions=file2_positions, widths=box_width, patch_artist=True, label='File2') for patch in box2['boxes']: patch.set_facecolor('#ff7f0e') # 设置坐标轴和图例 ax.set_xticks(range(n_labels)) ax.set_xticklabels(labels) ax.set_xlabel('LABEL') ax.set_ylabel('VAL') ax.legend() plt.tight_layout() plt.show()
方案2:不合并数据集直接绘制
如果不需要合并数据,也可以直接基于两个原始数据集处理:
import matplotlib.pyplot as plt import pandas as pd df1 = pd.read_csv("file1", sep=r'\s+', header=0) df2 = pd.read_csv("file2", sep=r'\s+', header=0) # 假设两个文件的LABEL完全一致,取其中一个的唯一标签 labels = df1['LABEL'].unique() n_labels = len(labels) box_width = 0.35 fig, ax = plt.subplots() # 绘制File1的箱线图 data1 = [df1[df1['LABEL'] == lbl]['VAL'].values for lbl in labels] ax.boxplot(data1, positions=[i - box_width/2 for i in range(n_labels)], widths=box_width, patch_artist=True, label='File1') # 绘制File2的箱线图 data2 = [df2[df2['LABEL'] == lbl]['VAL'].values for lbl in labels] ax.boxplot(data2, positions=[i + box_width/2 for i in range(n_labels)], widths=box_width, patch_artist=True, label='File2') # 美化样式和坐标轴 for patch in ax.artists[::2]: patch.set_facecolor('#1f77b4') for patch in ax.artists[1::2]: patch.set_facecolor('#ff7f0e') ax.set_xticks(range(n_labels)) ax.set_xticklabels(labels) ax.set_xlabel('LABEL') ax.set_ylabel('VAL') ax.legend() plt.tight_layout() plt.show()
核心原理
pandas默认的boxplot(by='LABEL')会把每个LABEL映射到x轴的整数位置(0、1、2...),两次调用会使用相同位置导致重叠。通过给两组箱线图设置偏移的位置坐标(比如每个LABEL对应i-0.175和i+0.175),就能让它们在同一LABEL下并排展示。
内容的提问来源于stack exchange,提问作者kelly
相关产品推荐
相关产品推荐

