Image

Объяснение визуализации данных (часть 5): визуализация временных рядов данных в Python (Matplotlib, Plotly и Altair)

Объяснение визуализации временных рядов, включая подробные примеры кода в Matplotlib, Plotly и Altair.

Делиться

c942bf7480f9be229e20b79a9ad04c0d

Это пятая статья из моей серии, посвящённой визуализации данных. См. также:

  • Часть 1: «Визуализация данных: что это такое и почему это важно»
  • Часть 2: «Визуализация данных: введение в визуальные переменные».
  • Часть 3: «Визуализация данных: роль цвета».
  • Часть 4: «Визуализация данных: обзор основ Python».

Пришло время приступить к созданию собственных визуализаций данных. В этой статье я подробно расскажу о процессе визуализации временных рядов в Python. Если вы не читали предыдущие статьи из моей серии, посвящённой визуализации данных, настоятельно рекомендую прочитать хотя бы предыдущую статью для ознакомления с Python.

В курсе написания визуализаций на Python я сосредоточусь на трёх пакетах Python: Matplotlib, Plotly и Altair. Один из подходов к их изучению может включать написание одной-двух статей на каждый пакет, каждая из которых будет подробно рассматривать выбранный пакет. Хотя это и обоснованный подход, основное внимание в моей серии уделяется не какой-либо конкретной библиотеке, а самому процессу визуализации данных. Эти пакеты — всего лишь инструменты, средства достижения цели.

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

Для начала: определение временных рядов данных.

Что такое временные ряды данных?

Формально временные ряды данных включают в себя переменную, являющуюся функцией времени. Проще говоря, это просто данные, которые меняются со временем.

Например, цена акций публичной компании за последние десять лет — это временной ряд. Если вы предпочитаете более научный пример, рассмотрим погоду. График, отображающий ежедневную температуру в вашем любимом городе в течение года, — это график, отображающий временной ряд.

Данные временных рядов являются отличной отправной точкой для визуализации данных по нескольким причинам:

  • Это чрезвычайно распространённый и полезный тип данных. Значительная часть информации зависит от времени, и её понимание даёт ценное представление о предмете интереса в будущем.
  • Существуют проверенные и надёжные методы эффективной визуализации временных рядов данных, как вы увидите ниже. Освойте их, и вы будете в отличной форме.
  • По сравнению с некоторыми другими типами данных, визуализация временных рядов достаточно интуитивно понятна человеку и соответствует нашему восприятию времени. Это позволяет сосредоточиться на базовых элементах проектирования визуализации на начальном этапе, не увязая в попытках разобраться в очень сложных данных.

Давайте начнем с рассмотрения различных методов визуализации на концептуальном уровне.

Как визуализируются данные временных рядов?

Стандартом визуализации временных рядов является знаменитая линейная диаграмма:

34cf102e66b69dfb25a2d6063cb0f695

На этой диаграмме время обычно откладывается по оси X, а переменная, изменяющаяся со временем, — по оси Y. Это создаёт впечатление, что картина «движется вперёд», что соответствует линейному восприятию времени человеком.

Хотя линейный график является стандартом, существуют и другие, связанные с ним возможности.

Многолинейная диаграмма

Этот подход является прямым продолжением одинарной линейной диаграммы и отображает несколько связанных временных рядов на одном графике, что позволяет проводить сравнение между группами или категориями (например, продажи по регионам):

b250f3596e574076ceaa76a966af4f1d

Диаграмма площади

Функционально диаграмма с областями почти такая же, как и линейная диаграмма, но область под линией заполнена. Это подчеркивает величину изменений:

cdc2c03eb036cf7c02f12d8dafc23deb

Диаграмма с областями и штабелированием

Технически, стопочная диаграмма с областями является аналогом многолинейной диаграммы, но её немного сложнее читать. В частности, итоговый показатель является кумулятивным, а базовая линия для каждой стопочной линии начинается с линии, расположенной ниже. Например, в 2023 году на диаграмме ниже «Возраст 25–64» соответствует примерно 4 миллиардам человек, поскольку мы начинаем отсчёт там, где заканчивается «Возраст 15–24».

f7b260394733bbf4f97e791b6555bb57

Столбчатая диаграмма (вертикальная или горизонтальная)

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

fee6d658a414189f7f7ab178c020cdd3

Теперь приступим к непосредственному созданию визуализаций. В каждом из примеров ниже я подробно разберу код в специальной библиотеке визуализации для построения линейных и площадных диаграмм. Я прикрепил ссылки на данные и рекомендую вам следовать инструкциям. Чтобы усвоить эти методы, вам необходимо попрактиковаться в их применении самостоятельно.

Кодирование визуализаций временных рядов в Matplotlib

import pandas as pd import matplotlib.pyplot as plt # Загрузка данных df = pd.read_csv('sales_data.csv') df['Дата'] = pd.to_datetime(df['Дата']) # Пример 1: Простая линейная диаграмма fig1, ax1 = plt.subplots(figsize=(10, 6)) ax1.plot(df['Дата'], df['Продажи продукта A'], linewidth=2) ax1.set_xlabel('Дата') ax1.set_ylabel('Продажи') ax1.set_title('Продажи продукта A с течением времени') ax1.grid(True, alpha=0.3) plt.tight_layout() # Отображение с помощью: fig1 # Пример 2: Многолинейная диаграмма fig2, ax2 = plt.subplots(figsize=(10, 6)) ax2.plot(df['Дата'], df['Продажи продукта A'], label='Продукт A', ширина линии=2) ax2.plot(df['Дата'], df['Продажи продукта B'], label='Продукт B', ширина линии=2) ax2.plot(df['Дата'], df['Продажи продукта C'], label='Продукт C', ширина линии=2) ax2.set_xlabel('Дата') ax2.set_ylabel('Продажи') ax2.set_title('Сравнение продаж — Все продукты') ax2.legend() ax2.grid(True, alpha=0.3) plt.tight_layout() # Отобразить с помощью: fig2 # Пример 3: Диаграмма с областями fig3, ax3 = plt.subplots(figsize=(10, 6)) ax3.fill_between(df['Дата'], df['Продажи продукта A'], alpha=0.4) ax3.plot(df['Дата'], df['Продажи продукта A'], linewidth=2) ax3.set_xlabel('Дата') ax3.set_ylabel('Продажи') ax3.set_title('Продажи продукта A — Диаграмма с областями') ax3.grid(True, alpha=0.3) plt.tight_layout() # Отобразить с помощью: fig3 # Пример 4: Диаграмма с областями с накоплением fig4, ax4 = plt.subplots(figsize=(10, 6)) ax4.stackplot(df['Дата'], df['Продажи продукта A'], df['Продажи продукта B'], df['Продажи продукта C'], labels=['Продукт A', 'Продукт B', 'Продукт C'], alpha=0.7) ax4.set_xlabel('Дата') ax4.set_ylabel('Продажи') ax4.set_title('Общие продажи — Диаграмма с областями и накоплением') ax4.legend(loc='upper left') ax4.grid(True, alpha=0.3) plt.tight_layout() # Отображение с помощью: fig4

Выполнение этого кода создает следующие четыре визуализации:

03e417f776dd4163d33bf79adfb18fc4
d3675a326275107633efd348ecc7ac9d
e8040ee85bc889c94ead60d6b3db364a
d4bc0720fc8d6b99aaee27e64a4f7b25

Давайте разберем код шаг за шагом, чтобы вы поняли, что происходит:

  1. Сначала мы загружаем данные в pandas как CSV-файл и гарантируем, что дата правильно представлена как объект datetime.
  2. Библиотека Matplotlib структурирует диаграммы внутри объекта Figure, представляющего весь холст. Доступ к нему можно получить напрямую с помощью plt.figure, но использование нескольких переменных с помощью plt.subplots более интуитивно понятно для множественной визуализации. Каждый вызов plt.subplots определяет новый, отдельный объект Figure (холст).
  3. Строка fig1, ax1 = plt.subplots(figsize=(10, 6)) определяет первый подграфик; fig1 представляет холст, но ax1 представляет фактическую область построения графика внутри него и является переменной, в которой вы будете вносить большинство изменений.
  4. В Matplotlib есть разные функции для построения разных диаграмм. Функция plot строит двумерные точки, а затем соединяет их, создавая линейный график. Именно это мы и указываем в строке ax1.plot(df['Date'], df['Product A Sales'], linewidth=2).
  5. Остальные строки в основном выполняют эстетические функции, которые выполняют именно то, на что указывают их названия: маркируют оси, добавляют линии сетки и задают макет.
  6. Для многолинейной диаграммы код точно такой же, за исключением того, что мы вызываем plot три раза: по одному для каждого набора точек xy, которые мы хотим отобразить на графике, чтобы показать все продукты.
  7. Диаграмма с областями почти идентична линейной диаграмме, за исключением добавления ax3.fill_between(df['Date'], df['Product A Sales'], alpha=0.4), который сообщает Matplotlib о необходимости затенить область под линией.
  8. Для диаграммы с областями с накоплением , напротив, требуется использовать функцию stacked_plot, которая одновременно обрабатывает все три массива данных, которые мы хотим отобразить. Однако остальной код, отвечающий за эстетику, остаётся тем же.

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

Кроме того, помните, что вам не нужно запоминать этот синтаксис, особенно если вы новичок в программировании визуализации данных или вообще не знакомы с Python. Сосредоточьтесь на понимании происходящего на концептуальном уровне; вы всегда можете найти конкретный синтаксис и подставить нужные данные.

Это будет справедливо и для оставшихся двух примеров.

Кодирование визуализаций временных рядов в Plotly

Вот код для создания тех же визуализаций, что и выше, на этот раз в стиле Plotly:

import pandas as pd import plotly.graph_objects as go # Загрузка данных df = pd.read_csv('sales_data.csv') df['Date'] = pd.to_datetime(df['Date']) # Пример 1: Простая линейная диаграмма fig1 = go.Figure() fig1.add_trace(go.Scatter(x=df['Date'], y=df['Product A Sales'], mode='lines', name='Product A')) fig1.update_layout( title='Продажи продукта A с течением времени', xaxis_title='Date', yaxis_title='Sales', template='plotly_white' ) # Отображение с помощью: fig1 # Пример 2: Многолинейная диаграмма fig2 = go.Figure() fig2.add_trace(go.Scatter(x=df['Date'], y=df['Продажи продукта A'], mode='lines', name='Продукт A')) fig2.add_trace(go.Scatter(x=df['Дата'], y=df['Продажи продукта B'], mode='lines', name='Продукт B')) fig2.add_trace(go.Scatter(x=df['Дата'], y=df['Продажи продукта C'], mode='lines', name='Продукт C')) fig2.update_layout( title='Сравнение продаж — Все продукты', xaxis_title='Дата', yaxis_title='Продажи', template='plotly_white' ) # Отобразить с помощью: fig2 # Пример 3: Диаграмма с областями fig3 = go.Figure() fig3.add_trace(go.Scatter( x=df['Дата'], y=df['Продукт A Sales'], mode='lines', name='Product A', fill='tozeroy' )) fig3.update_layout( title='Продажи продукта A — Диаграмма с областями', xaxis_title='Дата', yaxis_title='Продажи', template='plotly_white' ) # Отображение с помощью: fig3 # Пример 4: Диаграмма с областями с накоплением fig4 = go.Figure() fig4.add_trace(go.Scatter( x=df['Дата'], y=df['Продажи продукта A'], mode='lines', name='Продукт A', stackgroup='one' )) fig4.add_trace(go.Scatter( x=df['Дата'], y=df['Продажи продукта B'], mode='lines', name='Продукт B', stackgroup='one' )) fig4.add_trace(go.Scatter( x=df['Дата'], y=df['Продажи продукта C'], mode='lines', name='Продукт C', stackgroup='one' )) fig4.update_layout( title='Общие продажи — Диаграмма с областями и накоплением', xaxis_title='Дата', yaxis_title='Продажи', template='plotly_white' ) # Отображение с помощью: fig4

Получаем следующие четыре визуализации:

b66303daf7b37e1ecf2ff15ec1afe2f7
8a5133d49409be55d5a670377b61f959
d10014f318320406047771540e61803d
3f238b996bfd65c7a1fc93d43ad1749a

Вот разбивка кода:

  • Plotly полностью независим от Matplotlib. Он использует объекты Figure с похожими именами, но не имеет объектов ax.
  • Функция Scatter с режимом «линии» используется для построения линейной диаграммы с заданными данными по осям X и Y. Функцию add_trace можно рассматривать как добавление нового компонента к существующему рисунку. Таким образом, для многолинейной диаграммы мы просто вызываем add_trace с соответствующими входными данными Scatter три раза.
  • Для маркировки и эстетики в Plotly используйте функцию update_layout.
  • Диаграмма с областями строится идентично линейной диаграмме с добавлением необязательного аргумента fill='tozeroy'.
    • На первый взгляд это может показаться каким-то непонятным цветом, но на самом деле это сообщение «TO ZERO Y», указывающее Plotly область, которую следует заполнить.
    • Если вам трудно это представить, попробуйте изменить аргумент на «tozerox» и посмотрите, что произойдет.
  • Для стековой диаграммы с областями нам понадобится другой необязательный параметр: stackgroup='one'. Добавление этого параметра к каждому вызову Scatter сообщает Plotly, что все они должны быть построены как часть одного стека.

Преимущество Plotly заключается в том, что по умолчанию все диаграммы Plotly интерактивны и позволяют масштабировать их, наводить курсор на подсказки и переключать легенду. (Обратите внимание, что изображения выше сохранены в формате PNG, поэтому вам придется самостоятельно сгенерировать диаграммы, чтобы увидеть это.)

Кодирование визуализаций временных рядов в Altair

Завершим созданием этих четырёх визуализаций в Altair. Вот код:

import pandas as pd import altair as alt # Загрузка данных df = pd.read_csv('sales_data.csv') df['Дата'] = pd.to_datetime(df['Дата']) # Пример 1: Простая линейная диаграмма chart1 = alt.Chart(df).mark_line().encode( x='Дата:T', y='Продажи продукта A:Q' ).properties( title='Продажи продукта A с течением времени', width=700, height=400 ) # Отображение с помощью: chart1 # Пример 2: Многолинейная диаграмма # Изменение формы данных для Altair df_melted = df.melt(id_vars='Дата', var_name='продукт', value_name='продажи') chart2 = alt.Chart(df_melted).mark_line().encode( x='Дата:T', y='sales:Q', color='product:N' ).properties( title='Сравнение продаж — Все продукты', width=700, height=400 ) # Отображается с помощью: chart2 # Пример 3: Диаграмма с областями chart3 = alt.Chart(df).mark_area(opacity=0.7).encode( x='Дата:T', y='Продажи продукта A:Q' ).properties( title='Продажи продукта A — Диаграмма с областями', width=700, height=400 ) # Отображается с помощью: chart3 # Пример 4: Диаграмма с областями с накоплением chart4 = alt.Chart(df_melted).mark_area(opacity=0.7).encode( x='Дата:T', y='sales:Q', color='product:N' ).properties( title='Общие продажи — Диаграмма с областями с накоплением', width=700, height=400 ) # Отображение с помощью: chart4

Получаем следующие графики:

3373b16c9b0243d771caef193a8a3a39
c04ca44482eddd4c27f29975ea0ec6d7
1916d6cf664fd23fe5d573764251df0f
b7ad6532b9653171393e229fdea05cab

Давайте разберем код:

  • Структура Altair несколько отличается от Matplotlib и Plotly. Для её освоения требуется некоторая практика, но как только вы её поймёте, интуитивность сделает создание новых визуализаций простым и понятным.
  • В Altair всё вращается вокруг объекта Chart, в который вы передаёте свои данные. Затем вы используете функцию mark_, чтобы указать, какой тип диаграммы вы хотите построить, и функцию encoding, чтобы указать, какие переменные будут соответствовать визуальным элементам на диаграмме (например, оси X и Y, цвету, размеру и т. д.).
  • Для линейной диаграммы мы используем функцию mark_line, а затем указываем, что хотим, чтобы на оси X отображалась дата, а на оси Y — продажи.
  • Функция «melt» не изменяет сами данные, а только их структуру. Она помещает все товары в один столбец, создавая «длинный формат», который лучше подходит для модели визуализации Altair. Подробнее см. в этой полезной статье.
  • После преобразования данных, как указано выше, мы можем построить многолинейную диаграмму, просто добавив «цветовую» кодировку, как показано в коде. Это стало возможным благодаря тому, что все типы продуктов теперь представлены в одном столбце, и мы можем указать Altair различать их по цвету.
  • Код для построения диаграмм с площадями демонстрирует всю красоту структуры Altair. Всё остаётся прежним — нужно лишь изменить используемую функцию на mark_area!

По мере того, как вы будете самостоятельно изучать другие типы визуализаций (и в будущих статьях!), модель Altair для построения визуализаций станет для вас более простой в реализации (и, надеемся, вы ее оцените по достоинству).

Что дальше?

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

Что касается кода, то комфорт приходит со временем и практикой. Пока же вы можете смело использовать приведённые выше примеры и адаптировать их под свои данные по мере необходимости.

До следующего раза.

Ссылки

  • https://matplotlib.org/
  • https://plotly.com/
  • https://altair-viz.github.io/

Источник: towardsdatascience.com

✅ Найденные теги: новости, Объяснение

ОСТАВЬТЕ СВОЙ КОММЕНТАРИЙ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Каталог бесплатных опенсорс-решений, которые можно развернуть локально и забыть о подписках

галерея

Фото сгенерированных лиц: исследование показывает, что люди не могут отличить настоящие лица от сгенерированных
Нейросети построили капитализм за трое суток: 100 агентов Claude заперли…
Скетч: цифровой осьминог и виртуальный мир внутри компьютера с человечком.
Сцена с жестами пальцами, где один жест символизирует "VPN", а другой "KHP".
‼️Paramount купила Warner Bros. Discovery — сумма сделки составила безумные…
Скриншот репозитория GitHub "Claude Scientific Skills" AI для научных исследований.
Структура эффективного запроса Claude с элементами задачи, контекста и референса.
Эскиз и готовая веб-страница платформы для AI-дизайна в современном темном режиме.
ideipro logotyp
Image Not Found
Звёздное небо с галактиками и туманностями, космос, Вселенная, астрофотография.

Система оповещения обсерватории Рубина отправила 800 000 сигналов в первую ночь наблюдений.

Астрономы будут получать оповещения о небесных явлениях в течение нескольких минут после их обнаружения. Теренс О'Брайен, редактор раздела «Выходные». Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной…

Мар 2, 2026
Женщина с длинными тёмными волосами в синем свете, нейтральный фон.

Расследование в отношении 61-фунтовой машины, которая «пожирает» пластик и выплевывает кирпичи.

Обзор компактного пресса для мягкого пластика Clear Drop — и что будет дальше. Шон Холлистер, старший редактор Публикации этого автора будут добавляться в вашу ежедневную рассылку по электронной почте и в ленту новостей на главной странице вашего…

Мар 2, 2026
Черный углеродное волокно с текстурой плетения, отражающий свет.

Материал будущего: как работает «бессмертный» композит

Учёные из Университета штата Северная Каролина представили композит нового поколения, способный самостоятельно восстанавливаться после серьёзных повреждений.  Речь идёт о модифицированном армированном волокном полимере (FRP), который не просто сохраняет прочность при малом весе, но и способен «залечивать» внутренние…

Мар 2, 2026
Круглый экран с изображением замка и горы, рядом электронная плата.

Круглый дисплей Waveshare для креативных проектов

Круглый 7-дюймовый сенсорный дисплей от Waveshare создан для разработчиков и дизайнеров, которым нужен нестандартный экран.  Это IPS-панель с разрешением 1 080×1 080 пикселей, поддержкой 10-точечного ёмкостного сенсора, оптической склейкой и защитным закалённым стеклом, выполненная в круглом форм-факторе.…

Мар 2, 2026

Впишите свой почтовый адрес и мы будем присылать вам на почту самые свежие новости в числе самых первых