Форматтер меток дат Matplotlib

Beginner

This tutorial is from open-source community. Access the source code

Введение

~.dates.ConciseDateFormatter - полезный инструмент для форматирования меток дат при работе с Matplotlib. В этом практическом занятии вы научитесь использовать этот форматтер для улучшения строк, выбранных для меток делений оси времени, и для минимизации количества строк, используемых в этих метках делений.

Советы по работе с ВМ

После запуска ВМ нажмите в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.

Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook загрузится полностью. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.

Если вы сталкиваетесь с проблемами во время обучения, не стесняйтесь обращаться к Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.

Стандартный форматтер

Начнем с рассмотрения стандартного форматтера и его подробного вывода. Построим график данных в течение времени и посмотрим, как стандартный форматтер отображает дату и время.

import datetime
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates

## create time data
base = datetime.datetime(2005, 2, 1)
dates = [base + datetime.timedelta(hours=(2 * i)) for i in range(732)]
N = len(dates)
np.random.seed(19680801)
y = np.cumsum(np.random.randn(N))

## plot data
fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))
lims = [(np.datetime64('2005-02'), np.datetime64('2005-04')),
        (np.datetime64('2005-02-03'), np.datetime64('2005-02-15')),
        (np.datetime64('2005-02-03 11:00'), np.datetime64('2005-02-04 13:20'))]
for nn, ax in enumerate(axs):
    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
    ## rotate labels...
    for label in ax.get_xticklabels():
        label.set_rotation(40)
        label.set_horizontalalignment('right')
axs[0].set_title('Default Date Formatter')
plt.show()

Концизный форматтер дат

Далее мы исследуем ~.dates.ConciseDateFormatter и его вывод. Создадим новый график с использованием концизного форматтера дат и посмотрим, как он отличается от стандартного форматтера.

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))
for nn, ax in enumerate(axs):
    locator = mdates.AutoDateLocator(minticks=3, maxticks=7)
    formatter = mdates.ConciseDateFormatter(locator)
    ax.xaxis.set_major_locator(locator)
    ax.xaxis.set_major_formatter(formatter)

    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')
plt.show()

Регистрация конвертера

Если все вызовы к осям с датами должны быть выполнены с использованием этого конвертера, наиболее удобным способом будет использовать реестр единиц измерения. Мы регистрируем конвертер в реестре единиц измерения и строим график данных с использованием концизного форматтера дат.

import datetime
import matplotlib.units as munits

converter = mdates.ConciseDateConverter()
munits.registry[np.datetime64] = converter
munits.registry[datetime.date] = converter
munits.registry[datetime.datetime] = converter

fig, axs = plt.subplots(3, 1, figsize=(6, 6), layout='constrained')
for nn, ax in enumerate(axs):
    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')
plt.show()

Локализация форматов дат

Форматы дат можно локализовать, если стандартные форматы не подходят, путём манипуляции с одним из трёх списков строк. Мы модифицируем метки, чтобы они были в формате "день месяц год", а не в ISO формате "год месяц день".

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))

for nn, ax in enumerate(axs):
    locator = mdates.AutoDateLocator()
    formatter = mdates.ConciseDateFormatter(locator)
    formatter.formats = ['%y',  ## метки делений в основном годы
                         '%b',       ## метки делений в основном месяцы
                         '%d',       ## метки делений в основном дни
                         '%H:%M',    ## часы
                         '%H:%M',    ## минуты
                         '%S.%f', ]  ## секунды
    ## эти в основном просто предыдущий уровень...
    formatter.zero_formats = [''] + formatter.formats[:-1]
    #...за исключением меток делений, которые в основном часы, тогда лучше иметь
    ## день-месяц:
    formatter.zero_formats[3] = '%d-%b'

    formatter.offset_formats = ['',
                                '%Y',
                                '%b %Y',
                                '%d %b %Y',
                                '%d %b %Y',
                                '%d %b %Y %H:%M', ]
    ax.xaxis.set_major_locator(locator)
    ax.xaxis.set_major_formatter(formatter)

    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter')
plt.show()

Регистрация конвертера с локализацией

Мы также можем зарегистрировать конвертер с локализацией, передав именованные аргументы в ~.dates.ConciseDateConverter и зарегистрировав типы данных, которые вы будете использовать, в реестре единиц измерения.

import datetime

formats = ['%y',          ## метки делений в основном годы
           '%b',     ## метки делений в основном месяцы
           '%d',     ## метки делений в основном дни
           '%H:%M',  ## часы
           '%H:%M',  ## минуты
           '%S.%f', ]  ## секунды
## эти могут быть такими же, за исключением смещения на один уровень....
zero_formats = [''] + formats[:-1]
#...за исключением меток делений, которые в основном часы, тогда приятно иметь день-месяц
zero_formats[3] = '%d-%b'
offset_formats = ['',
                  '%Y',
                  '%b %Y',
                  '%d %b %Y',
                  '%d %b %Y',
                  '%d %b %Y %H:%M', ]

converter = mdates.ConciseDateConverter(
    formats=formats, zero_formats=zero_formats, offset_formats=offset_formats)

munits.registry[np.datetime64] = converter
munits.registry[datetime.date] = converter
munits.registry[datetime.datetime] = converter

fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(6, 6))
for nn, ax in enumerate(axs):
    ax.plot(dates, y)
    ax.set_xlim(lims[nn])
axs[0].set_title('Concise Date Formatter registered non-default')
plt.show()

Резюме

В этом практическом занятии вы узнали, как использовать ~.dates.ConciseDateFormatter для форматирования меток дат при работе с Matplotlib. Также вы узнали, как локализовать форматы дат и регистрировать конвертеры, чтобы сделать процесс более удобным.