尝试将浮点型diff_cross值作为频数绘制直方图遇阻求助
我有一组预分箱的数据,想绘制直方图,部分数据格式如下(原始无表头):
| cos_low | cos_up | E_low | E_up | diff_cross |
|-1 |-0.9 |105 |162.9 |21.7861 |
|-1 |-0.9 |162.9 |220.8 |41.0181 |
|-1 |-0.9 |220.8 |278.7 |38.4258 |
|-1 |-0.9 |278.7 |336.6 |23.33 |
|-1 |-0.9 |336.6 |394.5 |7.47169 |
|-1 |-0.9 |394.5 |452.4 |1.41047 |
|-1 |-0.9 |452.4 |510.3 |0.190604 |
|-1 |-0.9 |510.3 |568.2 |0.0381209 |
|-1 |-0.9 |568.2 |626.1 |0 |
|-1 |-0.9 |626.1 |684 |0 |
完整数据包含角度和能量箱边,能量箱范围105到3000,共50个箱。我想把diff_cross作为每个能量箱的频数绘制直方图,但始终无法生成正确图像。
我试过Matplotlib官网针对已分箱数据的代码:
counts, bins = np.histogram(x) plt.stairs(bins, counts)
但用法可能有误。也查过类似问题没找到合适方案,我的尝试代码如下:
import numpy as np import sympy as smp import matplotlib.pyplot as plt import scipy as spy import pandas as pd # 读取各通量数据文件 flux_0 = pd.read_csv("2d_bins_flux_0.txt", sep=" ", header=None) # 命名列 flux_0.columns = ['cos_low', ' ', 'cos_up', ' ', 'E_low', ' ', 'E_up', ' ', 'diff_cross'] # 按角度拆分数据 flux_0_1 = flux_0.loc[lambda df: df['cos_low'] == -1, :] # 角度区间 -1.0 < x < -0.9 flux_0_2 = flux_0.loc[lambda df: df['cos_low'] == -.9, :] # 角度区间 -0.9 < x < -0.8 # 以下是出问题的部分,尝试过多种方法都无效 counts = flux_0_1.diff_cross bins = flux_0_1.E_low plt.hist(bins[:-1], bins, weights=counts)
我想要生成阶梯状的直方图,请帮忙解决问题。
解决方案
问题分析
- 数据读取问题:用
sep=" "会导致列名出现空列,建议用delim_whitespace=True处理任意空格分隔。 - 直方图绘制方法错误:针对已有预分箱和计数的数据,
plt.hist不是最优选择,plt.stairs(Matplotlib 3.4+)或plt.bar更适配。
修正后的代码
import numpy as np import matplotlib.pyplot as plt import pandas as pd # 正确读取数据:处理任意空格分隔,直接指定列名 flux_0 = pd.read_csv("2d_bins_flux_0.txt", delim_whitespace=True, header=None, names=['cos_low', 'cos_up', 'E_low', 'E_up', 'diff_cross']) # 按角度筛选数据 flux_0_1 = flux_0[flux_0['cos_low'] == -1] # 提取完整箱边:需包含最后一个箱的右边界 bins = np.append(flux_0_1['E_low'].values, flux_0_1['E_up'].iloc[-1]) counts = flux_0_1['diff_cross'].values # 绘制阶梯状直方图 plt.stairs(counts, bins, fill=True, edgecolor='black') # 设置图表属性 plt.xlabel('Energy') plt.ylabel('diff_cross') plt.title('Histogram for angle bin -1.0 to -0.9') plt.grid(axis='y', alpha=0.3) plt.show()
低版本Matplotlib替代方案(用bar绘制)
# 计算每个箱的宽度 bin_widths = flux_0_1['E_up'] - flux_0_1['E_low'] # 绘制柱状直方图 plt.bar(flux_0_1['E_low'], counts, width=bin_widths, align='edge', edgecolor='black') plt.xlabel('Energy') plt.ylabel('diff_cross') plt.title('Histogram for angle bin -1.0 to -0.9') plt.grid(axis='y', alpha=0.3) plt.show()
关键说明
- 数据读取:
delim_whitespace=True自动处理任意数量空格分隔,避免空列问题。 - bins处理:
plt.stairs需要长度为counts+1的完整箱边数组,需补充最后一个箱的右边界。 - 样式控制:
fill=True填充阶梯区域,edgecolor设置边框提升可读性。
内容的提问来源于stack exchange,提问作者suhpec

