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"] 绘制条形图,无论我尝试什么,我都会得到:
- 所有带有标签的 2048 能量值变得一团糟
- 前 50 个(例如)能量值在 x 轴的开头混杂在一起
基本上,绘图是在右侧绘制条形图的位置(使用能量值),当我尝试操纵刻度或添加垂直线时,它始终使用 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')
我想从 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"] 绘制条形图,无论我尝试什么,我都会得到:
- 所有带有标签的 2048 能量值变得一团糟
- 前 50 个(例如)能量值在 x 轴的开头混杂在一起
基本上,绘图是在右侧绘制条形图的位置(使用能量值),当我尝试操纵刻度或添加垂直线时,它始终使用 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')