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

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.