Pandas 条形图 x 轴卡在错误的列上

Pandas bar plot x axis stuck on wrong column

我想从 pandas 数据框绘制条形图,并有合理数量的 xticks。

我的数据框(data)是这样的:

0  Channel  Counts  Energy [keV]
0        1       0         -0.02
0        2       0          0.01
0        3       0          0.04 
...
2     2044       2         58.81
1     2045       1         58.83
[2048 rows x 4 columns]

我正在用 x = data["Energy [keV]"] 和 height = data["Counts"] 绘制条形图,无论我尝试什么,我都会得到:

基本上,绘图是在右侧绘制条形图的位置(使用能量值),当我尝试操纵刻度或添加垂直线时,它始终使用 0 到 2048 x 轴。

我得到的是:plot with jumbled values (too many ticks)

代码:

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

tmp = {'Channel': np.arange(1, 2049, 1),'Energy [keV]': np.arange(1, 2049, 1),
       'Counts': np.random.rand(2048)*1000}
data = pd.DataFrame(tmp)
data['Energy [keV]'] = -0.048 + 0.029*data['Channel']

fig4 = plt.figure(figsize=(16,8))
ax4 = fig4.add_subplot(1, 1, 1)

data.plot.bar(x = "Energy [keV]", y = "Counts", width=1, ax=ax4, align='center')
ax4.vlines(x=25.0, ymin = ylim_min, ymax = ylim_max, color = 'darkred')

我尝试了几种解决方案,包括将列转换为 numpy 数组、更改数据帧索引、xaxis.set_ticks、xaxis.set_major_formatter...但总是出错。

我想要漂亮的圆形刻度,例如 5.0、10.0、15.0,当我在 x=25.0 处设置 vline 时,它​​实际上的值为 25.0。在代码中,我创建了一个随机数的计数,这样代码片段将更容易重新创建。

你试过了吗ax4.bar(data["Energy [keV]"], data["Counts"], width=1, align='center')

正如您在 pandas documentation 中看到的那样:

A bar plot is a plot that presents categorical data with rectangular bars with lengths proportional to the values that they represent

它试图显示所有的“类别”。问题是,它将每个观察结果视为单一类别 - 因此,如果观察结果没有均匀分布在 x 轴上(在您的示例中,它们不是),则 x 轴将被扭曲。为了说明这一点,如果我们修改您的数据:

data['Energy [keV]'] = data['Energy [keV]'] + (data['Energy [keV]'] > 50)*2

并使用 bar 绘制它,你不会看到任何可疑的东西:

虽然实际数据是这样的:

您当然可以尝试通过 以某种方式修复它,但这是预期的行为 - 也许考虑一些不同的图表类型,例如:

data.plot.line(x = "Energy [keV]", y = "Counts",ax=ax4, linewidth =0.1)
ax4.fill_between(x = data["Energy [keV]"], y1 = data["Counts"], y2=0)
ax4.set_xlim(data["Energy [keV]"].min(), data["Energy [keV]"].max())
ax4.set_ylim(0, data["Counts"].max()*1.1)
ax4.axvline(x=25.0, color = 'darkred')

或:

markerline, stemlines, baseline = ax4.stem(data["Energy [keV]"], data["Counts"], markerfmt=' ')
plt.setp(stemlines, 'linewidth', 0.4)
ax4.set_xlim(data["Energy [keV]"].min(), data["Energy [keV]"].max())
ax4.set_ylim(0, data["Counts"].max()*1.1)
ax4.axvline(x=25.0, color = 'darkred')