pandas, matplotlib, use dataframe index as axis tick labels

matplotlib, pandas, python

Solution

As a general solution, I have found the following method to be an easy way to bring a Pandas datetime64 index into a matplotlib axis label.

First, create a new series by converting the pandas datetime64 index to a Python datetime.datetime class.

`new_series = your_pandas_dataframe.index.to_pydatetime()`

Now you have all the functionality of matplotlib.dates. Before plotting, import matplotlib.dates as mdates and declare the following variables:

years = mdates.YearLocator()   
months = mdates.MonthLocator()  
days = mdates.DayLocator()
hours = mdates.HourLocator(12) #if you want ticks every 12 hrs, you can pass 12 to this function
minutes = mdates.MinuteLocator() 
daysFmt = mdates.DateFormatter('%m/%d') #or whatever format you want

Now, make your plots, using the new_series as the x-axis:

fig1 = plt.figure()
ax = fig1.add_subplot(111)
ax.plot(new_series,your_pandas_dataframe)

You can use the mdates functions declared above to tweak the labels and ticks to your pleasing, such as:

ax.xaxis.set_major_locator(days)
ax.xaxis.set_major_formatter(daysFmt)
ax.xaxis.set_minor_locator(hours)

Problem

I am using matplotlib's `imshow()` function to show a `pandas.DataFrame`. I would like the labels and ticks for both x and y axes to be drawn from the DataFrame.index and DataFrame.columns lists, but I can't figure out how to do it. Assuming that `data` is a `pandas.DataFrame`: ``` >>> print data <class 'pandas.core.frame.DataFrame'> Index: 201 entries, 1901 to 2101 Data columns: jan 201 non-null values feb 201 non-null values mar 201 non-null values apr 201 non-null values may 201 non-null values jun 201 non-null values jul 201 non-null values aug 201 non-null values sep 201 non-null values oct 201 non-null values nov 201 non-null values dec 201 non-null values ``` When I do this: ``` ax1 = fig.add_subplot(131, xticklabels=data.columns, yticklabels=data.index) ax1.set_title("A") ax1.tick_params(axis='both', direction='out') im1 = ax1.imshow(data, interpolation='nearest', aspect='auto', cmap=cmap ) ``` I end up with nicely spaced tick labels on the y axis of the image, but the labels are 1901-1906 instead of 1901 thru 2101. Likewise, the x axis tick labels are feb-jul instead of jan-dec. If I use ``` ax1 = fig.add_subplot(131) # without specifying tick labels ``` Then I end up with the axis tick labels simply being the underlying ndarray index values (i.e. 0-201 and 0-12). I don't need to modify the spacing or quantity of ticks and labels, I just want the label text to come from the DataFrame index and column lists. Not sure if I am missing something easy or not? Thanks in advance.

Original source