How to rotate a stacked area plot

Question:

I’d like to re-orient a stacked-area plot such that the stacked areas are stacked horizontally rather than vertically (from a viewer’s perspective). So here is what a typical stacked-area plot looks like:

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

Next, I’d like to take that entire plot and rotate it 90 degrees, which I attempted to do using the accepted answer found here. However, running the code that follows, the contents of the plot are seemingly lost? Is there a better way to draw a "rotated stacked-area" plot?

Here is the code I attempted to use:

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

If it is possible, I’d also like to apply plt.gca().invert_yaxis() after rotating in order to reverse the values plotted on the y-axis (formerly the x-axis).

Asked By: user2256085

||

Answers:

The following code iterates through the stacked polygons and exchanges the x and y values of their vertices. The axes limits are also switched.

Alternatively, you can create the same plot more straightforward via fill_betweenx(...). With the data converted to numpy arrays, the y-values can be summed directly.

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

rotating stacked area plot

Answered By: JohanC
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.