2

I am often working interactively in an ipython shell or ipython notebook. Say, I had a pandas.DataFrame with a DatetimeIndex, like this:

idx = pd.date_range("12:00", periods=400000, freq="S")
df = pd.DataFrame({"temp":np.random.normal(size=len(idx))}, index=idx)

In order to plot it, I can simply do:

plt.plot(df.temp, '.')

enter image description here

As one can see, neither do I have to specify the x-axis data, as it is nicely inferred from the DataFrame, nor do I have to specify that I actually want the x-axis to be date based. (Gone are the times of plt.plot_date) That's awesome!

But the x-axis looks ugly in two ways:

  • the labels overlap and are hard to read.
  • the labels show hours instead of dates.

One can almost repair this problem like, e.g. like this:

plt.plot(df.temp, '.')
import matplotlib.dates as mdates
plt.gca().xaxis.set_major_formatter(
    mdates.DateFormatter('%d-%m-%Y %H:%M:%S'))
plt.gcf().autofmt_xdate()

As one can see in the resulting plot, the leftmost date label is clipped. leftmost date label is clipped

So by increasing the code size by 300% one can almost get a nice plot.


Now to my question:

I can for my life not remember these 2..3 lines, which I'll have to type in always, when making date based plots. It makes the interface feel clumsy and slow. I always have to google for the solution ...

Can I setup matplotlib in a way, that it kind of remembers what my personal defaults are with regard to date based plotting?

I guess, I could actually hack into the plot function. But maybe there is a way using these matplotlib.rc_params, which I wasn't able to find.

As I said above, plt.plot is going a long way to actually guess what I want. It guesses the x-axis data to be the index of the DataFrame .. and it guesses it should actually plot a date based x-axis instead of a the numerical representation of the dates. How can I add something to this?

I'm thinking of maybe even give it some hints like:

plt.plot(df.temp, '.', date_fmt='%d-%m-%Y %H:%M:%S')

or

plt.plot(df.temp, '.', autofmt_xdate=True)
Dominik Neise
  • 1,179
  • 1
  • 10
  • 23

1 Answers1

2

You can use DateFormatter:

import matplotlib.dates as mdates

fig, ax = plt.subplots(figsize=(8,5))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y %H:%M:%S'))
#rotates the tick labels automatically
fig.autofmt_xdate()

ax.plot(df["T"], '.')

plt.show()

graph

jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
  • While the code certainly improves the result *for now*. The answer is not hitting the spot of my question. I will rephrase the question now to hopefully make it more clear. – Dominik Neise Aug 09 '16 at 05:11
  • Thank you. Please explain `sane axis labeling`, can you add some sample with desired output? – jezrael Aug 09 '16 at 05:13
  • You got the part about `sane axis labeling` just right. But I wasn't heading for a one-time answer, but I'm looking for an answer solving it once for all time. – Dominik Neise Aug 09 '16 at 05:58
  • Hmmm, hard question, bcause I am not matplotlib guru. I do some research and you can check [this](http://stackoverflow.com/a/13521621/2901002) or [this](http://stackoverflow.com/a/11068038/2901002). – jezrael Aug 09 '16 at 06:27