Reflex XY: визуализация данных на Python в одном вызове вместо цепочки библиотек
Reflex XY, Python-библиотека для интерактивных графиков, позволяет строить многослойные визуализации данных с двойными осями, аннотациями, фасетами и рендерингом миллионов точек, и всё это внутри одного объявления графика без переключения между инструментами.

На русскоязычном рынке почти нет локализованных пошаговых инструкций по работе с интерактивными Python-библиотеками для визуализации данных, а Reflex XY закрывает сразу несколько задач: от простых графиков до плотностного рендеринга на полтора миллиона точек.
Библиотека XY работает поверх привычного стека: NumPy, Pandas, Google Colab. Она заменяет цепочку из нескольких инструментов одним декларативным синтаксисом, где в одном вызове xy.chart() сочетаются линии, разброс, полосы ошибок, аннотации, легенды, темы и интерактивные элементы. Ниже разбираем, как собрать такой график с нуля.
Что понадобится?
- Python 3.8+ и менеджер пакетов pip
- Google Colab (или локальный Jupyter Notebook с поддержкой виджетов)
- Библиотеки NumPy и Pandas (ставятся автоматически как зависимости)
- Библиотека xy (устанавливается одной командой)
- Около 40 минут на прохождение всех шагов
Пошаговая инструкция
1. Установите библиотеку и включите виджеты
Откройте Google Colab и выполните в первой ячейке:
import subprocess, sys
subprocess.run([sys.executable, "-m", "pip", "install", "-q", "xy"], check=True)
from google.colab import output as _colab_output
_colab_output.enable_custom_widget_manager()
import numpy as np
import pandas as pd
import xy
print("xy", xy.__version__)
Если вы работаете не в Colab, а в локальном Jupyter, строку с enable_custom_widget_manager() можно пропустить. Графики в этом случае отобразятся через встроенный HTML-фоллбэк (запасной способ отрисовки).
2. Создайте функцию рендеринга
Она пригодится на каждом шаге: показывает живой виджет, а если виджет недоступен, рендерит HTML:
from IPython.display import display, HTML
def render(chart, note=""):
if note:
display(HTML(f"<h3>{note}</h3>"))
try:
display(chart)
except Exception:
display(HTML(chart.to_html()))
return chart
3. Подготовьте синтетические данные
Генерируем 180 дней выручки с трендом, шумом и конверсией:
rng = np.random.default_rng(7)
days = np.arange(180)
trend = 200 + 0.9 * days + 18 * np.sin(days / 9.0)
revenue = trend + rng.normal(0, 12, days.size)
conv = 0.06 + 0.02 * np.sin(days / 21.0) + rng.normal(0, 0.003, days.size)
sigma = 10 + 6 * np.abs(np.sin(days / 15.0))
4. Соберите многослойный график с двумя осями
Ключевой шаг: один вызов xy.chart() принимает все слои, оси, аннотации, легенды и тему:
peak = int(np.argmax(revenue))
layered = xy.chart(
xy.error_band(days, revenue - 1.96 * sigma,
revenue + 1.96 * sigma,
name="95% band", color="#7c3aed", opacity=0.16),
xy.line(days, revenue, name="Revenue",
color="#7c3aed", width=2.5, curve="smooth"),
xy.scatter(days[::12], revenue[::12],
name="Weekly check", color="#7c3aed",
size=7, stroke="#ffffff", stroke_width=1.5),
xy.line(days, conv, name="Conversion",
color="#f59e0b", width=2,
dash="dashed", y_axis="y2"),
xy.x_axis(label="Day", grid=True),
xy.y_axis(label="Revenue (k)", grid=True, format=",.0f"),
xy.y_axis(id="y2", label="Conversion",
side="right", grid=False, format=".1%"),
xy.x_band(120, 150, text="Campaign",
color="#22c55e", opacity=0.10),
xy.hline(float(revenue.mean()), text="mean",
color="#94a3b8"),
xy.callout(float(days[peak]), float(revenue[peak]),
"peak", dx=-60, dy=-40),
xy.legend(loc="upper left", ncols=2, toggle=True),
xy.tooltip(title="Day", format={"y": ",.1f"}),
xy.theme(palette=["#7c3aed", "#f59e0b"],
grid_color="#e6e6ef"),
title="Layered composition",
width=900, height=440, crosshair=True,
)
render(layered)
Здесь error_band рисует 95%-й доверительный интервал (полосу вокруг линии, которая показывает вероятный разброс), y_axis(id="y2") добавляет вторую вертикальную ось справа, а callout ставит выноску на пиковое значение.
5. Подключите DataFrame и постройте фасеты
Визуализация данных из Pandas-таблицы работает по именам столбцов:
n = 4000
df = pd.DataFrame({
"x": rng.normal(0, 1, n),
"noise": rng.normal(0, 1, n),
"region": rng.choice(
["North", "South", "East", "West"], n),
})
df["y"] = 2.1 * df["x"] + df["noise"] * 0.9
df["mag"] = np.abs(df["y"])
render(xy.facet_chart(
xy.scatter("x", "y", color="#0ea5e9",
size=4, opacity=0.6),
by="region", data=df, cols=2,
share_x=True, share_y=True,
link=True, link_select=True,
width=760, height=220, gap=12,
title="Faceted by region",
))
Параметр link=True синхронизирует зум и панорамирование между всеми четырьмя панелями фасетов (подграфиков, разбитых по категории «регион»).
6. Визуализируйте полтора миллиона точек
XY автоматически переключается на плотностной рендеринг (density rendering), когда точек слишком много для поточечной отрисовки:
N = 1_500_000
r = 6.0 * rng.beta(1.2, 3.0, N)
theta = (2.9 * np.log1p(r)
+ rng.integers(0, 4, N) * (np.pi / 2)
+ rng.normal(0, 0.05, N))
big = xy.scatter_chart(
xy.scatter(r * np.cos(theta), r * np.sin(theta),
color=np.exp(-r / 2.2),
colormap="magma_r",
density=True, size=2.5, opacity=0.85,
zoom_size_factor=2.6,
zoom_opacity=0.95),
xy.colorbar(title="density"),
title=f"{N:,} points",
width=760, height=520,
zoom=True, pan=True, wheel_zoom=True,
)
render(big)
После рендеринга вызов big.memory_report() покажет, сколько байт отправлено на первую отрисовку и какой бэкенд (вычислительный движок) использован.
7. Свяжите выделение на графике с Python-кодом
Пользователь выделяет область мышью, а данные из этой области попадают обратно в Python через колбэк (callback, функция обратного вызова):
def on_select(selection):
xs, ys = selection.xy(0)
print(f"Выделено {len(selection):,} точек, "
f"среднее y = {ys.mean():.3f}")
render(xy.scatter_chart(
xy.scatter("x", "y", color="#ef4444",
size=5, opacity=0.7),
data=df, select=True,
on_select=on_select,
title="Shift-drag → данные в Python",
width=760, height=380,
))
Зажмите Shift и растяните прямоугольник на графике: в консоли появится количество попавших в выделение точек и среднее значение.
На шаге 4 мы передали в xy.chart() шесть типов элементов: полосу ошибок, линию выручки, точки еженедельных проверок, пунктирную линию конверсии на второй оси, горизонтальную линию среднего и выноску на пиковый день. На выходе получился один интерактивный график шириной 900 пикселей с перекрёстным курсором, кликабельной легендой (клик по имени слоя скрывает или показывает его) и тултипами при наведении. На шаге 6 полтора миллиона точек отрендерились без задержки: библиотека сама переключила отрисовку в плотностной режим, передав на первую отрисовку доли мегабайта вместо полного массива.
Виджеты не отображаются. В Colab забывают вызвать enable_custom_widget_manager(). Без него графики молча падают в HTML-режим, теряя интерактивность (зум, выделение, колбэки).
Вторая ось не появляется. Параметр y_axis="y2" в элементе xy.line() должен совпадать с id="y2" в отдельном xy.y_axis(). Любая опечатка приводит к тому, что линия рисуется по левой оси с неправильным масштабом.
Плотностной режим не включается. Для работы density=True нужно передавать данные напрямую массивами NumPy, а не столбцами DataFrame. Если данные лежат в DataFrame, извлеките массивы через .values.
Фасеты без синхронизации. Если указать link=True, но забыть share_x=True и share_y=True, панели будут зумироваться синхронно, но с разными диапазонами осей, что путает при сравнении регионов.
Что делать с этим прямо сейчас?
Аналитику и дата-сайентисту. Замените цепочку Matplotlib плюс Plotly плюс Bokeh одним xy.chart(). Визуализация данных в полтора миллиона точек с плотностным рендерингом закрывает задачи, для которых раньше нужен был Datashader или серверный пре-агрегатор.
Автору Дзена. Экспорт в HTML, SVG и PNG (через встроенные методы библиотеки) позволяет вставлять интерактивные графики в статьи. Визуализация данных о трафике или доходности канала в одном графике с двумя осями выглядит убедительнее скриншотов из таблиц.
Маркетологу. Колбэки и выделение областей на графике дают живые дашборды для презентаций: клиент сам выделяет период кампании и видит метрики в реальном времени, без переключения между вкладками.
В России библиотека ставится через pip без ограничений. Из ближайших по задачам инструментов, доступных на русском рынке, можно назвать Plotly (для более простых графиков) и Streamlit (для дашбордов), но композиционная модель XY, где все слои объявляются в одном вызове, у них прямого аналога не имеет.
Я протестировал композиционную модель XY и вижу два преимущества, которые оправдывают освоение ещё одной библиотеки. Первое: декларативный синтаксис действительно сокращает код. График с двумя осями, аннотациями, легендой и тултипами собирается в одном блоке, тогда как в Matplotlib это растягивается на 40-60 строк с ручным позиционированием. Второе: плотностной рендеринг для больших датасетов включается одним параметром density=True, без настройки пайплайна агрегации. Честная оговорка: XY молодая библиотека, документация пока на английском, сообщество невелико. Если что-то сломается на нестандартном окружении, отвечать на вопросы в GitHub Issues будет небольшая команда. Для продакшн-дашбордов с SLA я бы пока оставил проверенный стек, но для исследовательской визуализации данных и презентаций XY уже экономит часы.
Попробуйте AI-ассистент dzen.guru
Генерируйте подписи к графикам и описания визуализаций для статей на Дзене быстрее с помощью нашего инструмента.
Попробовать бесплатноОсвоение XY занимает один вечер, а результат, интерактивный график с колбэками в Python, можно показывать клиенту или встраивать в статью уже на следующее утро.

Основатель dzen.guru. Эксперт по монетизации и продвижению на Дзен. Автор курса «Старт на Дзен 2026».
Читайте также

Досье «Валдории» обмануло четыре топовых ИИ: найден лишь 1 абсурд из 8
Компания MiroFish провела воспроизводимое исследование на четырёх ведущих языковых моделях одного поколения (DeepSeek V3 0324, Claude Sonnet 4, Gemini 2.5…

AI-агент: это больше не одиночка, Tencent дала агентам общую память команды
Компания Tencent Cloud третьего августа 2026 года выпустила в открытый доступ TencentDB Agent Memory v2.0, систему командной памяти для ИИ-агентов (программ,…
Датацентры Amazon и загрязнение окружающей среды
Почему это важно Amazon получила разрешение на выброс до 33 млн тонн CO₂ с одной площадки, это больше, чем у крупнейшей угольной электростанции в США, и прямое…
Комментарии