如何使用Plotly(Python)绘制网格布局的多个堆叠面积图?
如何在subplots网格中绘制堆叠面积图
我完全懂你遇到的这个卡点——用subplots轻松搞定网格布局的柱状图,但换到堆叠面积图就摸不着头脑了,你提到的“堆叠面积图层是Scatter图”其实是个小误解,咱们一步步来解决这个问题:
为什么会出现这个差异?
柱状图的实现逻辑很直接:在每个子轴上调用bar函数就能生成单组柱状图,堆叠柱状图也只是在同一子轴上多次调用bar并设置bottom参数。但堆叠面积图的底层不是Scatter图,而是基于填充的折线图层叠加——它需要在单个子轴内完成多组数据的堆叠计算和填充,这和柱状图的子轴调用逻辑略有不同,但完全可以适配subplots网格。
解决方案:两种方式在subplots中绘制堆叠面积图
下面用Matplotlib为例,给你两种可行的实现方法:
方法1:直接使用stackplot函数(推荐)
Matplotlib内置的stackplot能直接生成堆叠面积图,你只需要在每个子轴上调用这个函数即可:
import matplotlib.pyplot as plt import numpy as np # 生成示例数据 x = np.arange(0, 10, 1) # 三组待堆叠的数据 y_data = [ np.random.randint(1, 5, size=10), np.random.randint(1, 5, size=10), np.random.randint(1, 5, size=10) ] labels = ['类别A', '类别B', '类别C'] # 创建2x2的子图网格 fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8)) # 遍历每个子轴绘制堆叠面积图 for ax in axes.flat: ax.stackplot(x, *y_data, labels=labels) ax.set_title('堆叠面积图') ax.legend(loc='upper left') ax.set_xlabel('X轴') ax.set_ylabel('累计值') # 自动调整子图间距 plt.tight_layout() plt.show()
方法2:手动用fill_between实现堆叠
如果你想更灵活控制每一层的样式,可以手动计算累计值,用fill_between逐层填充:
import matplotlib.pyplot as plt import numpy as np x = np.arange(0, 10, 1) y1 = np.random.randint(1, 5, size=10) y2 = np.random.randint(1, 5, size=10) y3 = np.random.randint(1, 5, size=10) # 计算各层的上下边界 y_bottom1 = np.zeros_like(x) y_top1 = y1 y_bottom2 = y_top1 y_top2 = y1 + y2 y_bottom3 = y_top2 y_top3 = y1 + y2 + y3 fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8)) for ax in axes.flat: ax.fill_between(x, y_bottom1, y_top1, label='类别A', alpha=0.7) ax.fill_between(x, y_bottom2, y_top2, label='类别B', alpha=0.7) ax.fill_between(x, y_bottom3, y_top3, label='类别C', alpha=0.7) ax.set_title('手动堆叠面积图') ax.legend() plt.tight_layout() plt.show()
关键注意点
- 不管哪种方法,都是针对单个子轴完成堆叠操作,和柱状图在子轴上绘制的逻辑本质是一致的,只是堆叠面积图需要在子轴内处理多组数据的叠加关系。
- 如果你用的是其他可视化库(比如Seaborn),思路也是类似的:先创建subplots网格,再在每个子轴上调用对应库的堆叠面积图函数。
内容的提问来源于stack exchange,提问作者Vivek Sharma




