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

如何绘制DataFrame中actual与calculated列的并列对比直方图?

问题描述

现有如下Pandas DataFrame:

import pandas as pd

df = pd.DataFrame(
    {'id': [1, 2, 3, 4, 5],
     'actual': [412.6,741.24,1098.30,20025.87,1506.0],
     'calculated': [315.24,517.61,998.38,7438.03,1503.32]}
)

输出的DataFrame内容:

id    actual    calculated
0   1    412.60      315.24
1   2    741.24      517.61
2   3   1098.30      998.38
3   4  20025.87     7438.03
4   5   1506.00     1503.32

想要绘制actual与calculated列的并列条形图(对比每个id对应的具体数值),但以下代码未达到预期效果:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()

a_heights, a_bins = np.histogram(df['actual'])
b_heights, b_bins = np.histogram(df['calculated'], bins=a_bins)

width = (a_bins[1] - a_bins[0])/3

ax.bar(a_bins[:-1], a_heights, width=width, facecolor='cornflowerblue')
ax.bar(b_bins[:-1]+width, b_heights, width=width, facecolor='seagreen')

需求是Y轴显示对应数值(如412.60/315.24、741.24/517.61等),以下是正确实现方法:

正确实现方法

你需要的是并列条形图(而非统计频率的直方图),原代码错误使用了np.histogram(该函数用于统计数据频率分布),下面提供两种可行方案:

方案1:Pandas内置绘图(简洁版)

利用Pandas的plot.bar()可以直接生成并列条形图,代码更简洁:

import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame(
    {'id': [1, 2, 3, 4, 5],
     'actual': [412.6,741.24,1098.30,20025.87,1506.0],
     'calculated': [315.24,517.61,998.38,7438.03,1503.32]}
)

# 将id设为索引,以id作为X轴标签
df.set_index('id')[['actual', 'calculated']].plot(kind='bar', figsize=(8,6))

plt.ylabel('数值')
plt.title('Actual vs Calculated 数值对比')
plt.legend(title='类别')
plt.show()

方案2:Matplotlib手动绘制(自定义版)

如果需要更精细的样式控制,可以手动计算条形位置:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame(
    {'id': [1, 2, 3, 4, 5],
     'actual': [412.6,741.24,1098.30,20025.87,1506.0],
     'calculated': [315.24,517.61,998.38,7438.03,1503.32]}
)

x = np.arange(len(df['id']))  # X轴位置索引
width = 0.35  # 单个条形的宽度

fig, ax = plt.subplots(figsize=(8,6))
# 绘制actual列的条形
rects1 = ax.bar(x - width/2, df['actual'], width, label='Actual', color='cornflowerblue')
# 绘制calculated列的条形
rects2 = ax.bar(x + width/2, df['calculated'], width, label='Calculated', color='seagreen')

# 设置X轴标签为id值
ax.set_xticks(x)
ax.set_xticklabels(df['id'])
ax.set_ylabel('数值')
ax.set_title('Actual vs Calculated 数值对比')
ax.legend(title='类别')

# 可选:在条形上方显示具体数值
ax.bar_label(rects1, padding=3)
ax.bar_label(rects2, padding=3)

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:05:55