如何使用Seaborn将2017/2020/2022_value多组数据绘制在同一张图中
解决Seaborn PairGrid/Stripplot多组数值点显示问题
你的代码只显示2017_value的点,核心原因是宽格式数据无法让Seaborn自动区分年份组的颜色,且原PairGrid.map()的调用方式无法为不同年份变量指定独立颜色。以下是两种针对性解决方案:
方案1:转换为长格式数据,单图展示多年份点(推荐)
如果你的需求是在同一图中,每个area对应位置显示三个年份的数值点(用颜色区分年份),长格式数据是Seaborn分类绘图的最佳适配格式:
步骤1:数据格式转换
用Pandas的melt函数将宽格式转为长格式,提取年份标签:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 假设原始数据结构 # df = pd.DataFrame({ # 'area': ['华北', '华东', '华南'], # 'growth': [0.7, 1.3, 0.9], # '2017_value': [12, 16, 9], # '2020_value': [14, 19, 10], # '2022_value': [16, 21, 12] # }) # 转换为长格式,拆分年份和数值列 df_long = df.melt( id_vars=['area', 'growth'], value_vars=['2017_value', '2020_value', '2022_value'], var_name='year', value_name='value' ) # 提取年份数字,优化标签显示 df_long['year'] = df_long['year'].str.extract('(\d+)')
步骤2:绘制带颜色区分的Stripplot
直接用stripplot的hue参数指定年份分组,自定义颜色匹配需求:
plt.figure(figsize=(8, 10)) sns.stripplot( data=df_long, x='value', y='area', hue='year', size=10, orient='h', jitter=False, palette={'2017': 'blue', '2020': 'red', '2022': 'black'}, linewidth=1, edgecolor='w' ) # 添加垂直参考线 plt.axvline(x=1, ls='--', linewidth=3, c='black') # 调整样式 plt.xlabel('数值') plt.ylabel('区域') plt.xlim(0, 30) # 根据你的数据范围调整 plt.grid(axis='y') sns.despine(left=True, bottom=True) plt.legend(title='年份') plt.show()
方案2:保留原PairGrid多子图结构
如果需要保留growth+三个年份数值的四列子图布局,需循环为每个子图指定独立颜色,同时修正标题数量不匹配的问题:
g = sns.PairGrid( df, x_vars=['growth','2017_value','2020_value','2022_value'], y_vars=["area"], height=10, aspect=.50 ) # 为每个子图指定对应颜色,逐个绘制 colors = ['gray', 'blue', 'red', 'black'] for ax, x_var, color in zip(g.axes.flat, g.x_vars, colors): sns.stripplot( data=df, x=x_var, y='area', ax=ax, size=10, orient="h", jitter=False, color=color, linewidth=1, edgecolor="w" ) # 设置各子图x轴范围 g.axes[0,0].set(xlim=(-1, 12.5), xlabel="", ylabel="") g.axes[0,1].set(xlim=(0, 30), xlabel="", ylabel="") g.axes[0,2].set(xlim=(0, 30), xlabel="", ylabel="") g.axes[0,3].set(xlim=(0, 30), xlabel="", ylabel="") # 添加垂直参考线 for ax in g.axes.ravel(): ax.axvline(x=1, ls='--', linewidth=3, c='black') # 设置匹配子图数量的标题 titles = ["增长率", "2017年数值", "2020年数值", "2022年数值"] for ax, title in zip(g.axes.flat, titles): ax.set(title=title) ax.xaxis.grid(False) ax.yaxis.grid(True) sns.despine(left=True, bottom=True) plt.show()
内容的提问来源于stack exchange,提问作者Shivam Agrawal
相关产品推荐
相关产品推荐

