如何在Matplotlib中绘制discrete bin plot(离散分箱图)
Matplotlib 实现离散分箱图(discrete bin plot)方法
你描述的这类discrete bin plot核心渲染逻辑是:不对数据点做直线连接,以相邻数据点的中点为分界,每个数据点对应的最近邻区间内保持数值恒定,PDL+PGPLOT的bin()函数就是对一维索引序列的默认实现。
Matplotlib 原生精确复刻实现
PGPLOT的bin()默认针对输入的一维值序列,以序列索引为x坐标,每个水平分段的左右边界取相邻两个x坐标的中点,首尾两段向外延伸半个索引步长,段内y值和对应点的取值完全一致。可以通过自定义函数1:1复刻效果,核心用Matplotlib的step()方法实现:
import numpy as np import matplotlib.pyplot as plt def discrete_bin_plot(y, ax=None, show_points=True, point_color='red', **plot_kwargs): """ 复刻PDL::PGPLOT bin()函数效果 参数: y: 一维数值序列 ax: 可选,指定绘图的matplotlib坐标轴对象 show_points: 是否叠加绘制原始数据点 point_color: 原始数据点的颜色 **plot_kwargs: 传给step绘图的其他参数(线宽、颜色等) """ if ax is None: ax = plt.gca() x = np.arange(len(y)) # 计算分箱边界:相邻点中点 + 首尾外扩半格 bin_edges = np.r_[x[0]-0.5, (x[:-1] + x[1:])/2, x[-1]+0.5] # step的post模式保证区间内值恒定,匹配bin的渲染逻辑 ax.step(bin_edges, np.r_[y[0], y, y[-1]], where='post', **plot_kwargs) if show_points: ax.scatter(x, y, color=point_color, zorder=10, s=20) return ax # 用你给出的PDL示例同源数据测试 y_data = np.array([-19, -3, 4, 7, -8, -2, 9, 15, 4, 7, 1, -14, -4, -4, 11, 6, -15, -13, 2, 1]) plt.figure(figsize=(9, 4)) discrete_bin_plot(y_data, linewidth=1.5) plt.grid(alpha=0.3, linestyle='--') plt.tight_layout() plt.show()
运行上述代码生成的效果和你提供的PGPLOT示例完全一致。如果你的x坐标不是默认的序列索引,而是任意不等间隔的离散值,只需要把x = np.arange(len(y))替换为你自己的排序后的x序列,分箱边界的计算逻辑完全通用。
Matplotlib 内置替代方案
不需要自定义函数的话,也可以直接用Matplotlib内置的阶梯类绘图函数实现:
plt.stairs():这是Matplotlib专门面向分箱阶梯场景设计的接口,比step()更贴合分箱语义,只需要提前算好对应分箱边界,直接传入值和边界即可绘制:x = np.arange(len(y_data)) edges = np.r_[x[0]-0.5, (x[:-1]+x[1:])/2, x[-1]+0.5] plt.stairs(y_data, edges, linewidth=1.5) plt.scatter(x, y_data, c='red', s=20, zorder=10)plt.step()快速绘制:不需要计算边界的话,设置where='mid'参数可以近似实现效果,只是首尾段不会向外延伸半格,适合对边界精度要求不高的快速绘图场景。
其他Python绘图包的相关实现
- Plotly:交互式绘图场景下,可以用
plotly.graph_objects.Scatter,设置line.shape='hv'即可实现区间恒定值的阶梯效果,叠加Scatter散点层就能完整复刻样式。 - Bokeh:面向Web可视化场景,自带
step图元,设置mode='after'即可匹配最近邻域恒定值的渲染逻辑。 - Seaborn:没有专门针对原始序列的离散分箱图接口,但是统计分布场景下可以用
sns.histplot(element='step')实现类似的分箱恒定值效果,且完全兼容Matplotlib的自定义绘图逻辑,可以直接调用前面写的discrete_bin_plot函数在Seaborn风格的画布上绘图。
内容的提问来源于stack exchange,提问作者Enredanrestos
相关产品推荐
相关产品推荐

