Создание визуализаций временной шкалы с использованием Matplotlib

PythonPythonBeginner
Практиковаться сейчас

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

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

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

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

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

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

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

Получение данных

Для создания временной шкалы нам необходимо получить такие данные, как даты и имена. В этом примере мы будем использовать выпуски Matplotlib и их даты с GitHub. Если по какой-либо причине данные не могут быть получены, мы будем использовать резервные данные в качестве бэкапа. Вот код для получения данных:

from datetime import datetime

import matplotlib.pyplot as plt
import numpy as np

import matplotlib.dates as mdates

try:
    ## Попытка получить список выпусков Matplotlib и их дат
    ## из https://api.github.com/repos/matplotlib/matplotlib/releases
    import json
    import urllib.request

    url = 'https://api.github.com/repos/matplotlib/matplotlib/releases'
    url += '?per_page=100'
    data = json.loads(urllib.request.urlopen(url, timeout=1).read().decode())

    dates = []
    names = []
    for item in data:
        if 'rc' not in item['tag_name'] and 'b' not in item['tag_name']:
            dates.append(item['published_at'].split("T")[0])
            names.append(item['tag_name'])
    ## Преобразовать строки дат (например, 2014-10-18) в datetime
    dates = [datetime.strptime(d, "%Y-%m-%d") for d in dates]

except Exception:
    ## В случае неудачи выше, например, из-за отсутствия подключения к интернету
    ## использовать следующие списки в качестве резервных.
    names = ['v2.2.4', 'v3.0.3', 'v3.0.2', 'v3.0.1', 'v3.0.0', 'v2.2.3',
             'v2.2.2', 'v2.2.1', 'v2.2.0', 'v2.1.2', 'v2.1.1', 'v2.1.0',
             'v2.0.2', 'v2.0.1', 'v2.0.0', 'v1.5.3', 'v1.5.2', 'v1.5.1',
             'v1.5.0', 'v1.4.3', 'v1.4.2', 'v1.4.1', 'v1.4.0']

    dates = ['2019-02-26', '2019-02-26', '2018-11-10', '2018-11-10',
             '2018-09-18', '2018-08-10', '2018-03-17', '2018-03-16',
             '2018-03-06', '2018-01-18', '2017-12-10', '2017-10-07',
             '2017-05-10', '2017-05-02', '2017-01-17', '2016-09-09',
             '2016-07-03', '2016-01-10', '2015-10-29', '2015-02-16',
             '2014-10-26', '2014-10-18', '2014-08-26']

    ## Преобразовать строки дат (например, 2014-10-18) в datetime
    dates = [datetime.strptime(d, "%Y-%m-%d") for d in dates]

Создание стволовой диаграммы

Далее мы создадим стволовую диаграмму с некоторыми вариациями уровней, чтобы отличать даже близкие события. Мы добавим метки на базовой линии для наглядного подчеркивания одномерности временной шкалы. Для каждого события мы добавим текстовую метку с помощью ~.Axes.annotate, которая смещается в точках от конца линии события. Вот код для создания стволовой диаграммы:

## Choose some nice levels
levels = np.tile([-5, 5, -3, 3, -1, 1],
                 int(np.ceil(len(dates)/6)))[:len(dates)]

## Create figure and plot a stem plot with the date
fig, ax = plt.subplots(figsize=(8.8, 4), layout="constrained")
ax.set(title="Matplotlib release dates")

ax.vlines(dates, 0, levels, color="tab:red")  ## The vertical stems.
ax.plot(dates, np.zeros_like(dates), "-o",
        color="k", markerfacecolor="w")  ## Baseline and markers on it.

## annotate lines
for d, l, r in zip(dates, levels, names):
    ax.annotate(r, xy=(d, l),
                xytext=(-3, np.sign(l)*3), textcoords="offset points",
                horizontalalignment="right",
                verticalalignment="bottom" if l > 0 else "top")

Форматирование графика

Теперь мы отформатируем график, добавив метки по осям x и y, настроив основной делитель и форматтер оси x, а также удалив ось y и контуры. Вот код для форматирования графика:

## format x-axis with 4-month intervals
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=4))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
plt.setp(ax.get_xticklabels(), rotation=30, ha="right")

## remove y-axis and spines
ax.yaxis.set_visible(False)
ax.spines[["left", "top", "right"]].set_visible(False)

ax.margins(y=0.1)
plt.show()

Собираем все вместе

Вот окончательный код для создания простой временной шкалы с использованием дат выпуска Matplotlib:

from datetime import datetime

import matplotlib.pyplot as plt
import numpy as np

import matplotlib.dates as mdates

try:
    ## Пытаемся получить список выпусков Matplotlib и их дат
    ## из https://api.github.com/repos/matplotlib/matplotlib/releases
    import json
    import urllib.request

    url = 'https://api.github.com/repos/matplotlib/matplotlib/releases'
    url += '?per_page=100'
    data = json.loads(urllib.request.urlopen(url, timeout=1).read().decode())

    dates = []
    names = []
    for item in data:
        if 'rc' not in item['tag_name'] and 'b' not in item['tag_name']:
            dates.append(item['published_at'].split("T")[0])
            names.append(item['tag_name'])
    ## Преобразуем строки дат (например, 2014-10-18) в datetime
    dates = [datetime.strptime(d, "%Y-%m-%d") for d in dates]

except Exception:
    ## В случае неудачи выше, например, из-за отсутствия подключения к интернету
    ## используем следующие списки в качестве резервных.
    names = ['v2.2.4', 'v3.0.3', 'v3.0.2', 'v3.0.1', 'v3.0.0', 'v2.2.3',
             'v2.2.2', 'v2.2.1', 'v2.2.0', 'v2.1.2', 'v2.1.1', 'v2.1.0',
             'v2.0.2', 'v2.0.1', 'v2.0.0', 'v1.5.3', 'v1.5.2', 'v1.5.1',
             'v1.5.0', 'v1.4.3', 'v1.4.2', 'v1.4.1', 'v1.4.0']

    dates = ['2019-02-26', '2019-02-26', '2018-11-10', '2018-11-10',
             '2018-09-18', '2018-08-10', '2018-03-17', '2018-03-16',
             '2018-03-06', '2018-01-18', '2017-12-10', '2017-10-07',
             '2017-05-10', '2017-05-02', '2017-01-17', '2016-09-09',
             '2016-07-03', '2016-01-10', '2015-10-29', '2015-02-16',
             '2014-10-26', '2014-10-18', '2014-08-26']

    ## Преобразуем строки дат (например, 2014-10-18) в datetime
    dates = [datetime.strptime(d, "%Y-%m-%d") for d in dates]

## Выбираем несколько хороших уровней
levels = np.tile([-5, 5, -3, 3, -1, 1],
                 int(np.ceil(len(dates)/6)))[:len(dates)]

## Создаем фигуру и рисуем стволовую диаграмму с датой
fig, ax = plt.subplots(figsize=(8.8, 4), layout="constrained")
ax.set(title="Matplotlib release dates")

ax.vlines(dates, 0, levels, color="tab:red")  ## Вертикальные стволы.
ax.plot(dates, np.zeros_like(dates), "-o",
        color="k", markerfacecolor="w")  ## Основная линия и метки на ней.

## Аннотируем линии
for d, l, r in zip(dates, levels, names):
    ax.annotate(r, xy=(d, l),
                xytext=(-3, np.sign(l)*3), textcoords="offset points",
                horizontalalignment="right",
                verticalalignment="bottom" if l > 0 else "top")

## Форматируем ось x с интервалами в 4 месяца
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=4))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
plt.setp(ax.get_xticklabels(), rotation=30, ha="right")

## Удаляем ось y и контуры
ax.yaxis.set_visible(False)
ax.spines[["left", "top", "right"]].set_visible(False)

ax.margins(y=0.1)
plt.show()

Резюме

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