Plotting Grouped Bar Plots with Stacked Bars in Python
======================================================
In this article, we will explore how to create a grouped bar plot with stacked bars in Python using the matplotlib library. We will also cover how to modify the existing code to achieve this.
Introduction
Matplotlib is one of the most widely used data visualization libraries in Python. It provides a comprehensive set of tools for creating high-quality 2D and 3D plots, charts, and graphs. In this article, we will focus on creating a grouped bar plot with stacked bars using matplotlib.
Grouped Bar Plot
A grouped bar plot is a type of bar chart where multiple categories are grouped together in each bar. This type of plot is often used to compare the values across different categories.
Stacked Bars
Stacked bars are a type of bar chart where the bars within a group are stacked on top of each other. Each bar represents the sum of the values for that category and subgroup. In our case, we want to create two types of stacked bars: one with all four subgroups (Coal, Oil and natural gas, Nuclear, Renewables) and another with only three subgroups (Generation, Storage, Electricity networks).
Python Code
To create a grouped bar plot with stacked bars in Python, we will use the matplotlib library. We will first import the necessary modules and load our data.
import matplotlib.pyplot as plt
import numpy as np
# Load the data
colors = ["black","gray","red","green","blue","yellow"]
df = pd.DataFrame({
'Coal': [79.6, 70.9, 65.8, 64.7, 62.2, 56.4, 51.6, 48.2],
'Oil and natural gas': [79.8, 83.2, 77.2, 64.5, 67.4, 55.3, 67.0, 70.8],
'Nuclear': [28.4, 33.7, 36.9, 34.0, 34.8, 39.5, 43.7, 49.3],
'Renewables': [309.9, 318.3, 325.9, 359.0, 393.2, 418.4, 445.8, 471.7],
'Storage': [1.6, 2.5, 3.1, 4.7, 4.6, 6.2, 9.4, 18.3],
'Electricity networks': [316.8, 327.9, 318.6, 310.3, 291.8, 291.6, 308.1, 318.2]
})
# Create a figure and axis
fig, ax = plt.subplots(figsize=(10, 6))
First Stacked Bar Plot
We will first create the stacked bar plot with all four subgroups (Coal, Oil and natural gas, Nuclear, Renewables). We use the align='edge' parameter to align the bars on the edges of each group.
# Create the first stacked bar plot
ax = df.iloc[:,:4].plot.bar(stacked=True, align='edge', width=-.2, color=colors[:4])
# Set the x-axis tick labels
ax.set_xticks(np.arange(len(colors[:4])))
ax.set_xticklabels([f'{l} ({i})' for i,l in enumerate(colors[:4])])
Second Stacked Bar Plot
We will then create the second stacked bar plot with only three subgroups (Generation, Storage, Electricity networks). We use the align='edge' parameter to align the bars on the edges of each group.
# Create the second stacked bar plot
df.iloc[:,4:].plot.bar(ax=ax, align='edge', width=.4, color=colors[4:])
Customizing the Legend
We will then customize the legend by fixing its position to (1, 1). We use the legend function to create a new legend with custom labels.
# Customize the legend
handles, labels = ax.get_legend_handles_labels()
labels = [f'Generation ({l})' if i < 4 else l for i,l in enumerate(labels)]
ax.legend(handles, labels, bbox_to_anchor=(1, 1))
Plotting the Bar Plots
Finally, we will plot both bar plots on the same figure.
# Show the plot
plt.show()
The final code is:
import matplotlib.pyplot as plt
import numpy as np
# Load the data
colors = ["black","gray","red","green","blue","yellow"]
df = pd.DataFrame({
'Coal': [79.6, 70.9, 65.8, 64.7, 62.2, 56.4, 51.6, 48.2],
'Oil and natural gas': [79.8, 83.2, 77.2, 64.5, 67.4, 55.3, 67.0, 70.8],
'Nuclear': [28.4, 33.7, 36.9, 34.0, 34.8, 39.5, 43.7, 49.3],
'Renewables': [309.9, 318.3, 325.9, 359.0, 393.2, 418.4, 445.8, 471.7],
'Storage': [1.6, 2.5, 3.1, 4.7, 4.6, 6.2, 9.4, 18.3],
'Electricity networks': [316.8, 327.9, 318.6, 310.3, 291.8, 291.6, 308.1, 318.2]
})
# Create a figure and axis
fig, ax = plt.subplots(figsize=(10, 6))
# Create the first stacked bar plot
ax = df.iloc[:,:4].plot.bar(stacked=True, align='edge', width=-.2, color=colors[:4])
# Set the x-axis tick labels
ax.set_xticks(np.arange(len(colors[:4])))
ax.set_xticklabels([f'{l} ({i})' for i,l in enumerate(colors[:4])])
# Create the second stacked bar plot
df.iloc[:,4:].plot.bar(ax=ax, align='edge', width=.4, color=colors[4:])
# Customize the legend
handles, labels = ax.get_legend_handles_labels()
labels = [f'Generation ({l})' if i < 4 else l for i,l in enumerate(labels)]
ax.legend(handles, labels, bbox_to_anchor=(1, 1))
# Show the plot
plt.show()
Last modified on 2024-12-04