Бэкенды

Бэкенды являются жизненной силой Plots, и разнообразие возможностей, подходов и сильных/слабых сторон было одной из основных причин создания этого пакета.

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

Выбор постоянного бэкенда

Plots использует механизм Предпочтения для того, чтобы выбор бэкенда по умолчанию сохранялся при перезапуске julia.

$ JULIA_PKG_PRECOMPILE_AUTO=0 julia -e 'import Plots; Plots.set_default_backend!(:pythonplot)'
$ julia  # перезапустить, показать постоянный режим
julia> using Plots
[ Info: Precompiling Plots [91a5bcdd-55d7-5caf-9e0b-520d859cae80]
[ Info: PythonPlot  # выполняет предварительную компиляцию для этого бэкенда
julia> plot(1:2) |> display  # использует `PythonPlot` по умолчанию

Предпочтения можно очистить с помощью Plots.set_default_backend!(). В качестве альтернативы можно использовать переменную среды PLOTS_DEFAULT_BACKEND для выбора бэкенда по умолчанию (но при этом потребуется запустить выполняемую вручную предварительную компиляцию с помощью Base.compilecache(Plots)).

Краткий обзор

Мое избранное: GR для скорости, Plotly(JS) для интерактивности, UnicodePlots для REPL/SSH и PythonPlot во всех остальных случаях.

Если вам требуется…​ используйте…​

разные возможности

GR, PythonPlot, Plotly(JS), Gaston

скорость

GR, UnicodePlots, InspectDR, Gaston

интерактивность

PythonPlot, Plotly(JS), InspectDR

красота

GR, Plotly(JS), PGFPlots/ PGFPlotsX

построение графиков в REPL

UnicodePlots

трехмерные графики

GR, PythonPlot, Plotly(JS), Gaston

окно графического интерфейса пользователя

GR, PythonPlot, PlotlyJS, Gaston, InspectDR

небольшой объем потребляемых ресурсов

UnicodePlots, Plotly

стабильность бэкенда

PythonPlot, Gaston

график + данные -> .hdf5-файл

HDF5

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


GR

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

backends1

Плюсы:

  • Скорость

  • Поддержка двух- и трехмерных графиков

  • Автономный или встроенный

Минусы:

  • Ограниченная интерактивность

Основной автор: Джозеф Хайнен (Josef Heinen) (@jheinen)

Тонкая настройка

С помощью механизма extra_kwargs можно использовать больше возможностей GR.

using Plots; gr()

x = range(-3, 3, length=30)
surface(
  x, x, (x, y)->exp(-x^2 - y^2), c=:viridis, legend=:none,
  nx=50, ny=50, display_option=Plots.GR.OPTION_SHADED_MESH,  # <-- series[:extra_kwargs]
)
backends2

Поддерживаемые :subplot :extra_kwargs

Ключевое слово Описание

legend_hfactor

Коэффициент вертикального интервала для условных обозначений

legend_wfactor

Мультипликативный коэффициент, влияющий на ширину условных обозначений

Поддерживаемые :series :extra_kwargs

Тип рядов Ключевое слово Описание

:surface

nx

Количество точек интерполяции в направлении x

:surface

ny

Количество точек интерполяции в направлении y

:surface, :wireframe

display_option

См. документацию по GR

Plotly / PlotlyJS

Они рассматриваются как отдельные бэкенды, хотя имеют общую часть кода и используют JavaScript API Plotly. plotly() — это единственный свободный от зависимостей вариант построения графиков, поскольку необходимый JavaScript поставляется в комплекте с Plots. Она может создавать встроенные графики в IJulia или открывать автономные окна браузера при запуске из REPL Julia.

plotlyjs() является предпочтительным вариантом, который позволяет использовать отличную функциональность PlotlyJS.jl от Спенсера Лайона (Spencer Lyon). Встраиваемые графики IJulia можно обновлять из любой ячейки. И это выгодно отличает данный бэкенд. Из REPL Julia он подключается к Blink.jl и Electron для построения графиков в отдельном окне GUI-интерфейса. Это тоже очень здорово. Кроме того, PlotlyJS поддерживает сохранение результатов в большем количестве форматов, чем Plotly, таких как EPS и PDF, и поэтому является рекомендуемой версией Plotly для разработки изображений типографского качества.

"backends_plotlyjs.png"
backends plotlyjs

Плюсы:

  • Широкая функциональность

  • Поддержка двух- и трехмерных графиков

  • Полностью сформированная библиотека

  • Интерактивность (даже при встраивании)

  • Автономный или встроенный

Минусы:

  • Нет пользовательских фигур

  • JSON может ограничивать производительность

Основной автор PlotlyJS.jl: Спенсер Лайон (Spencer Lyon) (@spencerlyon2)

MathJax

Plotly необходимо загружать MathJax для отрисовки строк LaTeX, поэтому реализована передача дополнительных ключевых слов с помощью extra_kwargs = :plot. С его помощью можно передать заголовок в дополнительное ключевое слово include_mathjax. Он имеет следующие параметры:

  • include_mathjax = "" (по умолчанию): заголовок mathjax отсутствует

  • include_mathjax = "cdn" включает стандартную сетевую версию заголовка

  • include_mathjax = "<filename?config=xyz>" включает определяемый пользователем файл

Они также могут быть переданы с помощью ключевого слова extra_plot_kwargs.

using LaTeXStrings
plotlyjs()
plot(
    1:4,
    [[1,4,9,16]*10000, [0.5, 2, 4.5, 8]],
    labels = [L"\alpha_{1c} = 352 \pm 11 \text{ km s}^{-1}";
              L"\beta_{1c} = 25 \pm 11 \text{ km s}^{-1}"] |> permutedims,
    xlabel = L"\sqrt{(n_\text{c}(t|{T_\text{early}}))}",
    ylabel = L"d, r \text{ (solar radius)}",
    yformatter = :plain,
    extra_plot_kwargs = KW(
        :include_mathjax => "cdn",
        :yaxis => KW(:automargin => true),
        :xaxis => KW(:domain => "auto")
   ),
)
"plotly_mathjax.html"

Тонкая настройка

Добавлять дополнительные аргументы в словари рядов и макетов plotly можно с помощью механизма extra_kwargs. Поддерживаются произвольные аргументы, но нужно быть осторожным, так как никаких проверок не выполняется, и поэтому можно непреднамеренно перезаписать существующие записи.

Например, добавить customdata можно следующим образом: scatter(1:3, customdata=["a", "b", "c"]). В plotly можно также передавать несколько дополнительных аргументов.

pl = scatter(
    1:3,
    rand(3),
    extra_kwargs = KW(
        :series => KW(:customdata => ["a", "b", "c"]),
        :plot => KW(:legend => KW(:itemsizing => "constant"))
    )
)

PythonPlot

Оболочка Julia вокруг популярного пакета Python Matplotlib. Использует PythonCall.jl для передачи данных с минимальными затратами.

backends3

Плюсы:

  • Широкая функциональность

  • Поддержка двух- и трехмерных графиков

  • Полностью сформированная библиотека

  • Автономный или встроенный

  • Хорошая поддержка в Plots

Минусы:

  • Использует Python

  • Зависимости часто приводят к проблемам с настройкой

Основной автор: Стивен Джонсон (Steven G Johnson) (@stevengj)

Тонкая настройка

С помощью механизма extra_kwargs можно использовать больше возможностей matplotlib. Например, для трехмерного графика следующий пример должен генерировать панель цветов в нужном месте. Без указанных ниже extra_kwargs панель цветов отображается слишком далеко справа, чтобы можно было увидеть ее деления и цифры. Четыре координаты в приведенном примере, т. е. [0.9, 0.05, 0.05, 0.9], задают расположение панели цветов [ left, bottom, width, height ]. Отметим, что для двухмерных графиков такая тонкая настройка не требуется.

using Plots; pythonplot()

x = y = collect(range(-π, π; length = 100))
fn(x, y) = 3 * exp(-(3x^2 + y^2)/5) * (sin(x+2y))+0.1randn(1)[1]
surface(x, y, fn, c=:viridis, extra_kwargs=Dict(:subplot=>Dict("3d_colorbar_axis" => [0.9, 0.05, 0.05, 0.9])))
backends4

Поддерживаемые :subplot :extra_kwargs

Ключевое слово Описание

3dcolorbaraxis

Указывает расположение панели цветов [ left, bottom, width, height ] для трехмерного графика

PGFPlotsX

Построение графиков LaTeX на основе PGF/TikZ.

backends5

Бэкенд-последователь бэкенда PGFPlots.

Имеет больше возможностей и находится на этапе разработки, в остальном — то же самое.

Для добавления сохранения отдельного TEX-файла, включающего начальную часть, используйте атрибут tex_output_standalone = true в команде plot.

Плюсы:

  • Красивые графики

  • Много функциональных возможностей (хотя код все еще не завершен)

Минусы:

  • Сложность установки

  • Сильные зависимости

Авторы:

  • PGFPlots: Кристиан Фойерзангер (Christian Feuersanger)

  • PGFPlotsX.jl: Кристофер Карлссон (Kristoffer Carlsson) (@KristofferC89), Тамаш Папп (Tamas K. Papp) (@tpapp)

  • Plots <

код ссылки PGFPlotsX: Саймон Крист (Simon Christ) (@BeastyBlacksmith), на основе кода Патрика Кофода Могенсена (Patrick Kofod Mogensen) (@pkofod)

Рабочий процесс LaTeX

Для использования собственного вывода LaTeX бэкенда pgfplotsx можно сохранить график в виде файла .tex или .tikz.

using Plots; pgfplotsx()
pl  = plot(1:5)
pl2 = plot((1:5).^2, tex_output_standalone = true)
savefig(pl,  "myline.tikz")    # создает среду tikzpicture, которая может быть включена в другие документы
savefig(pl2, "myparabola.tex") # создает отдельный документ, который компилируется самостоятельно, включая начальную часть

Преимущество сохранения в виде файла .tikz заключается в том, что \includegraphics можно использовать для изменения масштаба графика без изменения размера шрифтов. Вывод LaTeX по умолчанию предназначен для включения в качестве фигуры в другой документ и сам по себе не компилируется. Если вы включаете эти фигуры в другой документ LaTeX, необходимо иметь правильную начальную часть. Она может быть показана с помощью Plots.pgfx_preamble(pl) или скопирована из автономного вывода.

Тонкая настройка

С помощью механизма extra_kwargs можно использовать больше возможностей PGFPlotsX. По умолчанию он интерпретирует каждое дополнительное ключевое слово как параметр для команды plot. При задании extra_kwargs = :subplot они будут рассматриваться как параметр для команды axis, а extra_kwargs = :plot — как параметр для среды tikzpicture.

Например, изменить карту цветов на ту, которая является собственной для pgfplots, можно следующим образом. Таким образом можно сохранять четкость начальной части документов LaTeX.

using Plots; pgfplotsx()
surface(range(-3,3, length=30), range(-3,3, length=30),
        (x, y) -> exp(-x^2-y^2),
        label="",
        colormap_name = "viridis",
        extra_kwargs =:subplot)
backends6

В дальнейшем дополнительные команды или строки можно добавить с помощью специального ключевого слова add. Здесь к обычному линейному графику добавляется квадрат:

plot(1:5, add = raw"\draw (1,2) rectangle (2,3);", extra_kwargs = :subplot)
backends7

UnicodePlots

Простота. Строить графики можно напрямую в терминале. Вы не получите ничего типографского качества, но для быстрого просмотра данных это просто замечательный вариант. Позволяет строить графики на удаленно управляемом узле (SSH).

cwazrxa

Плюсы:

  • Минимальное количество зависимостей

  • построение графиков в REPL

  • Простота

  • Скорость

Минусы:

  • Ограниченные точность, плотность

Основной автор: Кристоф Стокер (Christof Stocker) (@Evizero)

Тонкая настройка

С помощью механизма extra_kwargs можно использовать больше возможностей UnicodePlots.

using Plots; unicodeplots()

extra_kwargs = Dict(:subplot=>(; border = :bold, blend = false))
p = plot(1:4, 1:4, c = :yellow; extra_kwargs)
plot!(p, 2:3, 2:3, c = :red)
wntpsif

Поддерживаемые :subplot :extra_kwargs

Ключевое слово Описание

width

Ширина графика

height

Высота графика

projection

Трехмерная проекция (:orthographic, perspective)

zoom

Трехмерное масштабирование

up

Трехмерный вертикальный вектор (азимут и повышение управляются с помощью Plots.jl camera)

canvas

Тип холста (см. страницу Низкоуровневый интерфейс)

border

Тип границы (:solid, :bold, :dashed, :dotted, :ascii, :none)

blend

Включение и отключение смешивания цветов холста (true/false)

Поддерживаемые :series :extra_kwargs

Тип рядов Ключевое слово Описание

all

colormap

Карта цветов (см. раздел Параметры)

heatmap, spy

fix_ar

Включение и отключение фиксации соотношения сторон терминала (true/false)

surfaceplot

zscale

Масштабирование оси z

surfaceplot

lines

Используйте lineplot вместо scatterplot (монотонные данные)

Gaston

Gaston — это прямой интерфейс для gnuplot, кроссплатформенной программы построения графиков, управляемой из командной строки. Интеграция Gaston в Plots произошла недавно (в 2021 г.), но поддерживаются многие возможности.

backends8

InspectDR

Быстрое построение графиков с помощью адаптивного графического интерфейса (опционально). Цель: быстрое выявление проблем и недостатков проектирования/моделирования для сокращения количества итераций проектирования.

inspectdr(); backendplot(n = 2)  #hide

Плюсы:

  • Относительно небольшое время загрузки или время до отображения первого графика.

  • Интерактивные привязки к мыши или сочетания клавиш.

    • Быстрый и простой способ панорамирования/масштабирования данных.

  • Перетаскивание Δ-маркеров (измерение/отображение Δx, Δy и наклон).

  • Разработан с учетом больших массивов данных.

    • Реагирование даже при работе со значительными (> 200 тыс. точек) массивами данных.

    • Подтверждена возможность работы с наборами данных размером 2 ГБ с приемлемой скоростью на более старых компьютерах под управлением Windows 7 (перетаскивать область данных крайне не рекомендуется).

Минусы:

  • В основном ограничивается двухмерными линейными графиками или графиками рассеяния

Основной автор: М. А. Лафорж (MA Laforge) (@ma-laforge)

HDF5 (HDF5-Plots)

Запись графика и данных в один файл HDF5 с использованием удобной для восприятия структуры, которая легко поддается обратному инжинирингу.

hdf5 samplestruct

Запись в HDF5-файл

hdf5() # Выбирает бэкенд HDF5-Plots
p = plot(...) # Строит график обычным образом
Plots.hdf5plot_write(p, "plotsave.hdf5")

Чтение из HDF5-файла

pythonplot() # Сначала следует выбрать бэкенд
pread = Plots.hdf5plot_read("plotsave.hdf5")
display(pread)

Плюсы:

  • Открытый стандартный формат файла для сложных наборов данных.

  • Удобный для восприятия (с использованием HDF5view).

  • Сохранение графика и данных в один двоичный файл.

  • (Повторная) отрисовка графиков в более позднее время с использованием предпочитаемого бэкенда.

Минусы:

  • В настоящее время отсутствует поддержка SeriesAnnotations и GridLayout.

    • (Откройте проблему, если в этом есть необходимость).

  • Пока не предусмотрена обратная совместимость (нет должного управления версиями).

    • Поэтому в настоящее время не совсем подходит для целей архивирования.

  • Сейчас реализован как бэкенд, чтобы избежать добавления зависимостей к Plots.jl.

Основной автор: М. А. Лафорж (MA Laforge) (@ma-laforge)


Устаревшие бэкенды

PyPlot

Бэкенд на основе matplotlib, использующий PyCall.jl и PyPlot.jl. Заменен на PythonCall.jl и PythonPlot.jl. Несмотря на то, что по-прежнему поддерживается в Plots 1.X, пользователям рекомендуется перейти на бэкенд pythonplot.

PGFPlots

Построение графиков LaTeX на основе PGF/TikZ.

Для добавления сохранения отдельного TEX-файла, включающего начальную часть, используйте атрибут tex_output_standalone = true в команде plot.

Плюсы:

  • Красивые графики

  • Много функциональных возможностей (хотя код все еще не завершен)

Минусы:

  • Сложность установки

  • Сильные зависимости

Авторы:

  • PGFPlots: Кристиан Фойерзангер (Christian Feuersanger)

  • PGFPlots.jl: Микель Кочендерфер (Mykel Kochenderfer) (@mykelk), Луи Дрессель (Louis Dressel) (@dressel) и другие

  • Plots <

код ссылки PGFPlots: Патрик Кофод Могенсен (Patrick Kofod Mogensen) (@pkofod)

Gadfly

Реализация Julia, вдохновленная «Грамматикой графики» (Grammar of Graphics).

Плюсы:

  • Четкий вид

  • Широкие возможности

  • Гибкость при совместном использовании с Compose.jl (вставка графиков и т. д.)

Минусы:

  • Не поддерживает трехмерные графики

  • Длительное время отображения первого графика

  • Много зависимостей

  • Без интерактивности

Основной автор: Дэниел К. Джонс (Daniel C Jones)

Immerse

Построенный на основе Gadfly, Immerse добавляет некоторую интерактивность и отдельное окно графического интерфейса, включая масштабирование/панорамирование и замечательный инструмент «точечное лассо» для сохранения векторов Julia с выбранными точками данных.

Плюсы:

  • Аналог Gadfly

  • Интерактивность

  • Автономный или встроенный

  • Функция «Лассо»

Минусы:

  • Аналог Gadfly

Основной автор: Тим Холи (Tim Holy)

Qwt

Мой пакет, который заключает PyQwt в оболочку. Подобен PyPlot, использует PyCall для преобразования вызовов в Python. Хотя Qwt.jl был «первым черновиком» Plots, его функциональность уступила место другим бэкендам, и поддерживать его не стоит.

Основной автор: Томас Брелофф (Thomas Breloff)

Bokeh

Незавершенный, но очень похожий на PlotlyJS…​ Используйте последний.

Winston

Неполная функциональность…​ Я так и не доработал его, и не думаю, что он предлагает что-то большее, чем другие бэкенды. Тем не менее графики имеют четкий вид, и пакет работает относительно быстро.