Skip to content

Instantly share code, notes, and snippets.

@Safrone
Last active March 13, 2018 21:18
Show Gist options
  • Save Safrone/41c1d519f6b6222b01e9d8f78e041fb7 to your computer and use it in GitHub Desktop.
Save Safrone/41c1d519f6b6222b01e9d8f78e041fb7 to your computer and use it in GitHub Desktop.
A formatter for dates in matplotlib plots where the output format string changes based on a condition.
from matplotlib import ticker
from matplotlib.dates import DateFormatter, _from_ordinalf
class ConditionalDateFormatter(ticker.Formatter):
def __init__(self, fmt: str, fmt_conditional: str, date_condition: Callable[[datetime], bool], tz=None):
"""
A formatter for dates in matplotlib plots where the output format string changes based on a condition.
Args:
fmt (str): regular format string
fmt_conditional (str): format string for when condition == True
date_condition (Callable[[datetime], bool]): returns True when
fmt_conditional is desired based on the given datetime.
tz (): timezone for formatter.
"""
self.formatter = DateFormatter(fmt, tz)
self.conditional_formatter = DateFormatter(fmt_conditional, tz)
self.date_condition = date_condition
self.tz = tz
def __call__(self, x, pos=0):
dt = _from_ordinalf(x, tz=self.tz)
if self.date_condition(dt):
return self.conditional_formatter.__call__(x, pos)
return self.formatter.__call__(x, pos)
regular_format = '%-I%p'
conditional_format = '%b %-d'
condition = lambda x: x.hour == 0 # aka midnight
formatter = ConditionalDateFormatter(regular_format, conditional_format, condition=condition)
# When used in a plot of datetimes the axis might look like:
# [..., 10PM, 11PM, Mar 13, 1AM, 2AM, 3AM, ...]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment