Engee 文档
Notebook

使用Makie创建复杂的图形布局

此示例演示Makie库的工具,通过使用嵌套GridLayout、链接轴、自定义图例和色阶,以及高级元素定位和空间管理技术将各种类型的图形(散点图、等值线图、3D模型和时

1. 软件包安装和数据准备
In [ ]:
Pkg.add("Makie")
Pkg.add("CairoMakie")

为第一个图表准备数据:

In [ ]:
seconds = 0:0.1:2
measurements = [8.2, 8.4, 6.3, 9.5, 9.1, 10.5, 8.6, 8.2, 10.5, 8.5, 7.2,
                8.8, 9.7, 10.8, 12.5, 11.6, 12.1, 12.1, 15.1, 14.7, 13.1]

using CairoMakie
2. 创建基本图表

让我们从实验数据和指数模型的简单可视化开始。
主要组件:

  • Figure() 为图形创建容器
  • Axis() 定义带有标题的坐标系
  • scatter!() 增加测量点
  • lines!() 绘制模型线
  • axislegend() 创建一个传奇

显示带有实验数据和指数模型的图形:

In [ ]:
f = Figure()
ax = Axis(f[1, 1],
    title = "Experimental data and exponential fit",
    xlabel = "Time (seconds)",
    ylabel = "Value",
)
CairoMakie.scatter!(
    ax,
    seconds,
    measurements,
    color = :tomato,
    label = "Measurements"
)
lines!(
    ax,
    seconds,
    exp.(seconds) .+ 7,
    color = :tomato,
    linestyle = :dash,
    label = "f(x) = exp(x) + 7",
)
# Добавление легенды в правый нижний угол
axislegend(position = :rb)

# Отображение фигуры
f
Out[0]:
No description has been provided for this image
3. 形成复杂的布局

创建一个复杂的图形对象(形状),其中包含多个用于绘图的区域:

  1. 我们使用 GridLayout 用于组织嵌套网格
  2. 我们定义了4个主要区域(A,B,C,D)
  3. 调整背景和形状大小
  4. 我们连接轴以同步刻度
In [ ]:
using CairoMakie
using Makie.FileIO  # Для работы с файлами

# Активация бэкенда и создание фигуры
CairoMakie.activate!()
f = Figure(
    backgroundcolor = RGBf(0.98, 0.98, 0.98),
    size = (1000, 700)
)

# Создание вложенных сеток
ga = f[1, 1] = GridLayout()  # Область A
gb = f[2, 1] = GridLayout()  # Область B
gcd = f[1:2, 2] = GridLayout()  # Контейнер для C и D
gc = gcd[1, 1] = GridLayout()  # Область C (3D мозг)
gd = gcd[2, 1] = GridLayout()  # Область D (EEG сигналы)

# Создание связанных осей для Область A
axtop = Axis(ga[1, 1])        # Верхнее распределение
axmain = Axis(ga[2, 1],       # Основной график
    xlabel = "before", 
    ylabel = "after")
axright = Axis(ga[2, 2])      # Правое распределение

# Связывание осей для синхронизации
linkyaxes!(axmain, axright)  # Общая шкала Y
linkxaxes!(axmain, axtop)    # Общая шкала X

f
Out[0]:
No description has been provided for this image
4. 区域A:散射和分布图

A区示范:

-通过颜色编码对数据进行分组
-具有共同刻度的相关轴
-主图边缘的分布
-自动图例放置
-微调元素之间的边距

In [ ]:
# Генерация тестовых данных для трех групп
labels = ["treatment", "placebo", "control"]
data = randn(3, 100, 2) .+ [1, 3, 5]  # 3 группы × 100 точек × 2 измерения

# Визуализация каждой группы
for (label, col) in zip(labels, eachslice(data, dims = 1))
    CairoMakie.scatter!(axmain, col, label = label)
    CairoMakie.density!(axtop, col[:, 1])  # Распределение сверху
    CairoMakie.density!(axright, col[:, 2], direction = :y)  # Распределение справа
end

# Настройка границ осей
CairoMakie.ylims!(axtop, low = 0)
CairoMakie.xlims!(axright, low = 0)

# Установка меток на осях
axmain.xticks = 0:3:9
axtop.xticks = 0:3:9

# Добавление легенды и скрытие лишних элементов
leg = Legend(ga[1, 2], axmain)
hidedecorations!(axtop, grid = false)
hidedecorations!(axright, grid = false)
leg.tellheight = true  # Фиксируем высоту легенды

# Добавление заголовка области
Label(ga[1, 1:2, Top()], "Stimulus ratings", valign = :bottom,
    font = :bold,
    padding = (0, 0, 5, 0))

# Настройка расстояний между элементами
colgap!(ga, 10)
rowgap!(ga, 10)

f
Out[0]:
No description has been provided for this image
5. B区:等值线图

B区展示:

-用于2d数据可视化的等值线图
-图层次结构:contourf+contour
-自定义色标与bin标签
-通过 Mixed 对齐模式
-精确控制图形之间的距离

In [ ]:
# Подготовка данных для контурных графиков
xs = LinRange(0.5, 6, 50)
ys = LinRange(0.5, 6, 50)
data1 = [sin(x^1.5) * cos(y^0.5) for x in xs, y in ys] .+ 0.1 .* randn.()
data2 = [sin(x^0.8) * cos(y^1.5) for x in xs, y in ys] .+ 0.1 .* randn.()

# Построение контурных графиков
ax1, hm = CairoMakie.contourf(gb[1, 1], xs, ys, data1, levels = 6)
ax1.title = "Histological analysis"
CairoMakie.contour!(ax1, xs, ys, data1, levels = 5, color = :black)
hidexdecorations!(ax1)  # Скрываем метки на оси X

ax2, hm2 = CairoMakie.contourf(gb[2, 1], xs, ys, data2, levels = 6)
CairoMakie.contour!(ax2, xs, ys, data2, levels = 5, color = :black)

# Настройка цветовой шкалы
cb = CairoMakie.Colorbar(gb[1:2, 2], hm, label = "cell group")
low, high = CairoMakie.extrema(data1)
edges = range(low, high, length = 7)
centers = (edges[1:6] .+ edges[2:7]) .* 0.5
cb.ticks = (centers, string.(1:6))  # Кастомные метки

# Оптимизация выравнивания
cb.alignmode = Mixed(right = 0)

# Настройка расстояний
colgap!(gb, 10)
rowgap!(gb, 10)

f
Out[0]:
No description has been provided for this image
6. 区域C:大脑的3d可视化

C区示范:

-3d模型的下载和可视化(STL格式)
-使用 Axis3 对于3D图形
-基于Y坐标的颜色编码
-倒色图更好的感知
-将3D可视化集成到整体布局中

In [ ]:
# Загрузка и визуализация 3D модели мозга
brain = load(assetpath("brain.stl"))

ax3d = Axis3(gc[1, 1], title = "Brain activation")
m = mesh!(
    ax3d,
    brain,
    color = [tri[1][2] for tri in brain for i in 1:3],
    colormap = Reverse(:magma),  # Инвертированная цветовая карта
)
Colorbar(gc[1, 2], m, label = "BOLD level")  # Цветовая шкала

f
Out[0]:
No description has been provided for this image
7. 区域D:脑电信号

D区展示:

-用于分组图形的轴阵列
-人工脑电信号的产生
-按点数动态缩放轴
-旋转标签以节省空间
-自动对齐列大小

In [ ]:
# Создание сетки осей для сигналов ЭЭГ
axs = [Axis(gd[row, col]) for row in 1:3, col in 1:2]
hidedecorations!.(axs, grid = false, label = false)  # Упрощаем оформление

# Генерация и визуализация ЭЭГ сигналов
for row in 1:3, col in 1:2
    xrange = col == 1 ? (0:0.1:6pi) : (0:0.1:10pi)  # Разные диапазоны
    eeg = [sum(sin(pi * rand() + k * x) / k for k in 1:10)
           for x in xrange] .+ 0.1 .* randn.()
    lines!(axs[row, col], eeg, color = (:black, 0.5))  # Полупрозрачные линии
end

# Подписи осей и заголовок
axs[3, 1].xlabel = "Day 1"
axs[3, 2].xlabel = "Day 2"
Label(gd[1, :, Top()], "EEG traces", valign = :bottom,
    font = :bold,
    padding = (0, 0, 5, 0))

# Добавление повернутых меток
for (i, label) in enumerate(["sleep", "awake", "test"])
    Box(gd[i, 3], color = :gray90)  # Фон метки
    Label(gd[i, 3], label, rotation = pi/2, tellheight = false)  # Вертикальный текст
end

# Автомасштабирование по количеству точек
n_day_1 = length(0:0.1:6pi)
n_day_2 = length(0:0.1:10pi)
colsize!(gd, 1, Auto(n_day_1))
colsize!(gd, 2, Auto(n_day_2))

# Настройка расстояний
rowgap!(gd, 10)
colgap!(gd, 10)
colgap!(gd, 2, 0)  # Убираем отступ у колонки с метками

f
Out[0]:
No description has been provided for this image
8. 最终设置和标签

其他设置:

-添加A/B/C/D标签
-微调列比例
-行高平衡
-优化元素的整体排列

In [ ]:
# Добавление меток областей
for (label, layout) in zip(["A", "B", "C", "D"], [ga, gb, gc, gd])
    Label(layout[1, 1, TopLeft()], label,
        fontsize = 26,
        font = :bold,
        padding = (0, 5, 5, 0),
        halign = :right)
end

# Настройка пропорций
colsize!(f.layout, 1, Auto(0.5))  # Уменьшаем ширину первой колонки
rowsize!(gcd, 1, Auto(1.5))       # Увеличиваем высоту 3D визуализации

# Отображение финального результата
f
Out[0]:
No description has been provided for this image