Create Stacked Bar Chart with Negative Values in Matplotlib

Working on a data visualization project where I needed to show both positive and negative values in a single stacked bar chart using Python.

At first, I thought it would be easy, but I quickly realized that handling negative values in a stacked chart requires a little extra care.

In this tutorial, I’ll show you step-by-step how I created a Matplotlib stacked bar chart with negative values in Python. I’ll also share some practical tips I’ve learned from over 10 years of working with Python and data visualization.

What is a Stacked Bar Chart in Python?

A stacked bar chart is a type of bar graph that displays multiple data series stacked on top of one another. It’s a great way to show how different parts contribute to a total across categories.

In Python, we can easily create stacked bar charts using the Matplotlib library. It’s one of the most powerful and flexible plotting libraries in Python.

However, when you have negative values, the bars can overlap or behave unexpectedly. That’s why we’ll look at the correct way to handle them.

Set Up the Environment

Before we start coding, make sure you have Matplotlib and NumPy installed in your Python environment.

You can install them using pip:

pip install matplotlib numpy

Once installed, we’re ready to start building our Python stacked bar chart.

Example Dataset for the Stacked Bar Chart

For this example, let’s assume we’re visualizing monthly profit and loss data for two U.S. retail stores, one in New York and another in California.

Each store has both positive (profit) and negative (loss) values, which makes this a perfect real-world use case.

Let’s start by importing the required Python libraries and creating our dataset.

import matplotlib.pyplot as plt
import numpy as np

# Sample data for two U.S. retail stores
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
store_ny = [5000, -2000, 3000, -1500, 4000, 2500]  # New York
store_ca = [3000, 1500, -2500, 2000, -1000, 3500]  # California

# Create an array for the x-axis positions
x = np.arange(len(months))
width = 0.6

Here, I’ve created two lists, one for New York and one for California, containing both positive and negative values. Next, we’ll use Matplotlib to plot these values in a stacked format.

Method 1 – Create a Basic Stacked Bar Chart with Negative Values

Let’s start with the simplest method to create a stacked bar chart in Python using Matplotlib.

# Create the figure and axis
fig, ax = plt.subplots(figsize=(10, 6))

# Plot the first bar (New York)
ax.bar(x, store_ny, width, label='New York', color='#1f77b4')

# For stacking, we need to handle positive and negative values separately
store_ny_positive = np.where(np.array(store_ny) > 0, store_ny, 0)
store_ny_negative = np.where(np.array(store_ny) < 0, store_ny, 0)

# Stack California values correctly on top/bottom of New York
ax.bar(x, np.where(np.array(store_ca) > 0, store_ca, 0),
       width, bottom=store_ny_positive, label='California (Profit)', color='#ff7f0e')

ax.bar(x, np.where(np.array(store_ca) < 0, store_ca, 0),
       width, bottom=store_ny_negative, label='California (Loss)', color='#d62728')

# Add labels and title
ax.set_ylabel('Profit/Loss ($)')
ax.set_title('Monthly Profit and Loss by Store (Stacked Bar Chart with Negative Values)')
ax.set_xticks(x)
ax.set_xticklabels(months)
ax.legend()

plt.axhline(0, color='black', linewidth=0.8)
plt.tight_layout()
plt.show()

You can refer to the screenshot below to see the output.

Create Stacked Bar Chart with Negative Values in Matplotlib

This method ensures that positive and negative values are stacked correctly, profits go upward, and losses go downward.

The np.where() function helps us separate positive and negative values so that Matplotlib can stack them properly.

Method 2 – Use Pandas for Easier Data Handling

If you prefer working with Pandas, you can use a DataFrame to simplify your code. This approach is especially helpful when you’re working with larger datasets or multiple data series.

import pandas as pd
import matplotlib.pyplot as plt

# Create a DataFrame
data = {
    'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
    'New York': [5000, -2000, 3000, -1500, 4000, 2500],
    'California': [3000, 1500, -2500, 2000, -1000, 3500]
}

df = pd.DataFrame(data)
df.set_index('Month', inplace=True)

# Separate positive and negative values
df_positive = df.clip(lower=0)
df_negative = df.clip(upper=0)

# Plot stacked bars
fig, ax = plt.subplots(figsize=(10, 6))
df_positive.plot(kind='bar', stacked=True, ax=ax, color=['#1f77b4', '#ff7f0e'])
df_negative.plot(kind='bar', stacked=True, ax=ax, color=['#aec7e8', '#ffbb78'])

ax.axhline(0, color='black', linewidth=0.8)
ax.set_ylabel('Profit/Loss ($)')
ax.set_title('Monthly Profit and Loss by Store (Stacked Bar Chart with Negative Values)')
plt.tight_layout()
plt.show()

You can refer to the screenshot below to see the output.

Create Stacked Bar Chart with Negative Values Python Matplotlib

This method uses Pandas’ built-in plotting capabilities, which internally rely on Matplotlib. It’s a cleaner approach when your data already exists in a DataFrame format, and it automatically handles stacking logic for you.

Method 3 – Add Data Labels to the Stacked Bars

Adding labels to your stacked bars helps make the chart easier to read, especially when you’re presenting financial or business data.

Let’s modify our chart to include data labels for each bar segment.

import matplotlib.pyplot as plt
import numpy as np

months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
store_ny = [5000, -2000, 3000, -1500, 4000, 2500]
store_ca = [3000, 1500, -2500, 2000, -1000, 3500]

x = np.arange(len(months))
width = 0.6

fig, ax = plt.subplots(figsize=(10, 6))

# Plot stacked bars
bar1 = ax.bar(x, store_ny, width, label='New York', color='#1f77b4')
bar2 = ax.bar(x, store_ca, width, bottom=store_ny, label='California', color='#ff7f0e')

# Add data labels
for rect in bar1 + bar2:
    height = rect.get_height()
    if height != 0:
        ax.text(rect.get_x() + rect.get_width()/2, rect.get_y() + height/2,
                f'{int(height)}', ha='center', va='center', fontsize=9, color='white')

ax.axhline(0, color='black', linewidth=0.8)
ax.set_ylabel('Profit/Loss ($)')
ax.set_title('Stacked Bar Chart with Negative Values and Labels (Python Matplotlib)')
ax.set_xticks(x)
ax.set_xticklabels(months)
ax.legend()

plt.tight_layout()
plt.show()

You can refer to the screenshot below to see the output.

Create Stacked Bar Chart with Negative Values Matplotlib

Here, I used a for loop to iterate through each bar and add a text label in the center. This small touch makes the chart more informative and presentation-ready.

Customize the Chart Appearance

You can further customize your Matplotlib stacked bar chart by changing colors, adding gridlines, or adjusting font sizes.

For example, adding gridlines can help users easily compare values across months.

ax.grid(True, linestyle='--', alpha=0.6)

You can also change the color palette using Matplotlib’s built-in color maps or even use custom HEX color codes to match your brand.

Common Pitfalls When Working with Negative Values

From my experience, here are a few common issues you might face when plotting stacked bar charts with negative values in Python:

  • Bars overlap incorrectly: This happens if you don’t separate positive and negative values before stacking.
  • Zero line missing: Always include ax.axhline(0) to make it clear where positive ends and negative begins.
  • Labels misaligned: When adding labels, ensure they’re centered relative to the stacked segment.

By keeping these points in mind, you’ll avoid most of the visual inconsistencies that come with negative data.

Real-World Use Case

Imagine you’re analyzing the monthly net profit and loss of multiple retail stores across the U.S. A stacked bar chart with negative values helps you quickly visualize which months had losses and which had profits, all in one clean chart.

This visualization is ideal for financial reports, sales dashboards, and business performance tracking.

Conclusion

Creating a stacked bar chart with negative values in Python using Matplotlib might seem tricky at first, but once you understand how to separate positive and negative values, it becomes straightforward.

I’ve used this technique in many real-world projects, from analyzing regional sales data to visualizing profit margins across departments.

Both the NumPy-based and Pandas-based methods work great. If you’re already working with DataFrames, I recommend the Pandas method for its simplicity and readability.

You may also read:

Leave a Comment

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.