@@ -58,7 +58,7 @@ def matplotlib_locator_formatter(timedelta, span=1):
5858 Compute appropriate locator and formatter for renderers
5959 based on matplotlib, depending on designated time span.
6060 """
61- from matplotlib .dates import date_ticker_factory , DateFormatter
61+ from matplotlib .dates import DateFormatter
6262 locator , formatter = date_ticker_factory (span )
6363
6464 # http://pandas.pydata.org/pandas-docs/stable/timedeltas.html
@@ -93,6 +93,59 @@ def matplotlib_locator_formatter(timedelta, span=1):
9393 return locator , formatter
9494
9595
96+ def date_ticker_factory (span , tz = None , numticks = 5 ):
97+ """
98+ Create a date locator with *numticks* (approx) and a date formatter
99+ for *span* in days. Return value is (locator, formatter).
100+
101+ `date_ticker_factory` was removed from matplotlib in version 3.8.0.
102+ The recommendation is to use AutoDateLocator and AutoDateFormatter,
103+ or to vendorize the code.
104+
105+ https://matplotlib.org/stable/api/prev_api_changes/api_changes_3.8.0.html#date-ticker-factory-removed
106+ https://github.com/matplotlib/matplotlib/blob/v3.7.5/lib/matplotlib/dates.py#L1784C1-L1823C30
107+ """
108+ import math
109+ from matplotlib .dates import (
110+ DAYS_PER_MONTH , DAYS_PER_WEEK , DAYS_PER_YEAR , HOURS_PER_DAY , MINUTES_PER_DAY ,
111+ DateFormatter , DayLocator , HourLocator , MinuteLocator , MonthLocator , WeekdayLocator , YearLocator )
112+
113+ if span == 0 :
114+ span = 1 / HOURS_PER_DAY
115+
116+ mins = span * MINUTES_PER_DAY
117+ hrs = span * HOURS_PER_DAY
118+ days = span
119+ wks = span / DAYS_PER_WEEK
120+ months = span / DAYS_PER_MONTH # Approx
121+ years = span / DAYS_PER_YEAR # Approx
122+
123+ if years > numticks :
124+ locator = YearLocator (int (years / numticks ), tz = tz ) # define
125+ fmt = '%Y'
126+ elif months > numticks :
127+ locator = MonthLocator (tz = tz )
128+ fmt = '%b %Y'
129+ elif wks > numticks :
130+ locator = WeekdayLocator (tz = tz )
131+ fmt = '%a, %b %d'
132+ elif days > numticks :
133+ locator = DayLocator (interval = math .ceil (days / numticks ), tz = tz )
134+ fmt = '%b %d'
135+ elif hrs > numticks :
136+ locator = HourLocator (interval = math .ceil (hrs / numticks ), tz = tz )
137+ fmt = '%H:%M\n %b %d'
138+ elif mins > numticks :
139+ locator = MinuteLocator (interval = math .ceil (mins / numticks ), tz = tz )
140+ fmt = '%H:%M:%S'
141+ else :
142+ locator = MinuteLocator (tz = tz )
143+ fmt = '%H:%M:%S'
144+
145+ formatter = DateFormatter (fmt , tz = tz )
146+ return locator , formatter
147+
148+
96149def make_timezone_unaware (df ):
97150 # Please ensure that datetimes are timezone unaware before writing to Excel.
98151 # https://github.com/pandas-dev/pandas/pull/27129
0 commit comments