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 numpyOnce 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.6Here, 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.

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.

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.

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:
- Matplotlib Two Y Axes: Plot with Same and Different Scales
- Plot Two Y Axes with the Same Data in Matplotlib
- Create a Stacked Bar Chart with Labels in Python Matplotlib
- Create a Stacked Bar Chart Using a For Loop with Matplotlib

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.