0

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?

2 Answers 2

2

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')
Sign up to request clarification or add additional context in comments.

4 Comments

This would pass 2018 to the x-ticks as well. So the label will read (2018,1),... Is there a direct way to drop that?
@ScottBoston thanks for the updated attempt. How should we control figsize, legend position, and add each year+ some string as a title?
shouldn't figsize be passed to subplots?
@QuangHoang I think you can do it either way. I am not really certain though.
2

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)

3 Comments

this is super! how should I control legend position (add one the top of each stacked plot) and add each distinct year + some string as the title? also, how can we keep the distance between each subplot?
Have a look at the document for subplots. You can add title for each subplot inside the for loop, e.g. ax.set_title('some title').
@Adam You can use ...plot.bar(stacked=True, ax=ax, title=f'{n} Year')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.