如何为2D直方图中每个离散时间值设置独立Y轴分箱并绘图
为每个离散时间t独立设置Y轴分箱宽度的直方图实现方法
核心思路
seaborn.histplot的全局分箱参数无法针对单个离散x值(即每个t)单独配置Y轴分箱宽度,因此可以通过两种方式实现需求:同一坐标轴手动绘制分组直方图,或子图形式独立配置每个t的分箱。
方法一:同一坐标轴手动绘制(Matplotlib)
直接基于Matplotlib为每个t分组计算自定义分箱,再将各组直方图对齐到x轴的对应离散位置,保持x轴宽度统一。
示例代码
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 构造示例数据(替换为你的真实数据) np.random.seed(42) data = pd.DataFrame({ 't': np.repeat([0, 1, 2], 200), 'value': np.concatenate([ np.random.normal(5, 0.5, 200), # t=0:小范围数据,适合0.3分箱 np.random.normal(50, 8, 200), # t=1:大范围数据,适合10分箱 np.random.normal(100, 3, 200) # t=2:中等范围数据,适合1分箱 ]) }) # 定义每个t对应的Y轴分箱宽度 bin_widths = {0: 0.3, 1: 10, 2: 1} x_width = 0.8 # x轴每个t的分箱宽度统一 plt.figure(figsize=(10, 6)) for t in sorted(data['t'].unique()): # 提取当前t的value数据 subset = data[data['t'] == t]['value'] # 根据自定义分箱宽度生成分箱边界 min_val = subset.min() max_val = subset.max() bins = np.arange(min_val - bin_widths[t]/2, max_val + bin_widths[t]/2, bin_widths[t]) # 计算直方图计数与分箱区间 counts, edges = np.histogram(subset, bins=bins) # 计算分箱中点,用于条形图的Y轴位置 y_centers = (edges[:-1] + edges[1:]) / 2 # 绘制横向条形图,对齐到x轴的t位置 plt.barh(y_centers, counts, height=bin_widths[t], left=t - x_width/2, right=t + x_width/2, alpha=0.7, label=f't={t}') plt.xlabel('计数') plt.ylabel('value') plt.legend(title='时间t') plt.title('每个t独立设置分箱宽度的直方图') plt.tight_layout() plt.show()
方法二:子图形式独立配置(Seaborn FacetGrid)
如果可以接受子图布局,用Seaborn的FacetGrid为每个t生成独立子图,在每个子图中单独设置分箱宽度,实现更简洁。
示例代码
import seaborn as sns # 基于FacetGrid创建子图,关闭Y轴共享以支持独立分箱 g = sns.FacetGrid(data, col='t', col_wrap=3, sharey=False) # 为每个子图配置对应t的分箱宽度 for ax, t in zip(g.axes, sorted(data['t'].unique())): subset = data[data['t'] == t]['value'] bins = np.arange(subset.min() - bin_widths[t]/2, subset.max() + bin_widths[t]/2, bin_widths[t]) sns.histplot(subset, bins=bins, ax=ax) ax.set_title(f't={t}\n分箱宽度={bin_widths[t]}') ax.set_xlabel('value') ax.set_ylabel('计数') plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Schach21
相关产品推荐
相关产品推荐

