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

如何基于Pandas DataFrame绘制以Points_groups为X轴的对比直方图

问题描述

现有如下结构的Pandas DataFrame:

Points_groupsQty ContractsQty Gones
1350+108275
2300-3507251718
3250-3008853170
4200-250212110890
5150-20031207925
6100-1506531318
750-100101247
80-5045137

需要绘制以Points_groups为X轴,同时展示Qty Contracts和Qty Gones两组数据的对比柱状图(分组对比样式),但尝试的代码均未得到预期效果:

df.plot(kind ='hist')
plt.xlabel('Points_groups')
plt.ylabel("Number Of Students");
sns.distplot(df['Кол-во Ушедшие'])
sns.distplot(df['Кол-во Контракт'])
plt.show()
df.hist(column='Баллы_groups', by= ['Кол-во Контракт', 'Кол-во Ушедшие'], bins=2, grid=False, rwidth=0.9,color='purple', sharex=True);

正确解决方案

你之前使用的hist(直方图)是用来展示数值变量的分布频率的,而当前场景的X轴是分类变量(Points_groups是区间分组标签),需要的是分组柱状图来对比两类数据的数值大小,以下是几种可行的实现方法:

方法1:Pandas内置分组柱状图

直接用Pandas的plot.bar()快速生成,无需额外转换数据:

import matplotlib.pyplot as plt

# 指定X轴和要展示的Y列,绘制分组柱状图
ax = df.plot(x='Points_groups', y=['Qty Contracts', 'Qty Gones'], 
             kind='bar', figsize=(10,6), width=0.7)

# 自定义标签与样式
ax.set_xlabel('分数区间')
ax.set_ylabel('人数')
ax.set_title('不同分数区间的合同生与流失生数量对比')
plt.xticks(rotation=45)  # 旋转X轴标签避免重叠
plt.legend(title='类别')
plt.tight_layout()  # 自动调整布局适配标签
plt.show()

方法2:Seaborn分组柱状图

先将DataFrame转换为长格式,再用Seaborn实现更美观的可视化:

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

# 转换为长格式(适合Seaborn的分组绘图逻辑)
df_long = pd.melt(df, id_vars='Points_groups', 
                  value_vars=['Qty Contracts', 'Qty Gones'], 
                  var_name='类别', value_name='人数')

# 绘制分组柱状图
plt.figure(figsize=(10,6))
sns.barplot(data=df_long, x='Points_groups', y='人数', hue='类别', width=0.7)

plt.xlabel('分数区间')
plt.ylabel('人数')
plt.title('不同分数区间的合同生与流失生数量对比')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

方法3:Matplotlib手动定制

如果需要高度自定义样式,可以直接用Matplotlib手动绘制两组柱状图:

import matplotlib.pyplot as plt
import numpy as np

# 设置X轴位置参数
x = np.arange(len(df['Points_groups']))
bar_width = 0.35  # 单组柱状图的宽度

fig, ax = plt.subplots(figsize=(10,6))
# 分别绘制两组柱状图
rects1 = ax.bar(x - bar_width/2, df['Qty Contracts'], bar_width, label='Qty Contracts')
rects2 = ax.bar(x + bar_width/2, df['Qty Gones'], bar_width, label='Qty Gones')

# 添加标签、标题与刻度
ax.set_xlabel('分数区间')
ax.set_ylabel('人数')
ax.set_title('不同分数区间的合同生与流失生数量对比')
ax.set_xticks(x)
ax.set_xticklabels(df['Points_groups'], rotation=45)
ax.legend()

# 可选:为柱状图添加数值标签
def add_label(rects):
    for rect in rects:
        height = rect.get_height()
        ax.annotate(f'{height}',
                    xy=(rect.get_x() + rect.get_width()/2, height),
                    xytext=(0, 3),  # 向上偏移3个像素
                    textcoords='offset points',
                    ha='center', va='bottom')

add_label(rects1)
add_label(rects2)

fig.tight_layout()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:30:58