29886

Pandas auto datetime format in matplotlib

Question:

I frequently plot multiple timeseries data from different sources on a single plot, some of which require using matplotlib. When formatting the x-axis, I use matplotlib's autofmt_xdate(), but I much prefer the auto formatting of pandas. I'm aware I can manually set the format using set_major_formatter(), but the plots I create vary from years, to days in total range, so I would need to adjust the formatting based on each plot. Is there a way to set matplotlib to auto format the x-axis with dates similar to pandas?

I also use interactive plotting, and when using pandas df.plot() the x-axis updates when zooming to the respective ranges as shown below, which I would also like to achieve using matplotlib:

<a href="https://i.stack.imgur.com/DOKk6.png" rel="nofollow"><img alt="pandas format month " class="b-lazy" data-src="https://i.stack.imgur.com/DOKk6.png" data-original="https://i.stack.imgur.com/DOKk6.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a> <a href="https://i.stack.imgur.com/YsnDF.png" rel="nofollow"><img alt="pandas format day" class="b-lazy" data-src="https://i.stack.imgur.com/YsnDF.png" data-original="https://i.stack.imgur.com/YsnDF.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a> <a href="https://i.stack.imgur.com/u1xOw.png" rel="nofollow"><img alt="pandas format inter-day" class="b-lazy" data-src="https://i.stack.imgur.com/u1xOw.png" data-original="https://i.stack.imgur.com/u1xOw.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

Versions:

Python: 3.7.1 Pandas: 0.23.3 Matplotlib: 2.2.2

<strong>Desired Format:</strong>

import pandas as pd import numpy as np import matplotlib.pyplot as plt ix = pd.date_range('1/1/2017', '11/1/2018', freq='D') vals = np.random.randn(len(ix)) df = pd.DataFrame({'Values': vals}, index=ix) fig, ax = plt.subplots(1, 1, figsize=[8,6]) df.plot(ax=ax, lw=1) plt.show()

<a href="https://i.stack.imgur.com/2jALF.png" rel="nofollow"><img alt="desired pandas format" class="b-lazy" data-src="https://i.stack.imgur.com/2jALF.png" data-original="https://i.stack.imgur.com/2jALF.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

<strong>Current Format:</strong>

fig, ax = plt.subplots(1, 1, figsize=[8,6]) ax.plot(df, lw=1) fig.autofmt_xdate() plt.show()

<a href="https://i.stack.imgur.com/piOi7.png" rel="nofollow"><img alt="Current matplotlib format" class="b-lazy" data-src="https://i.stack.imgur.com/piOi7.png" data-original="https://i.stack.imgur.com/piOi7.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

Answer1:

An option to show the years in a second row is to use the major and minor ticklabels.

import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.dates import MonthLocator, YearLocator, DateFormatter ix = pd.date_range('1/1/2017', '11/1/2018', freq='D') vals = np.random.randn(len(ix)) s = pd.DataFrame({'Values': vals}, index=ix) fig, ax = plt.subplots(figsize=[8,6]) ax.plot(s, lw=1) ax.xaxis.set_major_locator(YearLocator()) ax.xaxis.set_major_formatter(DateFormatter("\n%Y")) ax.xaxis.set_minor_locator(MonthLocator((1,4,7,10))) ax.xaxis.set_minor_formatter(DateFormatter("%b")) plt.show()

If you need the minor ticks for something else, the following would format the major ticks alone - with the same result. Here you would use a FuncFormatter to determine the format depending on the month.

import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.dates import MonthLocator, DateFormatter from matplotlib.ticker import FuncFormatter ix = pd.date_range('1/1/2017', '11/1/2018', freq='D') vals = np.random.randn(len(ix)) s = pd.DataFrame({'Values': vals}, index=ix) fig, ax = plt.subplots(figsize=[8,6]) ax.plot(s, lw=1) monthfmt = DateFormatter("%b") yearfmt = DateFormatter("%Y") def combinedfmt(x,pos): string = monthfmt(x) if string == "Jan": string += "\n" + yearfmt(x) return string ax.xaxis.set_major_locator(MonthLocator((1,4,7,10))) ax.xaxis.set_major_formatter(FuncFormatter(combinedfmt)) plt.show()

The result is in both cases the same:

<a href="https://i.stack.imgur.com/cka0u.png" rel="nofollow"><img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/cka0u.png" data-original="https://i.stack.imgur.com/cka0u.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

Recommend

  • How to allow zooming of UIWebView (tried everything)
  • Prevent scrolling outside map area on google map
  • How to correct mouse event in Highcharts
  • OpenLayers: destroyed features reappear after zooming in or out
  • Postgresql regexp_replace
  • Force ggplot legend to show all categories when no values are present [duplicate]
  • Range Multiplication VB.NET (What is wrong with this code?)
  • Get Quarters StartDate and EndDate from Year
  • MS SQL Server 2008 :Getting start date and end date of the week to next 8 weeks
  • how to auto center objects in a form in access 2007?
  • Aggregating two data frame columns without any existing pattern logic
  • Representing intervals or ranges? [closed]
  • Install different versions of nuget packages inside one solution file with two projects
  • Jhipster: How to create relationships with User entity using supplied tools?
  • data.table replicate rows after join?
  • Can I use worksheet_change for a specific column only?
  • iOS 6 dateFromString returns wrong date
  • goJS dropdown remove items
  • How do you keep a running instance for Google App Engine
  • Manually Timing out a C# Thread
  • my tic-tac-toe program in matlab does not work [closed]
  • EntLib Way to Bind “Null” Value to Parameter
  • jQuery - resize an elements height to match window without refreshing, on window resize
  • How to create two column output from a single column
  • Jenkins Grails plugin does not list lastest versions of Grails
  • How can I get the choice “H2” back in the H2 consol?
  • Approximate Order-Preserving Huffman Code
  • Django model inheritance, filtering models
  • Selenium to click on a javascript button corresponding to a text
  • Breaking out column by groups in Pandas
  • Magento Fatal error: Maximum execution error solution, on WAMP
  • Use of this Javascript
  • C++ Partial template specialization - design simplification
  • R - Combining Columns to String Based on Logical Match
  • Is possible to count alias result on mysql
  • How to get next/previous record number?
  • Python: how to group similar lists together in a list of lists?
  • Benchmarking RAM performance - UWP and C#
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • reshape alternating columns in less time and using less memory