如何用Seaborn绘制带偏移的多分类水平条形图?
解决方案:批量绘制分组小提琴+散点图
1. 先做数据预处理(核心步骤)
原数据集每个单元格是逗号分隔的字符串,必须转换成长格式DataFrame才能让seaborn高效处理,避免重复写拆分代码。
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据集(替换为你的本地文件路径) df = pd.read_csv('data.csv', index_col=0) # 定义需要处理的类别和位置 categories = ['92A11', '92B11', '82B11'] locations = df.index.tolist() # 获取P1-P14所有位置 # 构建长格式数据 processed_rows = [] for loc in locations: for cat in categories: # 拆分字符串为数值,跳过空内容 value_list = [float(x.strip()) for x in df.loc[loc, cat].split(',') if x.strip()] # 每个数值对应一行记录 for val in value_list: processed_rows.append({ '位置': loc, '类别': cat, '数值': val }) # 转换为规整的DataFrame long_df = pd.DataFrame(processed_rows)
2. 批量生成符合要求的图表
用循环自动处理每个位置,生成统一格式的子图,完全匹配目标效果:
# 设置子图布局:14个位置用2行7列,可根据需求调整 cols = 7 rows = (len(locations) + cols - 1) // cols fig, axes = plt.subplots(rows, cols, figsize=(18, 6), sharex=True) axes = axes.flatten() # 转为一维数组方便循环 # 逐个位置绘制图表 for idx, loc in enumerate(locations): ax = axes[idx] # 筛选当前位置的数据 current_data = long_df[long_df['位置'] == loc] # 绘制小提琴图(填充橙色) sns.violinplot( data=current_data, x='数值', y='类别', orient='h', color='orange', inner=None, ax=ax ) # 绘制散点图(黑色无抖动,对齐小提琴图) sns.stripplot( data=current_data, x='数值', y='类别', orient='h', color='black', linewidth=1, jitter=False, ax=ax ) # 设置子图样式 ax.set_title(loc) ax.set_ylabel('') # 去掉重复的y轴标签 ax.set_xlabel('数值') # 隐藏多余的空白子图 for ax in axes[len(locations):]: ax.axis('off') # 统一设置x轴范围 plt.xlim(0, 200) plt.tight_layout() plt.show()
优势说明
- 无需手动逐个编写子图代码,14个位置自动批量生成
- 共享x轴保证所有图表刻度一致,视觉统一
- 散点无抖动,完美对齐小提琴图中线,和目标效果一致
- 长格式数据结构适配seaborn的分组绘图逻辑,后续调整类别/位置只需修改列表参数
内容的提问来源于stack exchange,提问作者A.E
相关产品推荐
相关产品推荐

