Subplots

A grid of linked plots that share one region. subplots opens a rows × cols grid; each plot inside fills the next cell in turn. The grid manages cell size and (optionally) shared axes, panning, and zoom — so the per-plot size argument is ignored inside a grid. Both the grid and every cell register in the snapshot tree, the cells nested under the grid.

subplots(GRID, (title = "trig grid", rows = 2, cols = 2,
                size = float2(-1.0f, 640.0f), flags = ImPlotSubplotFlags.None)) {
    plot(P_SIN,  (title = "sin",    size = float2(-1.0f, -1.0f), flags = ImPlotFlags.None)) { plot_line("sin", g_sin) }
    plot(P_COS,  (title = "cos",    size = float2(-1.0f, -1.0f), flags = ImPlotFlags.None)) { plot_line("cos", g_cos) }
    plot(P_DAMP, (title = "damped", size = float2(-1.0f, -1.0f), flags = ImPlotFlags.None)) { plot_line("damped", g_damp) }
    plot(P_BARS, (title = "bars",   size = float2(-1.0f, -1.0f), flags = ImPlotFlags.None)) { plot_bars("bars", g_bars) }
}

Source: examples/tutorial/subplots.das.

 1options gen2
 2options _comment_hygiene = true
 3
 4require imgui/imgui_harness
 5require imgui/imgui_containers_builtin
 6require imgui/imgui_widgets_builtin
 7require imgui/imgui_implot_boost_v2
 8require implot
 9require math
10
11// =============================================================================
12// TUTORIAL: subplots — a grid of linked plots sharing one region.
13//
14//   subplots(IDENT, rows, cols, size, flags) { ... }  — a rows×cols grid; each
15//       `plot` inside fills the NEXT cell (the cell's size is managed by the grid,
16//       so the per-plot size arg is ignored). Both the grid and every cell register
17//       in the snapshot rail: the grid as IDENT, each cell nested under IDENT.
18//
19// STANDALONE: daslang.exe modules/dasImguiImplot/examples/tutorial/subplots.das
20// LIVE:       daslang-live modules/dasImguiImplot/examples/tutorial/subplots.das
21// =============================================================================
22
23let N = 100
24
25var g_ctx : ImPlotContext?
26var g_sin : array<double>
27var g_cos : array<double>
28var g_damp : array<double>
29var g_bars : array<int>
30
31[export]
32def init() {
33    harness_init("dasImguiImplot — subplots", 1100, 760)
34    g_ctx = implot::CreateContext()
35    g_sin  <- [for (i in range(N)); double(sin(float(i) * 0.12f))]
36    g_cos  <- [for (i in range(N)); double(cos(float(i) * 0.12f))]
37    g_damp <- [for (i in range(N)); double(sin(float(i) * 0.25f) * exp(-float(i) * 0.02f))]
38    g_bars <- [for (i in range(12)); (i * 3) % 7]
39}
40
41[export]
42def update() {
43    if (!harness_begin_frame()) return
44    harness_new_frame()
45
46    SetNextWindowPos(float2(20.0, 20.0), ImGuiCond.Always)
47    SetNextWindowSize(float2(1060.0, 720.0), ImGuiCond.Always)
48    window(PLOT_WIN, (text = "subplots", closable = false,
49                      flags = ImGuiWindowFlags.None)) {
50        text("A 2x2 grid: each plot fills the next cell. The grid and every cell snapshot independently.")
51        subplots(GRID, (title = "trig grid", rows = 2, cols = 2,
52                        size = float2(-1.0f, 640.0f), flags = ImPlotSubplotFlags.None)) {
53            plot(P_SIN, (title = "sin", size = float2(-1.0f, -1.0f), flags = ImPlotFlags.None)) {
54                plot_line("sin", g_sin)
55            }
56            plot(P_COS, (title = "cos", size = float2(-1.0f, -1.0f), flags = ImPlotFlags.None)) {
57                plot_line("cos", g_cos)
58            }
59            plot(P_DAMP, (title = "damped", size = float2(-1.0f, -1.0f), flags = ImPlotFlags.None)) {
60                plot_line("damped", g_damp)
61            }
62            plot(P_BARS, (title = "bars", size = float2(-1.0f, -1.0f), flags = ImPlotFlags.None)) {
63                plot_bars("bars", g_bars)
64            }
65        }
66    }
67
68    harness_end_frame()
69}
70
71[export]
72def shutdown() {
73    if (g_ctx != null) {
74        DestroyContext(g_ctx)
75    }
76    harness_shutdown()
77}
78
79[export]
80def main() {
81    init()
82    while (!exit_requested()) {
83        update()
84    }
85    shutdown()
86}

Walkthrough

The grid container

Like plot, subplots is a [container] macro: the bare IDENT (GRID) plus a named tuple of the remaining arguments (rows / cols / size / flags), then a body. Note the named arguments — a positional call fails to compile (required argument 'flags' has no default). The body simply issues rows * cols plot scopes; ImPlot drops each into the next cell.

Nested snapshot paths

The grid registers as PLOT_WIN/GRID and each cell nests beneath it — PLOT_WIN/GRID/P_SIN, …/P_COS, and so on. The test_subplots regression opens both the grid (asserting BeginSubplots returned true) and the first cell by its nested path, confirming the cells snapshot independently.

Box zoom one cell

Every cell is independently interactive. Right-drag a box inside a cell — the tick-marked rubber band in the walkthrough — and that cell zooms to the box. Because this grid uses ImPlotSubplotFlags.None (no linked axes), only the boxed cell zooms; the other three keep their full range. Linking is opt-in: add ImPlotSubplotFlags.LinkAllX / LinkAllY (or the per-row/col variants) to make the cells share an axis, so a zoom or pan in one drives them all. The recording drives the right-drag with real synthetic input and asserts the boxed cell’s range shrank while a neighbour’s stayed put, so a zoom that bled across cells fails it.