Документация Engee

GridLayout

Страница в процессе перевода.

Правильное задание размеров столбцов и строк

Строкам и столбцам можно задать четыре различных типа размеров.

Фиксированный

Fixed(scene_units) используется для установки абсолютного размера столбца или строки независимо от их содержимого. Этот тип имеет смысл только в том случае, если в столбце или строке есть содержимое переменной ширины, которое может сжиматься или расширяться в соответствии с этим размером. Вероятно, размеры Fixed будут нужны вам нечасто.

using CairoMakie

f = Figure()

Axis(f[1, 1], title = "My column has size Fixed(400)")
Axis(f[1, 2], title = "My column has size Auto()")

colsize!(f.layout, 1, Fixed(400))
# colsize!(f.layout, 1, 400) также работает

f
aa1673b

Относительный

Relative(fraction) используется для установки размера столбца или строки, составляющего определенную долю от доступной ширины или высоты. Он полезен, например, если требуется, чтобы столбец занимал 50 % доступной ширины независимо от другого находящегося в нем содержимого. В данном случаеследует использовать Relative(1/2). Доступная ширина — это ширина GridLayout за вычетом пространства, занимаемого промежутками между строками и столбцами, включая выступы.

using CairoMakie

f = Figure()

Axis(f[1, 1], title = "My column has size Relative(2/3)")
Axis(f[1, 2], title = "My column has size Auto()")
Colorbar(f[1, 3])

colsize!(f.layout, 1, Relative(2/3))

f
e8301bb

Автоматический

Размер Auto немного сложнее для понимания. Он имеет два параметра — логический trydetermine и числовой ratio. По умолчанию используется Auto() == Auto(true, 1). Это также высота строки и ширина столбца по умолчанию.

Столбец или строка с размером Auto(true) пытается подогнать свой размер под содержимое.

При решении GridLayout просматривает содержимое в каждой строке или столбце и проверяет, указан ли фиксированный размер. Многие объекты могут сообщать свою ширину или высоту, поскольку их содержимое имеет определенный размер, например Label. Другие объекты часто используются с заданной пользователем шириной или высотой, например Colorbar(scene, width = 30). В данном случаеGridLayout также видит, что ширина панели цветов равна 30 единицам, и подгоняет ширину столбца под это значение. Объекты типа Axis, с другой стороны, обычно не имеют определенного размера.

О своей ширине или высоте сообщают только объекты, занимающие одну строку или столбец. Если охватывается несколько строк или столбцов, неясно, как должно распределяться пространство, необходимое объекту.

Если в столбце размером Auto(true) находится более одного объекта с фиксированной шириной или высотой, используется максимальный размер.

Если столбец или строка имеют размер Auto(false), объекты фиксированного размера игнорируются. Конечно, может случиться и так, что в строке или столбце с размером Auto(true) нет объекта фиксированного размера. В обоих этих случаях столбцы или строки определяют свой размер по тому, что остается после вычисления всех столбцов или строк Fixed, Relative, Aspect и размерно-ориентированных Auto(true). Каждый неопределенный столбец Auto получает долю оставшегося пространства, пропорциональную его параметру ratio.

Допустим, что осталось два столбца с неопределенным размером Auto при наличии 300 единиц пространства. Столбец 1 имеет соотношение 1, а столбец 2 — соотношение 2. Первый столбец получит 1 / (1 + 2) * 300 == 100 единиц, а второй — 2 / (1 + 2) * 300 == 200 единиц.

using CairoMakie

f = Figure()

Axis(f[1, 1], title = "My column infers my width\nof 200 units")
Axis(f[1, 2], title = "My column gets 1/3rd\nof the remaining space")
Axis(f[1, 3], title = "My column gets 2/3rds\nof the remaining space")

colsize!(f.layout, 2, Auto(1)) # эквивалентно Auto(true, 1)
colsize!(f.layout, 3, Auto(2)) # эквивалентно Auto(true, 2)

f
35f6bf1

Соотношение

Понять этот размер также непросто. Синтаксис имеет вид Aspect(reference, ratio). Для столбца шириной Aspect(1, 2.0) задается высота, в два раза превышающая высоту строки 1 независимо от значения этой высоты. Поэтому ячейка сетки в точке [1, 1] всегда будет иметь соотношение сторон 2 к 1. Для строк с размером Aspect действует обратная закономерность.

Столбцы и строки с размерами, поддерживающими соотношение, очень полезны, когда нужно ограничить соотношение сторон ячейки сетки. Например, график, который всегда должен быть квадратным. Принудительное применение соотношения на уровне макета в большинстве случаев лучше, чем установка axis.aspect = AxisAspect(1), потому что так мы имеем дело с неизмененным макетом, где все границы ячеек сетки визуально выровнены. С другой стороны, блок Axis с aspect = AxisAspect(1) просто сжимается, оставаясь квадратным, но в этом случае выравнивание с другим содержимым сетки нарушается.

using CairoMakie

f = Figure()

Axis(f[1, 1], title = "I'm square and aligned")
Box(f[1, 2], color = (:blue, 0.1), strokecolor = :transparent)
Axis(f[1, 2], aspect = AxisAspect(1),
    title = "I'm square but break the layout.\nMy actual cell is the blue rect.")
Axis(f[2, 1])
Axis(f[2, 2])

rowsize!(f.layout, 2, Relative(2/3))
colsize!(f.layout, 1, Aspect(1, 1))

f
2427fa4

Note Помните, что если задать слишком много ограничений на размеры строк и столбцов, GridLayout может легко стать слишком большим или слишком маленьким. Если вы используете элемент с фиксированным размером или фиксированным соотношением сторон, рекомендуется иметь элементы переменной ширины, позволяющие заполнить оставшееся пространство.

Вложенность

Сетки могут быть вложены в другие сетки и т. д. на произвольную глубину. Родительским элементом верхней сетки должна быть сцена, в которой размещается макет. Сетка, помещаемая внутрь другой сетки, автоматически становится ее родителем. По умолчанию для сеток задан режим выравнивания Inside. Это означает, что края содержимого выравниваются по ограничивающему прямоугольнику сетки, исключая внешние выступы. Таким образом, графики во вложенных сетках будут корректно выровнены по свои линиям.

using CairoMakie

f = Figure()

subgl_left = GridLayout()
subgl_left[1:2, 1:2] = [Axis(f) for i in 1:2, j in 1:2]

subgl_right = GridLayout()
subgl_right[1:3, 1] = [Axis(f) for i in 1:3]

f.layout[1, 1] = subgl_left
f.layout[1, 2] = subgl_right

f
bde5ab0

Выравнивание

Далее вы увидите разницу между режимами выравнивания Outside с отступами и без них и режимом выравнивания Inside. Линии содержащих осей хорошо выравниваются только в стандартном режиме Inside. Как правило, режим Outside полезен для основного блока GridLayout для того, чтобы между краями окна и графиками был некоторый промежуток. Видно, что обычная ось выглядит так же, как и ось, помещенная внутрь сетки с выравниванием Inside, и обе они одинаково хорошо выровнены.

using CairoMakie

f = Figure(size = (800, 800))

Axis(f[1, 1], title = "No grid layout")
Axis(f[2, 1], title = "No grid layout")
Axis(f[3, 1], title = "No grid layout")

Axis(f[1, 2], title = "Inside", alignmode = Inside())
Axis(f[2, 2], title = "Outside", alignmode = Outside())
Axis(f[3, 2], title = "Outside(50)", alignmode = Outside(50))

[Box(f[i, 2], color = :transparent, strokecolor = :red) for i in 1:3]

f
ea5c2a4

Расширенное размещение

Элементы в макете сетки могут занимать несколько строк и столбцов. Их можно указать с помощью синтаксиса диапазона и двоеточия для полной ширины или высоты. Чтобы указать последнюю строку или столбец, используйте end.

using CairoMakie

f = Figure()

Axis(f[1, 1:2], title = "[1, 1:2]")
Axis(f[2:4, 1:2], title = "[2:4, 1:2]")
Axis(f[:, 3], title = "[:, 3]")
Axis(f[1:3, 4], title = "[1:3, 4]")
Axis(f[end, end], title = "[end, end]")

f
c4051fa

Добавление строк и столбцов путем индексирования

Если индексирование выполняется за пределами текущего диапазона макета сетки, ошибка не выводится. Макет просто автоматически изменяет размер, чтобы вместить новые индексы. Это очень удобно, если нужно итеративно строить макет или добавлять основные и боковые заголовки.

using CairoMakie

f = Figure(size = (800, 800))

Axis(f[1, 1])
for i in 1:3
    Axis(f[:, end+1])
    Axis(f[end+1, :])
end

Label(f[0, :], text = "Super Title", fontsize = 50)
Label(f[end+1, :], text = "Sub Title", fontsize = 50)
Label(f[1:end-1, 0], text = "Left Text", fontsize = 50,
    rotation = pi/2)
Label(f[1:end-1, end+1], text = "Right Text", fontsize = 50,
    rotation = -pi/2)

f
e65379c

Если у вас есть строки от 1 до 3 и вы индексируете строку 0, строки варьируются от 0 до 3. Если затем проиндексировать строку --1, строки будут варьироваться от --1 до 3 и т. д. Это поведение изменилось с появлением GridLayoutBase.jl v0.7.0.

using CairoMakie

f = Figure(size = (800, 800))

for i in 1:3, j in 1:3
    Axis(f[i, j])
end

Label(f[0, :], text = "First Supertitle", fontsize = 20)
Label(f[-1, :], text = "Second Supertitle", fontsize = 30)
Label(f[-2, :], text = "Third Supertitle", fontsize = 40)

f
253dccd

Обрезка пустых строк и столбцов

Если после интерактивного изменения макета останутся неиспользуемые строки или столбцы, trim! удалит их.

Начнем с двух осей:

using CairoMakie

f = Figure()

ax1 = Axis(f[1, 1], title = "Axis 1")
ax2 = Axis(f[1, 2], title = "Axis 2")

f
6f48273

Мы решаем, что было бы хорошо, если бы вторая ось находилась под первой. Перемещаем ее в две новые ячейки, а старый неиспользуемый столбец остается пустым.

f[2, 1] = ax2

f
216d1b7

Избавляемся от неиспользуемого пространства с помощью trim!:

trim!(f.layout)

f
92b13ce

Настройка расстояния между строками и столбцами

rowgap! и colgap! можно использовать для изменения расстояния между строками или столбцами, соответственно.

using CairoMakie

fig = Figure()

axs = [Axis(fig[i, j]) for i in 1:3, j in 1:3]
axs[1, 1].title = "Group A"
axs[1, 2].title = "Group B.1"
axs[1, 3].title = "Group B.2"

hidedecorations!.(axs, grid=false)

colgap!(fig.layout, 1, Relative(0.15))

fig
e50eaab

Все расстояния можно изменить сразу, опустив индекс промежутка, размер которого нужно изменить.

rowgap!(fig.layout, 50)

fig
2580e40