Single Stacked Bar Chart Matplotlib
First transpose one column DataFrame:
df.T.plot.barh(stacked=True, legend=False)
If 2 or more columns:
df[['Percentage']].T.plot.barh(stacked=True, legend=False)
plotting stacked bar graph
With Python 3.9.7, your graphs look like the same:
>>> df_alpha
a b c d e f g h i j k l
2016 20 20 20 20 20 20 20 20 20 20 20 20
2017 0 13 20 20 20 20 20 20 20 20 20 20
2018 0 10 10 10 10 10 10 10 10 10 10 0
2019 0 18 15 15 15 15 15 15 15 15 15 0
2020 10 15 18 18 18 18 18 18 18 18 18 0
2021 21 45 78 75 78 78 78 78 78 78 78 20
>>> df_month
January February March April may June July August September October November December
2016 20 20 20 20 20 20 20 20 20 20 20 20
2017 0 13 20 20 20 20 20 20 20 20 20 20
2018 0 10 10 10 10 10 10 10 10 10 10 0
2019 0 18 15 15 15 15 15 15 15 15 15 0
2020 10 15 18 18 18 18 18 18 18 18 18 0
2021 21 45 78 75 78 78 78 78 78 78 78 20
Full-code:
import pandas as pd
import matplotlib.pyplot as plt
years = ['2016', '2017', '2018', '2019', '2020', '2021']
dataavail1 = {'a': [20, 0, 0, 0, 10, 21], 'b': [20, 13, 10, 18, 15, 45], 'c': [20, 20, 10, 15, 18, 78], 'd': [20, 20, 10, 15, 18, 75], 'e': [20, 20, 10, 15, 18, 78], 'f': [20, 20, 10, 15, 18, 78], 'g': [20, 20, 10, 15, 18, 78], 'h': [20, 20, 10, 15, 18, 78], 'i': [20, 20, 10, 15, 18, 78], 'j': [20, 20, 10, 15, 18, 78], 'k': [20, 20, 10, 15, 18, 78], 'l': [20, 20, 0, 0, 0, 20]}
dataavail2 = {'January': [20, 0, 0, 0, 10, 21], 'February': [20, 13, 10, 18, 15, 45], 'March': [20, 20, 10, 15, 18, 78], 'April': [20, 20, 10, 15, 18, 75], 'may': [20, 20, 10, 15, 18, 78], 'June': [20, 20, 10, 15, 18, 78], 'July': [20, 20, 10, 15, 18, 78], 'August': [20, 20, 10, 15, 18, 78], 'September': [20, 20, 10, 15, 18, 78], 'October': [20, 20, 10, 15, 18, 78], 'November': [20, 20, 10, 15, 18, 78], 'December': [20, 20, 0, 0, 0, 20]}
df_alpha = pd.DataFrame(dataavail1, index=years)
df_month = pd.DataFrame(dataavail2, index=years)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 8))
df_alpha.plot(kind='bar', stacked=True, colormap=plt.cm.tab20, ax=ax1, rot=0)
df_month.plot(kind='bar', stacked=True, colormap=plt.cm.tab20, ax=ax2, rot=0)
plt.show()
Update: the code also works with Python 3.7.12
plotting multiple stacked bar chart
IIUC, try:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 5, figsize=(20, 8))
iax = iter(ax.flatten())
for n, g in df.groupby('Business Unit'):
g.loc[n, :].plot.bar(ax=next(iax), title=f'{n}', stacked=True)
Draw a stacked bar chart from multiple columns instead of drawing a graph for each column?
It can be achieved by rearranging the dataframe using groupby. Consider the code:
df_responses= pd.read_csv('https://raw.githubusercontent.com/eng-aomar/Security_in_practice/main/secuirtyInPractice.csv')
df_new =df_responses.iloc[:,9:21]
image_format = 'svg' # e.g .png, .svg, etc.
# initialize empty dataframe
df2 = pd.DataFrame()
# group by each column counting the size of each category values
for col in df_new:
grped = df_new.groupby(col).size()
grped = grped.rename(grped.index.name)
df2 = df2.merge(grped.to_frame(), how='outer', left_index=True, right_index=True)
# plot the merged dataframe
df2.plot.bar(stacked=True)
plt.show()
Using your data and notebook. This is what I get:
Stacked Bar Graphs with only Plotly Express
You can create a dataframe and structure it from your lists. Then it's simple to use Plotly Express
import plotly.express as px
import pandas as pd
labels = ["label1", "label2", "label3"]
types = ["type1", "type2", "type3", "type4", "type5", "type6"]
counts = [[3, 5, 2, 1, 7, 10], [2, 2, 4, 1, 7, 2], [1, 6, 8, 11, 2, 3]]
px.bar(
pd.DataFrame(counts, columns=types, index=labels).reset_index().melt(id_vars="index"),
x="index",
y="value",
color="variable",
)
numpy
import numpy as np
c = np.array(counts)
px.bar(x=np.tile(labels, c.shape[1]), color=np.repeat(types, c.shape[0]), y=c.T.flatten())
Matplotlib stacked bar chart set column order
to set a custom order for the stacked bars, you will need to order it by setting the CategoricalIndex
and sorting the data by these categories. This will sort the three categories in the way you need. A small example to show the same is below...
Data 'df'
Intervention Remuneration Training Supervision
A 21 4 12
B 41 5 21
C 33 6 7
Code
#Convert Intervention as index, so columns are the categories
df = df.set_index('Intervention')
#Set categories... Order will Remuneration-Training-Supervision
df.columns=pd.CategoricalIndex(df.columns.values, ordered=True, categories=['Remuneration','Training','Supervision'])
#Sort the data
df = df.sort_index(axis=1)
#...and plot
bar = df.plot.barh(stacked=True)
Output
How to implement stacked bar graph with a line chart in R
You first need to reshape longer, for example with pivot_longer()
from tidyr
, and then you can use ggplot2
to plot the bars and the line in two separate layers. The fill =
argument in the geom_bar(aes())
lets you stratify each bar according to a categorical variable - name
is created automatically by pivot_longer()
.
library(ggplot2)
library(tidyr)
dat |>
pivot_longer(A:B) |>
ggplot(aes(x = Year)) +
geom_bar(stat = "identity", aes(y = value, fill = name)) +
geom_line(aes(y = `C(%)`), size = 2)
Created on 2022-06-09 by the reprex package (v2.0.1)
You're asking for overlaid bars, in which case there's no need to pivot, and you can add separate layers. However I would argue that this could confuse or mislead many people - usually in stacked plots bars are stacked, not overlaid, so thread with caution!
library(ggplot2)
library(tidyr)
dat |>
ggplot(aes(x = Year)) +
geom_bar(stat = "identity", aes(y = A), fill = "lightgreen") +
geom_bar(stat = "identity", aes(y = B), fill = "red", alpha = 0.5) +
geom_line(aes(y = `C(%)`), size = 2) +
labs(y = "", caption = "NB: bars are overlaid, not stacked!")
Created on 2022-06-09 by the reprex package (v2.0.1)
Related Topics
Aggregate and Reshape from Long to Wide
How to Combine 2 Plots (Ggplot) into One Plot
How to Write to JSON with Children from R
R: How to Get the Week Number of the Month
Select Row with Most Recent Date by Group
Dplyr Broadcasting Single Value Per Group in Mutate
Divide Row Value by Aggregated Sum in R Data.Frame
How to Make a Discontinuous Axis in R with Ggplot2
How to Add \Newpage in Rmarkdown in a Smart Way
Selecting Columns in R Data Frame Based on Those *Not* in a Vector
How to Add a Index by Set of Data When Using Rbindlist
How to Use the Switch Statement in R Functions
How to Use Map from Purrr with Dplyr::Mutate to Create Multiple New Columns Based on Column Pairs
One-Hot Encoding in [R] | Categorical to Dummy Variables
Improve Centering County Names Ggplot & Maps
Returning Above and Below Rows of Specific Rows in R Dataframe
Dt: Dynamically Change Column Values Based on Selectinput from Another Column in R Shiny App
How to Specify a Dynamic Position for the Start of Substring