Pandas分类列绘图报错:tuple index out of range求助
IndexError When Plotting Pandas Categorical Data with Matplotlib Axes Hey Jerome! Let's break down why you're hitting that tuple index out of range error when using matplotlib.axes.Axes.plot() directly, and how to fix it.
What's Going Wrong?
When you convert DM_DESC to a categorical type with custom ordering, sales["DM_DESC"].values returns an array of pandas Categorical objects—not simple strings or numbers. Native matplotlib's plot() method doesn't know how to handle this specialized data type under the hood. It tries to parse the data as a multi-dimensional array, which leads to the index error when it can't find the expected shape dimensions.
On the flip side, pandas' built-in plot() method is designed to work seamlessly with pandas data structures (including categoricals). It automatically converts the categorical data into plot-friendly values and sets up the x-axis labels correctly for you.
Solutions to Try
Here are three reliable fixes to get your plot working with the matplotlib axes object:
1. Use Categorical Codes for X-Axis (Most Control)
Extract the underlying integer codes of your categorical data (these correspond to your custom ListDM order), plot with those, then manually set the x-axis labels:
import matplotlib.pyplot as plt import pandas as pd import numpy as np ListDM = [ 'Jan Big Low price', 'CNY 1', 'CNY 2'] f=plt.figure() a=f.add_subplot(111) DonneesBase = pd.DataFrame({ "DM_DESC":["CNY 2","Jan Big Low price","CNY 1"], "YEAR":[2017,2017,2017], "SALES_W_VAT":[2.254691e+09, 2.509911e+09,1.8e+09] }) # Set up ordered categorical DonneesBase["DM_DESC"] = pd.Categorical(DonneesBase["DM_DESC"], ListDM, ordered=True) sales = DonneesBase[DonneesBase["YEAR"] ==2017].groupby(["DM_DESC","YEAR"])["SALES_W_VAT"].sum().reset_index() # Fix: Use categorical codes + manual labels x_codes = sales["DM_DESC"].cat.codes a.plot(x_codes, sales["SALES_W_VAT"].values) # Set x-ticks to match your custom order a.set_xticks(range(len(ListDM))) a.set_xticklabels(ListDM, rotation=45) # Rotate labels for readability plt.tight_layout() # Adjust layout to fit labels plt.show()
2. Pass the Categorical Column Directly (Simpler)
Instead of using .values, pass the categorical column itself to axes.plot(). Recent versions of matplotlib and pandas play nicely together here:
# Replace the failing line with this a.plot(sales["DM_DESC"], sales["SALES_W_VAT"])
3. Plot to Your Axes Using Pandas' plot()
Keep using pandas' reliable plot method, but tell it to draw on your existing axes object with the ax parameter:
# This works and uses your pre-defined axes sales.plot(x="DM_DESC", y="SALES_W_VAT", ax=a)
All three approaches will respect your custom categorical order and avoid the index error. Pick the one that fits your workflow best!
内容的提问来源于stack exchange,提问作者Jerome

