Adam
Adam

Reputation: 223

how to make stacked plots for dataframe with multiple index in python?

I have trade export data which is collected weekly. I intend to make stacked bar plot with matplotlib but I have little difficulties managing pandas dataframe with multiple indexes. I looked into this post but not able to get what I am expecting. Can anyone suggest a possible way of doing this in python? Seems I made the wrong data aggregation and I think I might use for loop to iterate year then make a stacked bar plot on a weekly base. Does anyone know how to make this easier in matplotlib? any idea?

reproducible data and my attempt

import pandas as pd
import matplotlib.pyplot as plt

# load the data
url = 'https://gist.githubusercontent.com/adamFlyn/0eb9d60374c8a0c17449eef4583705d7/raw/edea1777466284f2958ffac6cafb86683e08a65e/mydata.csv'
df = pd.read_csv(url, parse_dates=['weekly'])
df.drop('Unnamed: 0', axis=1, inplace=True)

nn = df.set_index(['year','week'])
nn.drop("weekly", axis=1, inplace=True)

f, a = plt.subplots(3,1)
nn.xs('2018').plot(kind='bar',ax=a[0])
nn.xs('2019').plot(kind='bar',ax=a[1])
nn.xs('2020').plot(kind='bar',ax=a[2])
plt.show()
plt.close()

this attempt didn't work for me. instead of explicitly selecting years like 2018, 2019, ..., is there any more efficient to make stacked bar plots for dataframe with multiple indexes? Any thoughts?

desired output

this is the desired stacked bar plot for year of 2018 as an example

how should I get my desired stacked bar plot? Any better ideas?

Upvotes: 0

Views: 672

Answers (2)

Scott Boston
Scott Boston

Reputation: 153460

Try this:

nn.groupby(level=0).plot.bar(stacked=True)

or to prevent year as tuple in x axis:

for n, g in nn.groupby(level=0):
    g.loc[n].plot.bar(stacked=True)

Update per request in comments

for n, g in nn.groupby(level=0):
    ax = g.loc[n].plot.bar(stacked=True, title=f'{n} Year', figsize=(8,5))
    ax.legend(loc='lower center')

Change layout position

fig, ax = plt.subplots(1,3)
axi = iter(ax)
for n, g in nn.groupby(level=0):
    axs = next(axi)
    g.loc[n].plot.bar(stacked=True, title=f'{n}', figsize=(15,8), ax=axs)
    axs.legend(loc='lower center')

Upvotes: 2

Quang Hoang
Quang Hoang

Reputation: 150735

Try using loc instead of xs:

f, a = plt.subplots(3,1)
for x, ax in zip(nn.index.unique('year'),a.ravel()):
    nn.loc[x].plot.bar(stacked=True, ax=ax)

Upvotes: 2

Related Questions