如何基于Pandas DataFrame绘制以Points_groups为X轴的对比直方图
问题描述
现有如下结构的Pandas DataFrame:
| Points_groups | Qty Contracts | Qty Gones | |
|---|---|---|---|
| 1 | 350+ | 108 | 275 |
| 2 | 300-350 | 725 | 1718 |
| 3 | 250-300 | 885 | 3170 |
| 4 | 200-250 | 2121 | 10890 |
| 5 | 150-200 | 3120 | 7925 |
| 6 | 100-150 | 653 | 1318 |
| 7 | 50-100 | 101 | 247 |
| 8 | 0-50 | 45 | 137 |
需要绘制以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
相关产品推荐
相关产品推荐

