Plot Multiple Bar Charts with Time Series in Matplotlib

Creating a visual representation of data over time is one of the most common tasks I handle as a Python developer.

Whether I am tracking quarterly revenue or monitoring weather patterns in different US states, a time series bar plot is often my go-to choice.

In this tutorial, I will show you exactly how to plot multiple bar charts on a time axis using Matplotlib.

We will move beyond simple examples and look at how to handle date objects and overlapping bars effectively.

Understand the Challenge of Time Series Bar Plots

When I first started working with Matplotlib, I found plotting multiple bars on a date axis to be quite tricky.

The main issue is that dates are often treated as continuous points, while bars need a specific width and offset to avoid overlapping.

To get this right, we need to convert our dates into a format that Matplotlib can manipulate numerically.

I usually use numpy or pandas libraries to manage the data before feeding it into the plotting functions.

Method 1: Create a Grouped Bar Plot with Time Series Data

Grouped bar plots are excellent when you want to compare different categories side-by-side over a specific period.

For this example, let’s look at the average monthly gasoline prices in two different US regions: the East Coast and the West Coast.

I will use the datetime module to create my time axis and then offset the bars manually.

import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime

# Data: Monthly Avg Gas Prices (USD) for two US regions
months = [
    datetime(2023, 1, 1), datetime(2023, 2, 1), datetime(2023, 3, 1),
    datetime(2023, 4, 1), datetime(2023, 5, 1), datetime(2023, 6, 1)
]

east_coast_prices = [3.45, 3.52, 3.60, 3.75, 3.80, 3.92]
west_coast_prices = [4.10, 4.25, 4.30, 4.50, 4.65, 4.78]

# We need a numeric representation of the dates for positioning
x = np.arange(len(months)) 
width = 0.35  # Width of each bar

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

# Plotting the bars
rects1 = ax.bar(x - width/2, east_coast_prices, width, label='East Coast', color='#3498db')
rects2 = ax.bar(x + width/2, west_coast_prices, width, label='West Coast', color='#e74c3c')

# Customizing the axes
ax.set_ylabel('Price per Gallon ($)')
ax.set_title('Gasoline Price Comparison: East vs West Coast (2023)')
ax.set_xticks(x)
ax.set_xticklabels([m.strftime('%b %Y') for m in months])
ax.legend()

plt.tight_layout()
plt.show()

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

Multiple Bar Charts with Time Series in Matplotlib

In this code, I used np.arange(len(months)) to create a temporary X-axis.

By subtracting and adding half the width to these positions, I successfully placed the bars side-by-side. Finally, I used strftime to format the date labels so they look clean and professional.

Method 2: Plot Stacked Bar Charts for Time Series

Sometimes, I prefer to see the total volume while still identifying the contribution of each segment.

For example, if I am analyzing the total energy production in Texas from both Wind and Solar sources, a stacked bar chart is perfect.

This method allows you to see the growth of the total energy sector over time while observing the ratio of the components.

import matplotlib.pyplot as plt
import pandas as pd

# Creating a dataset for Texas Energy Production (in Gigawatts)
data = {
    'Date': pd.to_datetime(['2023-01-01', '2023-02-01', '2023-03-01', '2023-04-01']),
    'Wind': [12.5, 14.2, 15.8, 13.1],
    'Solar': [5.1, 6.4, 8.2, 10.5]
}

df = pd.DataFrame(data)

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

# The 'bottom' parameter is key for stacking
ax.bar(df['Date'], df['Wind'], width=20, label='Wind Power', color='skyblue')
ax.bar(df['Date'], df['Solar'], width=20, bottom=df['Wind'], label='Solar Power', color='orange')

# Formatting the Date Axis
plt.xticks(df['Date'], df['Date'].dt.strftime('%Y-%m'), rotation=45)

ax.set_ylabel('Energy Production (GW)')
ax.set_title('Texas Renewable Energy Production Trends')
ax.legend()

plt.tight_layout()
plt.show()

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

Plot Multiple Bar Charts with Time Series Matplotlib

I find the bottom parameter in the ax.bar() function to be incredibly useful here.

By passing the values of the first category to the bottom argument of the second, Matplotlib stacks them automatically.

Notice how I set the width to 20; this is because, on a daily-scale X-axis, a width of 1 is just one day, making the bars look like thin lines.

Method 3: Use Pandas Plotting for Quick Comparisons

If I am in a hurry and my data is already in a Pandas DataFrame, I often skip the manual Matplotlib setup.

Pandas has a built-in wrapper for Matplotlib that handles time series grouping very efficiently.

Let’s look at the quarterly sales of three different US tech hubs: Silicon Valley, Austin, and Seattle.

import pandas as pd
import matplotlib.pyplot as plt

# Data: Quarterly Revenue (Millions of USD)
data = {
    'Quarter': ['2023-Q1', '2023-Q2', '2023-Q3', '2023-Q4'],
    'Silicon Valley': [450, 480, 510, 540],
    'Austin': [210, 230, 255, 290],
    'Seattle': [300, 315, 340, 360]
}

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

# Pandas makes multiple bar plots very simple
ax = df.plot(kind='bar', figsize=(11, 6), width=0.8)

ax.set_ylabel('Revenue (Millions $)')
ax.set_title('Tech Hub Revenue Growth by Quarter')
plt.xticks(rotation=0)
plt.grid(axis='y', linestyle='--', alpha=0.7)

plt.show()

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

Plot Matplotlib Multiple Bar Charts with Time Series

When I use this method, Pandas treats the index (Quarters) as the X-axis and automatically groups the numeric columns.

I find this to be the cleanest way to write code when dealing with more than two categories. It automatically adds a legend and handles the coloring for you, which saves a lot of time.

Advanced Customization: Handle Date Locators and Formatters

When working with long-term US economic data, like 10 years of employment rates, the X-axis can become cluttered.

In such cases, I use matplotlib.dates module to control exactly where the ticks appear. This ensures that the bars don’t overlap with the text, keeping the chart readable.

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
import numpy as np

# Generating dummy US Unemployment data for 12 months
dates = pd.date_range('2023-01-01', periods=12, freq='M')
men_unemployment = np.random.uniform(3.5, 4.5, 12)
women_unemployment = np.random.uniform(3.2, 4.2, 12)

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

width = 10 # Days
ax.bar(dates - pd.Timedelta(days=width/2), men_unemployment, width=width, label='Men', color='navy')
ax.bar(dates + pd.Timedelta(days=width/2), women_unemployment, width=width, label='Women', color='salmon')

# Using DateFormatter for better readability
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
ax.xaxis.set_major_locator(mdates.MonthLocator())

plt.xticks(rotation=45)
ax.set_title('US Monthly Unemployment Rate Comparison (2023)')
ax.set_ylabel('Unemployment Rate (%)')
ax.legend()

plt.tight_layout()
plt.show()

By using mdates.MonthLocator(), I tell Matplotlib to place a tick for every month, regardless of how many data points exist.

The DateFormatter ensures that the date strings are formatted exactly how I want them (e.g., “Jan 2023”).

Tips for Improving Your Time Series Bar Plots

Through my experience, I have learned a few tricks that make these plots significantly better:

  1. Adjust Bar Width: Always adjust the width based on the frequency of your dates (daily, monthly, yearly).
  2. Use Alpha for Overlap: If you decide to overlap bars rather than group them, set alpha=0.5 to see both sets of data.
  3. Color Choice: Use high-contrast colors like those from the “Tableau” palette to differentiate between US regions or categories.
  4. Grid Lines: Adding a horizontal grid (ax.yaxis.grid()) makes it much easier to read the exact values of the bars.

In this tutorial, I showed you several ways to create a multiple-bar plot with time series data in Matplotlib.

I started with a manual grouped approach, moved to stacked bars, and then showed how Pandas can simplify the process.

I also covered how to format dates properly to avoid a messy X-axis.

You may also read:

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.