Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pandas, matplotlib, use dataframe index as axis tick labels

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.

like image 244
tbc Avatar asked Jul 20 '12 21:07

tbc


1 Answers

I believe the issue has to do with specifying the tick labels for existing ticks. By default, there are fewer ticks than labels so only the first few labels are used. The following should work by first setting the number of ticks.

ax1 = fig.add_subplot(131)
ax1.set_title("A")
ax1.tick_params(axis='both', direction='out')
ax1.set_xticks(range(len(data.columns)))
ax1.set_xticklabels(data.columns)
ax1.set_yticks(range(len(data.index)))
ax1.set_yticklabels(data.index)
im1 = ax1.imshow(data, interpolation='nearest', aspect='auto', cmap=cmap)

This produces a tick for every year on the y-axis, so you might want to use a subset of the index values.

like image 133
zarthur Avatar answered Sep 18 '22 13:09

zarthur