Контурные графики
Самым простым способом начала работы с контурными графиками является использование бэкенда 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)
Как и в случае с функциями 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)
Общие атрибуты
Придадим этому графику более презентабельный вид с помощью следующих атрибутов:
-
Количество уровней можно изменить с помощью
levels
. -
Кроме названия и подписей осей, можно добавить подписи контуров с помощью атрибута
contour_labels
, имеющего псевдонимclabels
. Для записи функционального выражения в заголовке воспользуемся пакетом LaTeXStrings.jl. (Чтобы установить этот пакет, введите в REPL]
, а затем —add LaTeXStrings
.) -
Цветовую карту можно изменить с помощью
seriescolor
с псевдонимомcolor
или дажеc
. По умолчанию используется цветовая карта:inferno
из matplotlib. Полный список цветовых карт можно найти в разделе «Цветовые схемы» руководства. -
Расположение панели цветов можно изменить с помощью атрибута
colorbar
, псевдонимаcbar
. Чтобы удалить панель, задайте значениеcbar=false
. -
Ширина изоконтуров может быть изменена с помощью клавиш
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")
Если требуются только черные линии, можно задать атрибут 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")
Если для построения заполненных контуров вы используете бэкенд 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")
Часто необходимо, чтобы цветовая панель была логарифмической. Для обеспечения корректной работы потребуется несколько более сложный процесс, требующий настройки вручную. Сначала определим функцию 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")
Если вы хотите, чтобы границы заливки соответствовали порядкам величины, levels=8
. В зависимости от данных это число может потребовать некоторой корректировки. Если требуется более плавный график, можно задать для levels
гораздо большее число.