matplotlib 如何旋转堆叠面积图

8xiog9wr  于 2023-03-30  发布在  其他
关注(0)|答案(1)|浏览(137)

我想重新调整堆叠区域图的方向,使堆叠区域水平堆叠而不是垂直堆叠(从查看者的Angular 来看)。下面是典型的堆叠区域图:

# 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()

接下来,我想把整个图旋转90度,我试图用这里找到的公认答案来做。但是,运行下面的代码,图的内容似乎丢失了?有没有更好的方法来绘制“旋转堆叠区域”图?
下面是我尝试使用的代码:

# 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()

如果可能的话,我还想在旋转后应用plt.gca().invert_yaxis(),以反转y轴(以前的x轴)上绘制的值。

jdgnovmf

jdgnovmf1#

下面的代码遍历堆叠的多边形并交换它们顶点的x和y值。轴限制也被切换。
或者,您可以通过fill_betweenx(...)更直接地创建相同的图。将数据转换为numpy数组后,可以直接对y值求和。

import matplotlib.pyplot as plt
import numpy as np

# Create data
x = range(1, 6)
y1 = [1, 4, 6, 8, 9]
y2 = [2, 2, 7, 10, 12]
y3 = [2, 8, 5, 10, 6]

fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(15, 5))

ax1.set_title('Basic stacked area chart')
ax1.stackplot(x, y1, y2, y3, labels=['A', 'B', 'C'])
ax1.legend(loc='upper left')

ax2.set_title('Rotated stacked area chart')
polys = ax2.stackplot(x, y1, y2, y3, labels=['A', 'B', 'C'])
xlims = ax2.get_xlim()
ylims = ax2.get_ylim()
for poly in polys:
    for path in poly.get_paths():
        path.vertices = path.vertices[:, ::-1]
ax2.set_xlim(ylims)  # use old y limits
ax2.set_ylim(xlims[::-1])  # use old x limits, reversed
ax2.legend(loc='upper right')

ax3.set_title('Use fill_betweenx to create a stacked area chart')
y1 = np.array(y1)
y2 = np.array(y2)
y3 = np.array(y3)
ax3.fill_betweenx(x, 0, y1, label='A')
ax3.fill_betweenx(x, y1, y1 + y2, label='B')
ax3.fill_betweenx(x, y1 + y2, y1 + y2 + y3, label='C')
ax3.invert_yaxis()
ax3.set_xlim(xmin=0)
ax3.legend(loc='upper right')

plt.tight_layout()
plt.show()

相关问题