使用DatetimeIndex的Pandas绘图X轴日期格式设置问题
Hey Andrew, let's break down why your date formatting isn't working and get your X-axis looking exactly how you want it.
Why Your Current Approach Fails
When you use Pandas to plot a bar chart with a DatetimeIndex, Pandas converts those dates into categorical labels under the hood. That means the X-axis isn't actually a date axis—it's just a sequence of integer positions (0, 1, 2, ...) with date strings attached as labels.
This is why your mdates code throws that error: it tries to interpret those integer positions as valid dates, which doesn't make sense. The rcParams setting also does nothing here, because it only applies to actual date axes, not categorical ones.
Solution 1: Directly Format Tick Labels (Simplest Fix)
Since your data is already monthly (with Freq: M), the easiest way is to reformat the existing tick labels using your DatetimeIndex's built-in strftime() method. Here's how to adjust your code:
import matplotlib.pyplot as plt grouped_dataframe_unstacked = grouped_dataframe.unstack() fig, ax = plt.subplots(figsize=(6, 10)) grouped_dataframe_unstacked.plot(kind='bar', ax=ax, stacked=True) # Format labels to show only abbreviated month (e.g., "Feb", "Mar") ax.set_xticklabels(grouped_dataframe_unstacked.index.strftime('%b')) # Use '%b %Y' instead if you want "Feb 2020" style labels plt.xticks(rotation=45) # Rotate labels to avoid overlap plt.show()
Solution 2: Convert to a Proper Date Axis (More Flexible)
If you want to use matplotlib's date tools (for dynamic spacing or other advanced features later), you can manually convert your index to matplotlib-compatible date values and reconfigure the axis:
import matplotlib.pyplot as plt import matplotlib.dates as mdates grouped_dataframe_unstacked = grouped_dataframe.unstack() fig, ax = plt.subplots(figsize=(6, 10)) grouped_dataframe_unstacked.plot(kind='bar', ax=ax, stacked=True) # Convert DatetimeIndex to matplotlib-friendly date objects x_dates = grouped_dataframe_unstacked.index.to_pydatetime() # Align ticks with your data points ax.set_xticks(range(len(x_dates))) ax.set_xticklabels(mdates.num2date(x_dates)) # Apply the month-only formatter ax.xaxis.set_major_formatter(mdates.DateFormatter('%b')) plt.xticks(rotation=45) plt.show()
Quick Tips
- Use
%Binstead of%bif you want full month names (e.g., "February" instead of "Feb"). - Rotating tick labels prevents overlap, which is a common issue with date-based bar charts.
- For your monthly frequency data, Solution 1 is the most straightforward—you don't need the extra complexity of a full date axis here.
内容的提问来源于stack exchange,提问作者Andrew Holway

