You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Pandas DataFrame使用Seaborn绘制指定多变量组合图表?

问题描述

需求说明

我需要基于给定的Pandas DataFrame,用Python的Seaborn/Matplotlib绘制指定的多变量组合图表。目标图表已在Excel中制作完成,具体效果为:X轴是SEGM的9到0分类值,左侧Y轴对应YES的数量(柱状图),每个柱子上方标注YES数值和YES%;右侧Y轴对应TOTCUM%(折线图带数据点),每个点标注累计百分比。但我自己写的代码无法实现这个效果,求解决方案。

可重现的DataFrame代码

import pandas as pd

dx = {'SEGM':[9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
'YES':[4812, 2697, 2677, 1811, 1570, 1010, 418, 210, 115, 166],
'NO':[590, 1368, 2611, 2968, 3942, 3596, 2141, 1668, 1528, 11055],
'TOT':[5402, 4065, 5288, 4779, 5512, 4606, 2559, 1878, 1643, 11221],
'YES%':[89.08, 66.35, 50.62, 37.89, 28.48, 21.93, 16.33, 11.18, 7.0, 1.48],
'TOTCUM%':[11.51, 20.16, 31.43, 41.6, 53.34, 63.15, 68.6, 72.6, 76.1, 100.0]}
dx = pd.DataFrame(dx)

尝试的代码(未成功)

import seaborn as sns
import matplotlib.pyplot as plt

g=sns.barplot(dx.SEGM, dx['YES'], alpha=0.8)
sns.set_style("whitegrid", {'axes.grid' : False})
plt.title(f'{cat_col} with {vol_inperc}%', fontsize = 16,color='blue')
plt.ylabel('Volume', fontsize=12)
plt.xlabel(f'{cat_col}', fontsize=12)
plt.xticks(rotation=90)
for p in g.patches:
    height = p.get_height()
    g.text(p.get_x()+p.get_width()/2.,
        height + 3,
        '{}
{:1.2f}%'.format(round(height),height/len(df)*100),
        ha="center", fontsize=10, color='blue')

gt = g.twinx()

解决方案代码

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 初始化数据
dx = {'SEGM':[9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
'YES':[4812, 2697, 2677, 1811, 1570, 1010, 418, 210, 115, 166],
'NO':[590, 1368, 2611, 2968, 3942, 3596, 2141, 1668, 1528, 11055],
'TOT':[5402, 4065, 5288, 4779, 5512, 4606, 2559, 1878, 1643, 11221],
'YES%':[89.08, 66.35, 50.62, 37.89, 28.48, 21.93, 16.33, 11.18, 7.0, 1.48],
'TOTCUM%':[11.51, 20.16, 31.43, 41.6, 53.34, 63.15, 68.6, 72.6, 76.1, 100.0]}
dx = pd.DataFrame(dx)

# 设置无网格的绘图风格
sns.set_style("white", {'axes.grid': False})
fig, ax1 = plt.subplots(figsize=(10,6))

# 绘制左侧柱状图:YES数量
bar_plot = sns.barplot(x='SEGM', y='YES', data=dx, ax=ax1, color='#1f77b4', alpha=0.8)
ax1.set_xlabel('SEGM', fontsize=12)
ax1.set_ylabel('YES Volume', fontsize=12, color='#1f77b4')
ax1.tick_params(axis='y', labelcolor='#1f77b4')

# 添加柱状图标注:YES数值 + YES%
for idx, p in enumerate(bar_plot.patches):
    height = p.get_height()
    yes_pct = dx.iloc[idx]['YES%']
    bar_plot.text(p.get_x() + p.get_width()/2.,
                  height + 50,
                  f'{int(height)}\n{yes_pct:.2f}%',
                  ha='center', fontsize=10, color='#1f77b4')

# 创建右侧Y轴,绘制累计百分比折线图
ax2 = ax1.twinx()
line_plot = sns.lineplot(x='SEGM', y='TOTCUM%', data=dx, ax=ax2, marker='o', color='#ff7f0e', linewidth=2)
ax2.set_ylabel('Cumulative Total %', fontsize=12, color='#ff7f0e')
ax2.tick_params(axis='y', labelcolor='#ff7f0e')
ax2.set_ylim(0, 105)  # 确保100%的点完整显示

# 添加折线图数据标注
for x, y in zip(dx['SEGM'], dx['TOTCUM%']):
    ax2.text(x, y + 1, f'{y:.2f}%', ha='center', fontsize=10, color='#ff7f0e')

# 设置标题
plt.title('SEGM with YES Volume & Cumulative Total %', fontsize=16, color='blue')

# 调整布局避免标签截断
plt.tight_layout()
plt.show()

关键修正点

  1. 补全双轴逻辑:给右侧轴添加了折线图及数据标注
  2. 修复原代码中未定义的变量(cat_col、vol_inperc、df)
  3. 调整标注位置,避免数值重叠
  4. 匹配预期图表的颜色风格,优化视觉效果
  5. 设置合理Y轴范围,确保所有数据点完整展示

内容的提问来源于stack exchange,提问作者Nabi Shaikh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:37:02