如何旋转Matplotlib堆叠面积图实现水平堆叠?
实现水平堆叠的面积图(替代旋转方案)
问题描述
需要将垂直堆叠的面积图改为水平堆叠(从观察者视角看,堆叠方向变为水平),尝试通过Affine2D旋转整个图表后内容丢失,同时希望旋转后反转原x轴对应的y轴数值。
原垂直堆叠面积图代码:
# imports import matplotlib.pyplot as plt from matplotlib.transforms import Affine2D from matplotlib.collections import PathCollection # Create data x=range(1,6) y1=[1,4,6,8,9] y2=[2,2,7,10,12] y3=[2,8,5,10,6] # Basic stacked area chart. ax = plt.gca() ax.stackplot(x,y1, y2, y3, labels=['A','B','C']) ax.legend(loc='upper left') plt.show()
尝试的旋转代码(运行后内容丢失):
# Attempt to re-orient plot ax = plt.gca() ax.stackplot(x,y1, y2, y3, labels=['A','B','C']) ax.legend(loc='upper left') r = Affine2D().rotate_deg(90) for x in ax.images + ax.lines + ax.collections: trans = x.get_transform() x.set_transform(r+trans) if isinstance(x, PathCollection): transoff = x.get_offset_transform() x._transOffset = r+transoff old = ax.axis() ax.axis(old[2:4] + old[0:2]) plt.show()
解决方案:手动构建水平堆叠面积图
直接旋转整个图表会导致坐标轴、图例、绘图元素的变换冲突,更可靠的方式是手动使用fill_betweenx构建水平堆叠区域,核心思路是将原x轴数据作为y轴刻度,原y轴数据转为水平方向的堆叠值。
实现代码
import matplotlib.pyplot as plt import numpy as np # 原始数据 x = np.arange(1,6) y1 = np.array([1,4,6,8,9]) y2 = np.array([2,2,7,10,12]) y3 = np.array([2,8,5,10,6]) # 计算各层堆叠的累计值(水平方向的边界) bottom = np.zeros_like(x) top1 = bottom + y1 top2 = top1 + y2 top3 = top2 + y3 # 创建画布和轴 fig, ax = plt.subplots() # 绘制各层水平堆叠区域 ax.fill_betweenx(x, bottom, top1, label='A', alpha=0.7) ax.fill_betweenx(x, top1, top2, label='B', alpha=0.7) ax.fill_betweenx(x, top2, top3, label='C', alpha=0.7) # 反转y轴(对应原x轴的数值反转) ax.invert_yaxis() # 添加图例和标签 ax.legend(loc='upper right') ax.set_xlabel('堆叠值') ax.set_ylabel('原x轴刻度') plt.show()
代码说明
- 数据处理:计算每个堆叠层的水平边界(从底部0开始,依次累加各系列的数值);
- 绘制堆叠:使用
fill_betweenx函数,以原x轴数据作为y轴的位置,填充相邻边界之间的区域; - 轴调整:通过
ax.invert_yaxis()实现原x轴数值的反转需求; - 样式优化:添加图例、坐标轴标签,设置透明度让堆叠层次更清晰。
这种方法避免了旋转整个图表带来的元素适配问题,绘图逻辑更直观,也能完美满足水平堆叠和轴反转的需求。
内容的提问来源于stack exchange,提问作者user2256085
相关产品推荐
相关产品推荐

