如何用Seaborn对DataFrame数组列绘制多组箱线图?
解决Seaborn绘制多数组同图箱线图的问题
核心问题分析
你之前的代码存在两个关键问题:
- 直接调用
Moyennes(均值)列,没有用到Values_array中的原始数值,自然无法生成反映整体分布的箱线图 - 将单一年份值(如
date2018)作为y轴变量,Seaborn会把它识别为连续数值,导致日期格式异常
Seaborn的箱线图要求输入长格式数据(每个数值单独一行,附带分组信息),所以第一步必须把Values_array列的数组展开。
步骤1:展开数组列(单年份处理)
用Pandas的explode函数可以快速把每行的数组拆成单独行,保留对应的mods和年份信息:
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd # 以2018年数据为例,展开Values_array列 expanded_df = df2018.explode('Values_array').rename(columns={'Values_array': 'value'}) # 添加年份标识(可选,用于多年份整合) expanded_df['year'] = 2018
步骤2:绘制同一年份的分组箱线图
展开后直接用Seaborn绘制,按mods分组,所有箱线图会自动整合到同一画布:
sns.boxplot(data=expanded_df, x='mods', y='value', hue='mods', palette='Set2') plt.title('2018年各时段数值分布') plt.xlabel('时段(mods)') plt.ylabel('数值') plt.show()
进阶:多年份数据整合绘制
如果要把6年的数据都整合到同一张图(或分面图),可以先合并所有年份的展开数据:
# 假设你有df2018到df2023共6个年份的DataFrame all_expanded = [] for year in range(2018, 2024): df = locals()[f'df{year}'] # 从变量名读取对应年份的DataFrame temp_df = df.explode('Values_array').rename(columns={'Values_array': 'value'}) temp_df['year'] = year all_expanded.append(temp_df) # 合并所有年份数据 all_expanded = pd.concat(all_expanded, ignore_index=True) # 方式1:按年份分面,每个面展示当年各时段的箱线图 g = sns.FacetGrid(all_expanded, col='year', col_wrap=3, height=4) g.map(sns.boxplot, 'mods', 'value', 'mods', palette='Set2') g.add_legend() g.set_axis_labels('时段(mods)', '数值') plt.show() # 方式2:同一张图按年份区分,x轴为时段,hue为年份 sns.boxplot(data=all_expanded, x='mods', y='value', hue='year', palette='husl') plt.title('各年份时段数值分布对比') plt.xlabel('时段(mods)') plt.ylabel('数值') plt.legend(title='年份') plt.show()
关键说明
explode是处理列表/数组列的高效方法,比循环遍历行快得多,适合你的150条/年的数据规模- 不要把单一年份值作为y轴,而是将其作为分类变量(hue或分面参数),避免格式异常
- Seaborn会自动按分组变量(如
mods)整理数据,生成对应组的箱线图,无需手动循环调用plt.boxplot
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

