You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用numpy与pyqtgraph BarGraphItem创建堆叠直方图:不同长度数组可行吗?

用pyqtgraph的BarGraphItem实现基于不同长度数组的堆叠直方图

当然可以!numpy + pyqtgraph完全能轻松搞定这个需求——不同长度的数组只需要先做一点点预处理对齐,就能顺利生成堆叠直方图了。我给你一步步拆解实现思路,再附上完整代码示例:

核心思路

堆叠直方图的关键是让每一组柱状图的底部“踩”在前面所有组的顶部。对于长度不一的数组,我们首先要把它们对齐到相同长度(短数组补0或者你需要的填充值),然后计算每一组的起始y坐标(也就是前面所有组的累加和),最后用BarGraphItem依次绘制每一层。

步骤拆解

1. 数据预处理:对齐不同长度的数组

假设你有几个长度不同的numpy数组,我们先找到其中最长的数组长度,然后用numpy.pad()把短数组补到这个长度(补0是最常见的选择,如果你有其他需求也可以换填充值)。

比如:

import numpy as np

# 模拟不同长度的输入数组
arr1 = np.array([3, 5, 2, 7])
arr2 = np.array([1, 4])
arr3 = np.array([6, 2, 5])

# 找到最长数组的长度
max_len = max(len(arr1), len(arr2), len(arr3))

# 把所有数组补到相同长度
padded_arr1 = np.pad(arr1, (0, max_len - len(arr1)), mode='constant')
padded_arr2 = np.pad(arr2, (0, max_len - len(arr2)), mode='constant')
padded_arr3 = np.pad(arr3, (0, max_len - len(arr3)), mode='constant')

2. 计算堆叠层的起始位置

每一层柱状图的起始y值是前面所有层的数值之和,我们可以用numpy.cumsum()来快速计算:

# 先把数组整理成一个二维数组(每行是一组数据)
stacked_data = np.vstack([padded_arr1, padded_arr2, padded_arr3])

# 计算每一层的起始y坐标:第一个层从0开始,后面的层是前面所有层的累加和
base_ys = np.cumsum(stacked_data, axis=0) - stacked_data

这里base_ys的每一行就是对应组柱状图的底部y值,stacked_data的每一行是对应组的高度。

3. 用BarGraphItem绘制堆叠直方图

接下来创建pyqtgraph的图形界面,然后依次添加每一层的BarGraphItem,记得给不同层设置不同颜色区分:

import pyqtgraph as pg
from PyQt5.QtWidgets import QApplication
import sys

app = QApplication(sys.argv)

# 创建绘图窗口
win = pg.GraphicsLayoutWidget(show=True, title="堆叠直方图(不同长度数组)")
plot = win.addPlot(title="Stacked Bar Graph")

# 设置x轴的位置(每个bar的中心位置)
x = np.arange(max_len)
bar_width = 0.6  # 柱状图宽度

# 定义不同层的颜色
colors = ['#1f77b4', '#ff7f0e', '#2ca02c']

# 依次绘制每一层
for i in range(stacked_data.shape[0]):
    bar = pg.BarGraphItem(
        x=x,
        height=stacked_data[i],
        y=base_ys[i],
        width=bar_width,
        brush=pg.mkBrush(colors[i])
    )
    plot.addItem(bar)

# 设置x轴标签(可选,根据你的实际需求设置)
plot.setAxisItems({'bottom': pg.AxisItem(orientation='bottom', ticks=[(i, f'Cat {i+1}') for i in x])})

# 显示图例
legend = plot.addLegend()
for i, color in enumerate(colors):
    legend.addItem(pg.BarGraphItem(brush=pg.mkBrush(color)), f'Group {i+1}')

sys.exit(app.exec_())

额外注意事项

  • 如果你的短数组末尾没有数据代表“无值”,补0是合理的;如果是缺失值,你也可以考虑用np.nan,不过pyqtgraph会忽略nan值(对应的位置不会绘制柱状图)。
  • 如果你不想让x轴的数量对应最长数组的长度,而是想只保留有数据的类别,可以先整理出所有存在数据的x位置,再做对齐处理——不过这种情况稍微复杂一点,核心还是先把数据对齐到统一的x轴维度。

内容的提问来源于stack exchange,提问作者Yuliya Goroshkova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 18:12:36