简体   繁体   中英

Stacked Bar Chart in Matplotlib

I am trying to create stacked Bar Chart in Matplotlib. I have created a simple one using Pandas, but i am now interested in Matplotlib one but cant make it work.

My data

    ShiftType   ShiftNumber cnt
0   Non-Standard    1.0 154478
1   Non-Standard    2.0 140421
2   Non-Standard    3.0 159990
3   Standard    1.0 211100
4   Standard    2.0 198652
5   Standard    3.0 190857

Code that works using Pandas.

df.groupby(by=['ShiftType','ShiftNumber']).size().rename('cnt').unstack().plot(kind='bar', stacked=True)
plt.legend(title='Shift Numbers', bbox_to_anchor=(1.0, 1), loc='upper left')

在 Python 中使用 Pandas 的堆积条形图

How can i get this based on Matplotlib?

The sample code you provided does not accurately tally the sum. It's also somewhat unclear what you mean by "create stacked Bar Chart in Matplotlib" as the Pandas plot() function you called is a matplotlib integration. Regardless, as standard (and possibly best) practice, I regularly use figure and axes to set up my plots. This allows careful control of the plots which I think you are trying to do here.

I would suggest this code as a solution to your question and starting point for further plot manipulation.

fig, ax = plt.subplots()

df.groupby(['ShiftType', 'ShiftNumber']) \
    ['cnt'].sum() \
    .reset_index() \
    .pivot_table(index='ShiftType', columns='ShiftNumber', values='cnt') \
    .plot(kind='bar', stacked=True, ax=ax)
ax.legend(title='Shift Numbers', bbox_to_anchor=(1.0, 1), loc='upper left')

I would then add some standard features that every chart should have, for example a y-label and a title.

ax.set_ylabel('cnt')
ax.set_title('Count of Shift Types')

Combining those, you will then get this final plot.

ShiftType 堆积条形图

There might be someting more compact but here is a solution. Here is your df

     ShiftType  ShiftNumber     cnt
0  Non-Standard          1.0  154478
1  Non-Standard          2.0  140421
2  Non-Standard          3.0  159990
3      Standard          1.0  211100
4      Standard          2.0  198652
5      Standard          3.0  190857
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
fig, ax = plt.subplots(figsize=(10,7))  

m = df['ShiftNumber'].drop_duplicates()
margin_bottom = np.zeros(len(df['ShiftType'].drop_duplicates()))
colors = ["#006D2C", "#31A354","#74C476"]

for num, m in enumerate(m):
    values = list(df[df['ShiftNumber'] == m].loc[:, 'cnt'])

    df[df['ShiftNumber'] == m].plot.bar(x='ShiftType',y='cnt', ax=ax, stacked=True, 
                                    bottom = margin_bottom, color=colors[num], label=m)
    margin_bottom += values

plt.show()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM