Plotly для аналитика: интерактивные графики
Plotly vs matplotlib/seaborn
Matplotlib — стандарт научной визуализации в Python. Seaborn — удобная обёртка для статистических графиков. Оба рендерят статические изображения: вы получаете PNG или SVG, который показывает данные, но не позволяет взаимодействовать.
Plotly — другой подход. Он создаёт интерактивные графики на JavaScript. Пользователь может навести курсор и увидеть точные значения, выделить область для зума, скрыть серии кликом по легенде. Для дашбордов и презентаций это меняет качество донесения информации.
Для аналитика Plotly полезен в нескольких сценариях: интерактивные дашборды в Streamlit и Dash, графики в Jupyter с live zoom, HTML-отчёты, которые можно прислать стейкхолдеру, графики для blog-постов в TG или LinkedIn.
Установка
pip install plotlyОбычно вместе ставят pandas и numpy для удобства.
Базовый пример
Plotly Express — высокоуровневый API, похожий на seaborn:
import plotly.express as px
import pandas as pd
df = pd.read_csv('sales.csv')
fig = px.line(
df,
x='date',
y='revenue',
color='region',
title='Revenue by region'
)
fig.show()В Jupyter сразу откроется интерактивный график. В скрипте — браузер с рендером.
Plotly Express покрывает типовые графики: line, bar, scatter, histogram, box plot, heatmap, pie, treemap, sunburst. Для 80% задач хватает.
Интерактивность из коробки
То, что делает Plotly ценным — это встроенные фичи интерактива:
Hover. Навели курсор — увидели точное значение. Настраивается через hover_data:
fig = px.scatter(
df, x='price', y='quantity',
hover_data=['product_name', 'category']
)Zoom и pan. Выделили область мышью — график приблизился. Можно крутить pan'ом. Reset — двойной клик.
Toggle legend. Кликнул на серию в легенде — скрыл/показал. Удобно для графиков с 5+ линиями.
Export. Встроенная кнопка для скачивания PNG.
Всё это работает без дополнительного кода. Просто используете Plotly — получаете интерактивность.
Кастомизация через update_layout
Для доводки графика до production-качества — update_layout:
fig = px.line(df, x='date', y='revenue')
fig.update_layout(
title='Weekly Revenue 2026',
xaxis_title='Week',
yaxis_title='Revenue (RUB)',
template='plotly_white',
height=500,
legend=dict(orientation='h', yanchor='bottom', y=1.02),
hovermode='x unified'
)hovermode='x unified' — особенно полезная опция. При наведении показывает значения всех серий в одной точке. Идеально для сравнения.
Несколько серий
Plotly легко работает с группировкой:
df = pd.DataFrame({
'date': pd.date_range('2026-01-01', periods=30),
'metric': ['DAU'] * 10 + ['Revenue'] * 10 + ['Orders'] * 10,
'value': ...
})
fig = px.line(df, x='date', y='value', color='metric')Каждая уникальная категория в color превращается в отдельную линию. Автоматическая легенда, цвета, interactivity.
Dual-axis графики
Частая задача — показать две метрики с разными единицами (DAU и revenue). Нужен dual axis:
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig = make_subplots(specs=[[{'secondary_y': True}]])
fig.add_trace(
go.Scatter(x=df['date'], y=df['dau'], name='DAU'),
secondary_y=False
)
fig.add_trace(
go.Scatter(x=df['date'], y=df['revenue'], name='Revenue'),
secondary_y=True
)
fig.update_yaxes(title='DAU', secondary_y=False)
fig.update_yaxes(title='Revenue (RUB)', secondary_y=True)
fig.show()Для dual axis нужен более низкоуровневый API (graph_objects), Express не поддерживает. Но результат стоит усилий.
Heatmap для когортных таблиц
Классическое применение — retention cohort heatmap:
import plotly.express as px
fig = px.imshow(
retention_matrix, # pandas DataFrame с когортами в строках, неделями в столбцах
aspect='auto',
color_continuous_scale='YlGnBu',
labels=dict(x='Weeks since signup', y='Cohort', color='Retention %')
)
fig.update_layout(title='Retention Cohort Matrix')В отличие от seaborn, здесь можно hover на каждой ячейке и увидеть точное значение. Для презентаций эффектно.
Интерактивный scatter с фасетами
Для сравнения по сегментам:
fig = px.scatter(
df,
x='ctr', y='conversion_rate',
color='channel',
size='visits',
facet_col='device', # разбивка по устройствам
hover_data=['campaign_name']
)Получается grid графиков (mobile, desktop, tablet) в одной фигуре. Каждый — scatter с размером точки = число визитов.
Мощный инструмент для exploratory analysis в презентации.
Combined charts
Часто нужен комбинированный chart: бары + линия на одной оси.
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Bar(
x=df['month'], y=df['revenue'],
name='Revenue', marker_color='lightblue'
))
fig.add_trace(go.Scatter(
x=df['month'], y=df['orders'],
name='Orders', yaxis='y2',
line=dict(color='darkred', width=3)
))
fig.update_layout(
yaxis=dict(title='Revenue'),
yaxis2=dict(title='Orders', overlaying='y', side='right')
)Популярный паттерн для ежемесячных отчётов: revenue барами + orders линией.
Владение инструментами визуализации — часть работы аналитика, особенно на presentation-стороне. В тренажёре Карьерник есть задачи на Python и визуализацию с разбором best practices.
Экспорт в HTML
Одна из killer-фич Plotly — экспорт в standalone HTML:
fig.write_html('report.html')Это одиночный файл с полным графиком. Можно отправить по email или открыть без интернета. Все интерактивные фичи работают.
Для статических сценариев (PDF-отчёты, PowerPoint):
fig.write_image('chart.png', width=1200, height=600, scale=2)Нужен kaleido package.
Стили и темы
Plotly имеет встроенные темы через template:
fig.update_layout(template='plotly_white')
# Другие: 'plotly_dark', 'ggplot2', 'seaborn', 'simple_white'Для корпоративного стиля можно создать свою тему один раз:
import plotly.io as pio
pio.templates['my_company'] = go.layout.Template(
layout=dict(
colorway=['#C15F3C', '#3C9DC1', '#7AC13C'],
font=dict(family='Arial'),
paper_bgcolor='#F5F5F5'
)
)
pio.templates.default = 'my_company'Теперь все графики автоматически в вашем фирменном стиле.
Интеграция со Streamlit и Jupyter
Jupyter: работает из коробки после pip install plotly. Графики рендерятся inline.
Streamlit: st.plotly_chart(fig).
Dash: нативная интеграция, Dash построен на Plotly.
Jupyter widgets: можно обновлять график в ответ на sliders/dropdowns через fig.update_traces.
Ограничения
Plotly медленнее matplotlib для большого количества точек. 100k точек в scatter — ок. 1M — начинаются тормоза. Для больших данных можно использовать datashader или семплировать.
HTML-файлы с Plotly-графиками большие (несколько MB на график). Не идеально для email.
Кривая обучения у graph_objects API крутая. Plotly Express покрывает типовые случаи, но нестандартные графики требуют разобраться в layout, traces, annotations.
Альтернативы
Bokeh — аналогичный подход, тоже interactive через JavaScript. Популярен в научном сообществе.
Altair — декларативный синтаксис на основе Vega-Lite. Очень выразительно, но ограничен в complex сценариях.
Echarts-python — обёртка над Apache ECharts. Красивые китайские библиотеки, но менее популярна в западном сообществе.
Для аналитика Plotly — лучший баланс между простотой и возможностями.
Читайте также
FAQ
Plotly vs Tableau?
Plotly — для кода, Python. Tableau — drag-n-drop, BI-инструмент. Разные категории. Plotly хорош для custom дашбордов и интеграции в Python-приложения.
Бесплатный?
Open-source MIT license. Plotly Dash Enterprise — платный для управляемого хостинга, но для большинства задач хватает бесплатной версии.
Работает ли без интернета?
Да. Все рендеринги клиентские, JavaScript-библиотека встраивается в HTML.
Python или Plotly.js?
Для аналитика — Python. Plotly.js (JavaScript) — для фронтенд-разработчиков.