1

I am plotting a time series with a date time index. The plot needs to be a particular size for the journal format. Consequently, the sticks are not readable since they span many years.

Here is a data sample

2013-02-10  0.7714492098202259
2013-02-11  0.7709101833765016
2013-02-12  0.7704911332770049
2013-02-13  0.7694975914173087
2013-02-14  0.7692108921323576

The data is a series with a datetime index and spans from 2013 to 2016. I use

data.plot(ax = ax)

to plot the data.

How can I format my xticks to read like '13 instead of 2013?

Demetri Pananos
  • 6,770
  • 9
  • 42
  • 73

2 Answers2

1

It seems there is some incompatibility between pandas and matplotlib formatters/locators when it comes to dates. See e.g. those questions:

I'm not entirely sure why it still works in some cases to use matplotlib formatters and not in others. However because of those issues, the bullet-proof solution is to use matplotlib to plot the graph instead of the pandas plotting function. This allows to use locators and formatters just as seen in the matplotlib example.

Here the solution to the question would look as follows:

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

dates = pd.date_range("2013-01-01", "2017-06-20" )
y = np.cumsum(np.random.normal(size=len(dates)))

s = pd.Series(y, index=dates)

fig, ax = plt.subplots()
ax.plot(s.index, s.values)

ax.xaxis.set_major_locator(mdates.YearLocator())
ax.xaxis.set_minor_locator(mdates.MonthLocator())
yearFmt = mdates.DateFormatter("'%y")
ax.xaxis.set_major_formatter(yearFmt)

plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
0

According to this example, you can do the following

import matplotlib.dates as mdates

yearsFmt = mdates.DateFormatter("'%y")
years = mdates.YearLocator() 
ax = df.plot()
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yearsFmt)

enter image description here

Full work below

Add word value so pd.read_clipboard puts dates into index

value
2013-02-10  0.7714492098202259
2014-02-11  0.7709101833765016
2015-02-12  0.7704911332770049
2016-02-13  0.7694975914173087
2017-02-14  0.7692108921323576

Then read in data and convert index

df = pd.read_clipboard(sep='\s+')
df.index = pd.to_datetime(df.index)
Ted Petrou
  • 59,042
  • 19
  • 131
  • 136