Контурные графики

Самым простым способом начала работы с контурными графиками является использование бэкенда PythonPlot. Для работы PythonPlot требуется пакет PythonPlot.jl, который можно установить, введя в REPL ], а затем — add PythonPlot. При первом вызове pythonplot() Julia может установить matplotlib. Для всех графиков, построенных на этой странице, используется PythonPlot, хотя код будет работать и для бэкенда GR по умолчанию.

Определим некоторые диапазоны и функцию f(x, y) для построения графика. Обратите внимание на ' в строке, определяющей z. Это оператор сопряжения, который преобразует x в вектор-строку. Проверить форму x' можно, введя size(x'). В руководстве мы упоминали, что макрос @. поэлементно определяет все, что находится справа от него. Точнее, точка . — это сокращение для трансляции; поскольку x' имеет размер (1, 100), а y — размер (50, ), то z = @. f(x', y) будет транслировать функцию f через x' и y и выдаст матрицу размера (50, 100).

using Plots; pythonplot()

f(x, y) = (3x + y^2) * abs(sin(x) + cos(y))

x = range(0, 5, length=100)
y = range(0, 3, length=50)
z = @. f(x', y)
contour(x, y, z)
contour1

Как и в случае с функциями plot! и scatter!, функция contour также имеет изменяемую версию contour!, которая может быть использована для модификации графика после его построения.

При использовании бэкенда pythonplot contour также может принимать вектор-строку для x, поэтому в качестве альтернативы x можно определить как вектор-строку, как показано ниже, и PythonPlot будет знать, как правильно его построить. Следует иметь в виду, что это НЕ будет работать для других бэкендов, таких как бэкенд GR по умолчанию, которые требуют, чтобы x и y были векторами-столбцами.

x = range(0, 5, length=100)'
y = range(0, 3, length=50)
z = @. f(x, y)
contour(x, y, z)

Общие атрибуты

Придадим этому графику более презентабельный вид с помощью следующих атрибутов:

  1. Количество уровней можно изменить с помощью levels.

  2. Кроме названия и подписей осей, можно добавить подписи контуров с помощью атрибута contour_labels, имеющего псевдоним clabels. Для записи функционального выражения в заголовке воспользуемся пакетом LaTeXStrings.jl. (Чтобы установить этот пакет, введите в REPL ], а затем — add LaTeXStrings.)

  3. Цветовую карту можно изменить с помощью seriescolor с псевдонимом color или даже c. По умолчанию используется цветовая карта :inferno из matplotlib. Полный список цветовых карт можно найти в разделе «Цветовые схемы» руководства.

  4. Расположение панели цветов можно изменить с помощью атрибута colorbar, псевдонима cbar. Чтобы удалить панель, задайте значение cbar=false.

  5. Ширина изоконтуров может быть изменена с помощью клавиш linewidth или lw.

Обратите внимание, что levels, color и contour_labels должны быть указаны в contour.

using LaTeXStrings

f(x, y) = (3x + y^2) * abs(sin(x) + cos(y))

x = range(0, 5, length=100)
y = range(0, 3, length=50)
z = @. f(x', y)

contour(x, y, z, levels=10, color=:turbo, clabels=true, cbar=false, lw=1)
title!(L"Plot of $(3x + y^2)|\sin(x) + \cos(y)|$")
xlabel!(L"x")
ylabel!(L"y")
contour2

Если требуются только черные линии, можно задать атрибут color следующим образом:

contour(x, y, z, color=[:black])

а для чередования черных и красных линий определенного шестнадцатеричного значения можно ввести color=[:black, "#E52B50"] и так далее.

Чтобы получить полный список доступных значений, которые может принимать атрибут, введите plotattr("attribute") в REPL. Например, plotattr("cbar") показывает, что может принимать либо символы из предопределенного списка (например, :left и :top), которые перемещают цветовую панель из ее стандартного расположения, либо логическое значение true или false, последнее из которых скрывает цветовую панель.

Заполненные контуры

Можно также указать, что контуры должны быть заполнены. Один из способов сделать это — использовать атрибут fill:

contour(x, y, z, fill=true)

Другим вариантом является использование функции contourf вместе с ее изменяемой версией contourf!:

contourf(x, y, z, levels=20, color=:turbo)
title!(L"(3x + y^2)|\sin(x) + \cos(y)|")
xlabel!(L"x")
ylabel!(L"y")
contour3

Если для построения заполненных контуров вы используете бэкенд GR, заполненные области будут разделяться черными линиями. Если такие линии нежелательны, можно установить ширину линии равной 0: lw=0.

Логарифмические контурные графики

Как и в случае с линейными диаграммами и диаграммами рассеяния, оси X и Y можно сделать логарифмическими с помощью атрибутов xscale и yscale. Если обе оси должны быть логарифмическими, можно задать значение scale=:log10.

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

g(x, y) = log(x*y)

x = 10 .^ range(0, 6, length=100)
y = 10 .^ range(0, 6, length=100)
z = @. g(x', y)
contourf(x, y, z, color=:plasma, scale=:log10,
    title=L"\log(xy)", xlabel=L"x", ylabel=L"y")
contour4

Часто необходимо, чтобы цветовая панель была логарифмической. Для обеспечения корректной работы потребуется несколько более сложный процесс, требующий настройки вручную. Сначала определим функцию h(x, y) = exp(x^2 + y^2), логарифм которой мы будем строить. Затем настроим атрибуты levels и colorbar_ticks.

Атрибут colorbar_ticks может принимать кортеж двух векторов (tickvalues, ticklabels). Поскольку h(x, y) может иметь значения в диапазоне от 10^0 до 10^8 в заданной области, значения делений будут представлять собой вектор tv = 0:8. Для форматирования подписей с верхними индексами снова используется LaTeXStrings. Обратите внимание, что оператор интерполяции строк меняется с $ на %$ при работе внутри L"...", чтобы избежать конфликта с $, обычно используемым в LaTeX.

h(x, y) = exp(x^2 + y^2)

x = range(-3, 3, length=100)
y = range(-3, 3, length=100)
z = @. h(x', y)

tv = 0:8
tl = [L"10^{%$i}" for i in tv]
contourf(x, y, log10.(z), color=:turbo, levels=8,
    colorbar_ticks=(tv, tl), aspect_ratio=:equal,
    title=L"\exp(x^{2} + y^{2})", xlabel=L"x", ylabel=L"y")
contour5

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