How to plot a Pandas multi-index dataFrame with all xticks (Matplotlib)?

When working with multi-index DataFrames in Pandas, plotting with proper x-axis tick labels can be challenging. This guide shows how to create readable plots with all x-tick labels displayed correctly using Matplotlib.

Understanding Multi-Index DataFrames

A multi-index DataFrame has multiple levels of row or column indices. When plotting such data, the default x-axis labels might not display all information clearly ?

Step-by-Step Implementation

Creating Sample Multi-Index Data

First, let's create a multi-index DataFrame with time-series data grouped by year and month ?

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

# Set figure parameters
plt.rcParams["figure.figsize"] = [10, 6]
plt.rcParams["figure.autolayout"] = True

# Create date range with 1000 samples
idx = pd.date_range("2020-01-01", periods=1000)
val = np.random.rand(1000)
s = pd.Series(val, idx)

print("Original series shape:", s.shape)
print("First 5 values:")
print(s.head())
Original series shape: (1000,)
First 5 values:
2020-01-01    0.374540
2020-01-02    0.950714
2020-01-03    0.731994
2020-01-04    0.598658
2020-01-05    0.156019
Freq: D, dtype: float64

Creating Multi-Index Groups

Group the data by year and month to create a multi-index structure ?

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

plt.rcParams["figure.figsize"] = [10, 6]
plt.rcParams["figure.autolayout"] = True

idx = pd.date_range("2020-01-01", periods=1000)
val = np.random.rand(1000)
s = pd.Series(val, idx)

# Group by year and month, calculate mean
grouped_data = s.groupby([s.index.year, s.index.month]).mean()

print("Multi-index structure:")
print(grouped_data.head(10))
print("\nIndex levels:", grouped_data.index.names)
Multi-index structure:
2020  1     0.488201
      2     0.513835
      3     0.508094
      4     0.494571
      5     0.501483
      6     0.497743
      7     0.488633
      8     0.506613
      9     0.501002
      10    0.497842
dtype: float64

Index levels: [None, None]

Plotting with Custom X-Tick Labels

Create the plot and customize x-axis ticks to show all year-month combinations ?

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

plt.rcParams["figure.figsize"] = [12, 6]
plt.rcParams["figure.autolayout"] = True

idx = pd.date_range("2020-01-01", periods=1000)
val = np.random.rand(1000)
s = pd.Series(val, idx)

grouped_data = s.groupby([s.index.year, s.index.month]).mean()

# Create the plot
ax = grouped_data.plot(kind='line', marker='o', linewidth=2, markersize=4)

# Set custom x-ticks and labels
ax.set_xticks(range(len(grouped_data)))
ax.set_xticklabels(["%s-%02d" % item for item in grouped_data.index.tolist()], 
                   rotation=45, ha='right')

# Add labels and title
ax.set_xlabel('Year-Month')
ax.set_ylabel('Average Value')
ax.set_title('Multi-Index DataFrame Plot with All X-Ticks')
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()
[Plot displays a line chart with x-axis showing all year-month combinations like 2020-01, 2020-02, etc., rotated at 45 degrees for better readability]

Key Components Explained

Component Purpose Parameters
set_xticks() Set tick positions range(len(data))
set_xticklabels() Custom tick labels rotation, ha (horizontal alignment)
groupby() Create multi-index Multiple grouping levels

Alternative Approach Using reset_index()

You can also flatten the multi-index before plotting ?

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

plt.rcParams["figure.figsize"] = [12, 6]

idx = pd.date_range("2020-01-01", periods=500)
val = np.random.rand(500)
s = pd.Series(val, idx)

grouped_data = s.groupby([s.index.year, s.index.month]).mean()

# Reset index to flatten multi-index
df_flat = grouped_data.reset_index()
df_flat['year_month'] = df_flat['level_0'].astype(str) + '-' + df_flat['level_1'].astype(str).str.zfill(2)

# Plot using the flattened data
plt.plot(df_flat['year_month'], df_flat[0], marker='o', linewidth=2)
plt.xticks(rotation=45, ha='right')
plt.xlabel('Year-Month')
plt.ylabel('Average Value')
plt.title('Flattened Multi-Index Plot')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
[Plot displays the same data but using a flattened approach with cleaner code structure]

Conclusion

Use set_xticks() and set_xticklabels() to display all x-axis labels for multi-index DataFrames. For better readability, rotate labels and use proper spacing. The reset_index() approach offers an alternative method for simpler plotting workflows.

Updated on: 2026-03-25T22:06:57+05:30

5K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements