Matplotlib: Показать выбранные метки даты на оси x - PullRequest
2 голосов
/ 11 мая 2019

На моем графике matplotlib ось даты и времени в настоящее время отформатирована как

ax.xaxis.set_major_locator(dt.MonthLocator())
ax.xaxis.set_major_formatter(dt.DateFormatter('%d %b'))
ax.xaxis.set_minor_locator(dt.DayLocator())
ax.xaxis.set_minor_formatter(ticker.NullFormatter())

Current graph

Я хочу иметь метки для незначительных тиков, нотолько некоторые значения.Ожидаемый:

enter image description here

Что minor_formatter мне следует использовать?

1 Ответ

2 голосов
/ 25 июня 2019

Незначительные тики должны иметь выборочные метки - показывать только в дни с конкретными значениями. Чтобы выбрать даты, я придумал свой собственный Formatter, который принимает предикат (функция, возвращающая true / false при передаче datetime), который оборачивает DateFormatter для фактического форматирования строки. Это позволяет использовать более общий подход (например, вы можете показывать только выходные)

import matplotlib.dates as dt
import matplotlib.ticker as ticker

class SelectiveDateFormatter(ticker.Formatter):

    def __init__(self, predicate, date_formatter, tz=None):
        if tz is None:
            tz = dt._get_rc_timezone()
        self.predicate = predicate
        self.dateFormatter = date_formatter
        self.tz = tz

    def __call__(self, x, pos=0):
        if x == 0:
            raise ValueError('DateFormatter found a value of x=0, which is '
                         'an illegal date; this usually occurs because '
                         'you have not informed the axis that it is '
                         'plotting dates, e.g., with ax.xaxis_date()')
        current_date = dt.num2date(x, self.tz)
        should_print = self.predicate(current_date)
        if should_print:
            return self.dateFormatter(x, pos)
        else:
            return ""

    def set_tzinfo(self, tz):
        self.tz = tz

Вы можете использовать это, чтобы достичь моего примера:

predicate = lambda d: d.day % 10 == 0
format = dt.DateFormatter('%d')
selective_fmt = SelectiveDateFormatter(predicate, format)
ax.xaxis.set_minor_formatter(selective_fmt)

Или для показа только выходных:

predicate = lambda d: d.weekday() >= 5
...
...