JC_CL
JC_CL

Reputation: 2618

Why do my year-ticks with pandas.plot always show years ending in 9?

I'm using pandas inbuilt .plot command to plot stuff some long-ish time series.

But my date ticks always are years ending in 9 by default.screenshot of plot

Why is that so, and how can I change it? Years ending in 0 would look much nicer.

Trying to set the window of the axis with plt.xlim('1966', '2013') or something like this also does not do anything about plots fetish for years ending in 9 (and 4, if you "zoom in", as shown above).

It also does not seem to have anything to do with the start and end of the dates in the source dataframe.

here is a minimal, empty, example:

dfdates = pd.date_range('01/01/1942', '01/01/2018', freq = 'MS')
dfzeros = np.zeros((len(dfdates)))
header_test = pd.MultiIndex.from_product([['zero'],['zero'], ['zero'], ['zero'], ['zero'], ['zero']], names = ['stuff1', 'stuff2', 'stuff3', 'stuff4', 'stuff5', 'stuff6'])
Big_df = pd.DataFrame(dfzeros, index = dfdates, columns = header_test)

Big_df.plot()
plt.show()

…And this results in this for me: empty test plot

And I cant change the 9's at the end, no matter if I set a window with plt.xlim or if I change the start and end years, months or days of dfdates, so it's not something easy as "start of the dataframe + 10 years" or similar, and my large header also does not affect those.

I probably could set more sensible ticks per hand, but I'd rather know why it is so hell bent on using years with 9 at the end.

EDIT So here is what happens when I plot, using @lanery's answer: plot with double ticks Note the double ticks in the area of the plot where I specified the custom ticks (starting at 1965). All my dataframes start at 1940, but many are empty, to a certain point where I start to get data, depending on the dataset in question. I can cut this off with plt.xlim('1965','2015'), but I left it in in this plot, to show whats happening.

Upvotes: 1

Views: 1761

Answers (1)

lanery
lanery

Reputation: 5364

Since setting plt.xlim with datetime objects, something like

plt.xlim(pd.datetime(1966, 1, 1), pd.datetime(2013, 1, 1))

didn't do the trick, I think the best course of action is to set custom xticks and xticklabels. This can be done by like so

dates = pd.date_range('1990', '2015', freq=pd.DateOffset(years=5))
ax.xaxis.set_ticks(dates)
ax.xaxis.set_ticklabels(dates.strftime('%Y'))

A full example with some random data:

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

np.random.seed(17)
years = pd.date_range(pd.datetime(1990, 1, 1), pd.datetime(2015, 1, 1), freq='MS')
random_data = np.asarray(np.split(np.cumsum(np.random.randn(years.size*3)), 3)).T
df = pd.DataFrame(random_data, columns=['A', 'B', 'C'], index=years)

# all of the relevant plotting and xtick formatting
fig = plt.figure()
ax = fig.add_subplot(111)

df.plot(ax=ax)

# select range of years for the x-axis as well as major tick spacing
dates = pd.date_range('1990', '2015', freq=pd.DateOffset(years=5))
ax.xaxis.set_ticks(dates)
ax.xaxis.set_ticklabels(dates.strftime('%Y'))
# dates.strftime('%Y') = (['1990', '1995',...,'2010', '2015'])

ax.grid()

enter image description here

Upvotes: 1

Related Questions