Stacked Bar Charts with Python’s Matplotlib
By: Thiago Carvalho
Tags: Python, Matplotlib, Bar Chart, Data Science, Data Visualization

As expected, the chart is hard to read. Let’s try the stacked bar chart and add a few adjustments.

First, we can sort the values before plotting, giving us a better sense of order and making it easier to compare the bars. We’ll do so with the ‘Global Sales’ column since it has the total.

## sort values

df_grouped = df_grouped.sort_values('Global_Sales')

df_grouped

Some of the records on the data frame — Image by Author

Earlier, to build a clustered bar chart, we used a plot for each region where the width parameter and adjustments in the x-axis helped us fit each platform's four areas.

Similarly, for plotting stack bar charts, we’ll use a plot for each region. This time we’ll use the bottom/left parameter to tell Matplotlib what comes before the bars we’re drawing.

plt.bar([1,2,3,4], [10,30,20,5])

plt.bar([1,2,3,4], [3,4,5,6], bottom = [10,30,20,5])

plt.show() plt.barh([1,2,3,4], [10,30,20,5])

plt.barh([1,2,3,4], [3,4,5,6], left = [10,30,20,5])

plt.show()

Stacked Bar Charts (Vertical/ Horizontal) — Image by Author

Cool. We can use a loop to plot the bars, passing a list of zeros for the ‘bottom’ parameter in the first set and accumulating the following values for the next regions.

fields = ['NA_Sales','EU_Sales','JP_Sales','Other_Sales']

colors = ['#1D2F6F', '#8390FA', '#6EAF46', '#FAC748']

labels = ['NA', 'EU', 'JP', 'Others'] # figure and axis

fig, ax = plt.subplots(1, figsize=(12, 10)) # plot bars

left = len(df_grouped) * [0]

for idx, name in enumerate(fields):

plt.barh(df_grouped.index, df_grouped[name], left = left, color=colors[idx])

left = left + df_grouped[name] # title, legend, labels

plt.title('Video Game Sales By Platform and Region

', loc='left')

plt.legend(labels, bbox_to_anchor=([0.55, 1, 0, 0]), ncol=4, frameon=False)

plt.xlabel('Millions of copies of all games') # remove spines

ax.spines['right'].set_visible(False)

ax.spines['left'].set_visible(False)

ax.spines['top'].set_visible(False)

ax.spines['bottom'].set_visible(False) # adjust limits and draw grid lines

plt.ylim(-0.5, ax.get_yticks()[-1] + 0.5)

ax.set_axisbelow(True)

ax.xaxis.grid(color='gray', linestyle='dashed') plt.show()

Stacked Bar Chart — Image by Author

Great, this is way more readable than the last one.

It’s important to remember the purpose of this chart before trying to extract any insights. The idea here is to compare the platforms' total sales and understand each platform's composition.

Comparing totals across fields and comparing regions inside one bar is ok. Comparing regions from different bars, on the other hand, can be very misleading.

In this case, we can compare the NA region across the bars since it has the same starting point for every bar, but it isn't so easy to compare the others. Take the X360, for example, it has a lower value for JP than the PS2, but it’s hard to compare if the Others value is higher or lower than the Wii.

Comparable value — Image by Author

Uncomparable value — Image by Author

Suppose we change the stack's order, with Other Sales as the first bar, and sort the records by Other Sales. It should be easier to tell which is more significant.

## sort values

df_grouped = df_grouped.sort_values('Other_Sales') fields = ['Other_Sales', 'NA_Sales','EU_Sales','JP_Sales']

colors = ['#1D2F6F', '#8390FA', '#6EAF46', '#FAC748']

labels = ['Others', 'NA', 'EU', 'JP']

Stacked Bar Chart, emphasizing the Others category — Image by Author

There are two essential elements in this visualization, the order of the categories in the stack of bars and the rows' order.

If we want to emphasize one region, we can sort the records with the chosen field and use it as the left-most bar.

If we don’t, we can sort the records by the total and order the stacks with the categories that have higher values first.