Отображение диаграмм Altair

Altair создаёт визуализации Vega-Lite, для отображения которых нужен интерфейс с поддержкой JavaScript. Среды notebook сочетают Python на стороне вычислений и JavaScript на стороне интерфейса, поэтому многие пользователи считают их удобными для Altair.

Диаграммы Altair работают без дополнительной настройки в Jupyter Notebook, JupyterLab, Zeppelin и связанных средах, если есть подключение к Интернету для загрузки библиотек JavaScript.

Altair также работает в IDE с поддержкой его диаграмм. На большинстве платформ возможно автономное отображение с подходящим расширением интерфейса; подробности приведены ниже.

Система средств отображения Altair

У разных систем вывода свои требования и ограничения. Altair предоставляет API для переключения средств отображения (renderers), позволяя настроить представление диаграммы. Они выбираются через реестр alt.renderers.

Основные встроенные варианты:

alt.renderers.enable("html")

Используется по умолчанию. Выводит HTML-представление диаграммы. Работает в JupyterLab, Jupyter Notebook, Zeppelin, VSCode-Python, многих связанных средах notebook, а также инструментах экосистемы Jupyter: nbviewer и HTML-выводе nbconvert. Для загрузки библиотек JavaScript нужен Интернет.

alt.renderers.enable("mimetype")

Использовался по умолчанию до Altair 4.0. Выводит специальный MIME-тип Vega-Lite, который подходящие расширения интерфейса преобразуют в диаграмму. Также выводит PNG-представление, полезное при просмотре без Интернета или на платформах без поддержки спецификаций Vega, например GitHub. Работает в новых версиях JupyterLab, nteract и VSCode-Python, но не в Jupyter Notebook, nbviewer и nbconvert.

alt.renderers.enable("jupyter")

Добавлен в версии 5.3. Отображает диаграмму через JupyterChart. Совместим со средами, поддерживающими сторонние Jupyter Widgets: JupyterLab, Jupyter Notebook, VSCode-Python и Colab. Для загрузки JavaScript нужен Интернет. Несмотря на использование JupyterChart, это средство не даёт доступа к значениям параметров и выборам из Python. Для такого доступа создайте объект JupyterChart явно, как описано в его документации.

alt.renderers.enable("jupyter", offline=True)

Добавлен в версии 5.3. Аналогичен "jupyter", но загружает JavaScript из пакета vl-convert-python, а не из CDN, поэтому подключение к Интернету не требуется.

alt.renderers.enable("browser")

Добавлен в версии 5.3. Отображает диаграммы во внешнем веб-браузере. Особенно полезен для локальных сред вне Jupyter, например IPython или Spyder. Подробнее см. «Отображение в браузере».

Кроме того, Altair включает:

  • "default", "colab", "kaggle", "zeppelin" — эквиваленты "html".
  • "jupyterlab", "nteract" — эквиваленты "mimetype".
  • "png" — преобразует диаграмму в PNG и выводит её с MIME-типом "image/png".
  • "svg" — преобразует диаграмму в SVG и выводит её с MIME-типом "image/svg+xml".
  • "olli" — использует Olli для создания доступных текстовых структур для пользователей программ экранного доступа.
  • "json" — выводит исходную JSON-спецификацию с MIME-типом "application/json".

alt.renderers.names() возвращает список всех зарегистрированных средств отображения в Python.

Сторонние пакеты могут устанавливать дополнительные средства через механизм entry points Python. Можно также создать собственное.

Отображение в JupyterLab

JupyterLab 1.0 и новее работает со стандартным средством Altair при наличии Интернета; специально включать его не нужно.

Для автономного отображения можно выбрать mimetype:

# Optional in JupyterLab: requires an up-to-date vega labextension.
alt.renderers.enable('mimetype')

Убедитесь, что установлена подходящая версия расширения Vega для JupyterLab. Для Altair 4 его можно установить так:

$ jupyter labextension install @jupyterlab/vega5-extension

В JupyterLab 2.0 и новее расширение устанавливается по умолчанию, но его версия в выпуске JupyterLab часто отстаёт от новых выпусков Altair на несколько месяцев.

Отображение в Jupyter Notebook

Классический Jupyter Notebook работает со стандартным средством Altair при наличии Интернета; специально включать его не нужно.

Для автономного отображения можно выбрать средство notebook:

# Optional in Jupyter Notebook: requires an up-to-date vega nbextension.
alt.renderers.enable('notebook')

Его предоставляет расширение notebook ipyvega. Установите и включите его через pip:

$ pip install vega

или conda:

$ conda install vega --channel conda-forge

В старых версиях notebook, до 5.3, расширение нужно дополнительно включить:

$ jupyter nbextension install --sys-prefix --py vega

Отображение в nteract

nteract не отображает HTML напрямую, поэтому стандартное средство html не работает. Но nteract поддерживает встроенное отображение MIME-типов Vega и Vega-Lite. Используйте версию с поддержкой MIME-типа Vega-Lite v6 и включите:

alt.renderers.enable('mimetype')

Отображение в VS Code

VSCode-Python работает со стандартным средством Altair при наличии Интернета; специально включать его не нужно.

Для автономного отображения можно использовать mimetype:

# Optional in VS Code
alt.renderers.enable('mimetype')

Панели мониторинга

Altair совместим с распространёнными пакетами Python для создания панелей мониторинга. Многие из них также позволяют читать параметры диаграммы. Например, выбор точек может обновлять другую часть панели — таблицу с выбранными данными.

Пакет Интерактивные диаграммы Altair Чтение параметров
Panel ✔ ✔
Plotly Dash ✔ ✔
Jupyter Voila с JupyterChart ✔ ✔
Marimo ✔ ✔
Shiny с JupyterChart ✔ ✔
Solara ✔ ✔
Streamlit ✔ ✔

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

Если достаточно интерактивности самого Altair, можно использовать Quarto или Jupyter Book: они создают HTML-страницы, которым не нужен веб-сервер.

Если вашего пакета нет в списке, создайте issue на GitHub, чтобы его добавили.

Среды без интерфейса JavaScript

Создавать спецификации Vega-Lite с помощью Altair можно в любой среде Python. Но для отрисовки нужен движок JavaScript, поэтому Altair удобнее всего работает в упомянутых выше браузерных средах. В остальных средах можно применять следующие подходы.

Статические изображения

Средства "png" и "svg" используют движок JavaScript, встроенный в необязательную зависимость vl-convert, чтобы создать изображения по спецификации Vega-Lite. Затем они отображаются в средах IPython через систему расширений MIME-вывода. Так можно показывать статические диаграммы внутри IPython QtConsole, Spyder и браузерных сред вроде JupyterLab.

SVG включается так:

alt.renderers.enable("svg")

PNG включается так:

alt.renderers.enable("png")

Для "png" доступны именованные аргументы:

  • scale_factor увеличивает размер диаграммы в заданное число раз; по умолчанию 1.0.
  • ppi задаёт разрешение изображения в пикселях на дюйм; по умолчанию 72.

Пример:

alt.renderers.enable("png", scale_factor=2, ppi=144)

Отображение в браузере

Чтобы отображать интерактивные диаграммы в средах вне браузера, средство "browser" автоматически открывает их в новых вкладках системного веб-браузера.

Включите его так:

alt.renderers.enable("browser")

Поддерживаются именованные аргументы:

  • using задаёт системный браузер. Можно передать имя одного браузера, например "safari", или список имён: используется первый доступный. Поддерживаемые имена перечислены в документации модуля Python webbrowser. Если аргумент не задан, используется системный браузер по умолчанию.
  • offline определяет, загружать ли JavaScript из CDN или встраивать вместе со спецификацией. При False, используемом по умолчанию, нужен Интернет; при True библиотеки встраиваются и Интернет не требуется. Для True нужна необязательная зависимость vl-convert-python.
  • port задаёт порт, через который доступен HTML диаграммы. По умолчанию выбирается случайный свободный порт.

Ограничения:

  • Средство создаёт временный веб-сервер, который отдаёт диаграмму ровно один раз, и открывает его URL в выбранном браузере. Не нужны временные HTML-файлы и длительно работающий сервер; подход экономно использует память. Но при обновлении страницы диаграмма теряется, а её URL нельзя скопировать и открыть в другой вкладке.
  • В средах IPython диаграмма открывается автоматически, если объект диаграммы — последнее значение ячейки или команды. В стандартной консоли python это не работает: используйте chart.show(), чтобы вручную вызвать активное средство отображения.
  • Это средство несовместимо с удалёнными средами вроде Binder и Colab.

Сохранение и отображение вручную

Можно сначала сохранить диаграмму в файл, например HTML или PNG, а затем открыть его. Подробнее см. «Сохранение диаграмм».

Устранение неполадок

В Altair участвует несколько компонентов: Python создаёт структуры данных, они передаются средствам отображения, а те выполняют JavaScript для получения результата. Из-за этой сложности иногда возникают необычные состояния, когда результат не появляется сразу.

Ниже перечислены распространённые проблемы и способы решения.

Общие проблемы

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

Если ожидается диаграмма, но нет никакого вывода, значит библиотеки отрисовки JavaScript не вызываются. Возможные причины:

  1. Старый браузер без поддержки ECMAScript 6. Диаграммы могут отображаться неправильно или не отображаться вообще; например, Altair не работает ни в одной версии Internet Explorer. Обычно в консоли JavaScript браузера видны синтаксические ошибки.
  2. Браузер не может загрузить библиотеки JavaScript: мешает локальный межсетевой экран, блокировщик рекламы или отсутствие Интернета. Проверьте ошибки в консоли JavaScript.
  3. Не запускается механизм вывода notebook — см. ниже.

В среде notebook диаграмма появляется, только если последняя строка ячейки вычисляется в объект диаграммы.

Для сравнения рассмотрим обычные операции Python:

>>> x = 4  # no output here
>>> x      # output here, because x is evaluated
4
>>> x * 2  # output here, because the expression is evaluated
8

Если последняя операция — присваивание, вывода не будет. То же верно для Altair:

import altair as alt
from altair.datasets import data
cars = data.cars.url

chart = alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N',
)

Последняя инструкция присваивает значение, поэтому диаграмма не показана. Если диаграмма записана в переменную, закончите ячейку вычислением этой переменной:

chart = alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N',
)

chart

Можно также создать объект диаграммы напрямую, без присваивания. Тогда определение объекта станет последним выражением и будет показано:

alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N',
)

Диаграмма есть, но содержимое пустое

Иногда диаграмма появляется без данных, например:

import altair as alt

alt.Chart('nonexistent_file.csv').mark_line().encode(
    x='x:Q',
    y='y:Q',
)

Обычно причина одна из двух:

  1. URL данных неверен или недоступен.
  2. Кодирования не соответствуют столбцам источника данных.

В примере файл nonexistent_file.csv не существует, поэтому диаграмма не отрисовывается. Соответствующие предупреждения видны в консоли JavaScript.

Другие возможные ситуации:

Включён блокировщик рекламы. Диаграммы с данными по URL иногда вызывают ложное срабатывание блокировщика. Проверьте ошибки в консоли JavaScript и попробуйте отключить блокировщик.

Данные загружаются с другого домена. Если сохранить HTML и открыть его по адресу file://, большинство браузеров не разрешит JavaScript загружать наборы данных по http://. Это защитная функция браузера, которую нельзя отключить. Для локального просмотра используйте простой HTTP-сервер, например встроенный в Python:

$ python -m http.server

Кодирования не соответствуют данным. Пустая диаграмма также получается, если поле не существует: например, из-за опечатки или специальных символов в имени столбца.

Вот пример неверного имени поля:

import pandas as pd

data = pd.DataFrame({'x': [1, 2, 3],
                     'y': [3, 1, 4]})

alt.Chart(data).mark_point().encode(
    x='x:Q',
    y='y:Q',
    color='color:Q'  # <-- this field does not exist in the data!
  )

Altair не проверяет существование полей: полная схема допускает много способов их задания, и учесть все частные случаи трудно. Улучшение этого поведения — одна из приоритетных задач; см. issue #3576.

Кодирования со специальными символами

Грамматика Vega-Lite, на которой основан Altair, использует специальные символы в именах полей для доступа к вложенным свойствам. Подробнее см. справочник полей Vega-Lite.

Поэтому столбцы с такими именами могут вызывать ошибки. Например, эта диаграмма неверна:

import pandas as pd
data = pd.DataFrame({'x.value': [1, 2, 3]})

alt.Chart(data).mark_point().encode(
    x='x.value:Q',
)

Чтобы показать данные, экранируйте точку в имени поля:

import pandas as pd
data = pd.DataFrame({'x.value': [1, 2, 3]})

alt.Chart(data).mark_point().encode(
    x=r'x\.value:Q',
)

По возможности избегайте символов ".", "[" и "]" в источниках данных.

Проблемы в JupyterLab

VegaLite 4/5 Object

Если вы используете Jupyter Notebook, а не JupyterLab, см. соответствующий раздел.

Если в JupyterLab появляется сообщение VegaLite 4 object или VegaLite 5 object, включено средство mimetype, но интерфейс JupyterLab не поддерживает соответствующий MIME-тип.

Проще всего включить стандартное средство:

alt.renderers.enable('default')

и повторно выполнить ячейку. Для отображения через MIME-тип обновите JupyterLab командой pip install -U jupyterlab или conda update jupyterlab.

VegaLite 3 Object

Если вы используете Jupyter Notebook, а не JupyterLab, см. соответствующий раздел.

Если JupyterLab показывает:

<VegaLite 3 object>

вероятно, установлена слишком старая версия JupyterLab. Altair 3.0 и новее лучше всего работает с JupyterLab 1.0 и новее. Проверьте версию:

$ jupyter lab --version
1.2.0

Если версия старее, обновите JupyterLab через pip install -U jupyterlab или conda update jupyterlab, в зависимости от исходного способа установки.

Вывод JavaScript отключён в JupyterLab

Если показано:

JavaScript output is disabled in JupyterLab

возможны две причины:

  1. Старая версия Altair. JupyterLab работает с Altair 2.0 и новее. Проверьте версию в ячейке:
import altair as alt
alt.__version__

Если версия старее 2.0, выйдите из JupyterLab и следуйте инструкции установки.

  1. Включено неподходящее средство отображения. JupyterLab работает со стандартным средством, а после переключения через alt.renderers.enable() диаграммы могут перестать отображаться. Проверьте активное средство:
import altair as alt
print(alt.renderers.active)

В данном сценарии отображение работает с "default" или "jupyterlab". Чтобы вернуть стандартное средство:

import altair as alt
alt.renderers.enable('default')

Стандартное средство включено изначально, поэтому этот шаг нужен только после явного переключения.

Текстовое представление диаграммы

Если вы используете Jupyter Notebook, см. соответствующий раздел.

Если в JupyterLab появляется текстовое представление объекта:

Chart({
  data: 'https://vega.github.io/vega-datasets/data/cars.json',
  encoding: FacetedEncoding({
    x: X({
      shorthand: 'Horsepower'
    })
  }),
  mark: 'point'
})

вероятно, используется старое ядро Jupyter. Проверьте:

import IPython; IPython.__version__
# 6.2.1

Altair некорректно отображается с IPython 4.X и старее. Проще всего выбрать Kernel → Change Kernel, затем первое доступное ядро.

Javascript Error: require is not defined

Если в JupyterLab возникает ошибка:

Javascript Error: require is not defined

вероятно, где-то было вызвано alt.renderers.enable('notebook'). Средство notebook не поддерживается JupyterLab. Верните стандартное:

alt.renderers.enable('default')

Проблемы в Jupyter Notebook

Notebook: VegaLite 4/5 object

Если вы используете JupyterLab, см. соответствующий раздел.

Сообщение VegaLite 4 object или VegaLite 5 object в Jupyter Notebook обычно означает, что включено средство mimetype. Проще всего вернуть стандартное:

alt.renderers.enable('default')

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

Notebook: VegaLite 3 object

Если вы используете JupyterLab, см. соответствующий раздел.

Если Notebook показывает:

<Vegalite 3 object>

возможны две причины:

  1. Вы забыли включить средство notebook. Как указано в инструкции, установите пакет vega версии 2.0 или новее и расширение Jupyter, затем включите средство:
import altair as alt
alt.renderers.enable('notebook')

Если возникает ошибка:

NoSuchEntryPoint: No 'notebook' entry point found in group 'altair.vegalite.v2.renderer'

пакет vega не установлен. Выполните стандартную инструкцию установки.

  1. Версия Jupyter Notebook слишком старая. Проверьте:
$ jupyter notebook --version

Нужна версия 5.3 или новее. Если она старее, используйте pip install -U jupyter notebook или conda update jupyter notebook, в зависимости от способа установки.

Если после этих действий диаграммы не отображаются, вероятно, используется другое ядро. Выберите Python 2 или Python 3 в соответствии с версией Python, с которой установлен Altair.

Notebook: текстовое представление диаграммы

Для JupyterLab см. соответствующий раздел. Для других сред см. проблемы вне Jupyter.

Если Notebook показывает текст объекта:

Chart({
  data: 'https://vega.github.io/vega-datasets/data/cars.json',
  encoding: FacetedEncoding({
    x: X({
      shorthand: 'Horsepower'
    })
  }),
  mark: 'point'
})

вероятно, используется старое ядро Jupyter. Проверьте:

import IPython; IPython.__version__
# 6.2.1

С IPython 4.X и старее Altair отображается некорректно. Выберите Kernel → Change Kernel, затем Python 2 или Python 3 в соответствии с версией Python, использованной при установке Altair.

Проблемы вне Jupyter

Вне Jupyter Notebook, например в терминале Python или IPython, диаграммы выводятся как текстовое представление. Для отрисовки нужен JavaScript, который терминал Python сам по себе не выполняет.

Рекомендации по работе вне notebook приведены в разделе «Среды без интерфейса JavaScript».