Colormaps and style

Push a colormap and the items + heatmaps inside it auto-color from it; draw the matching colorbar with colormap_scale. A colormap maps a normalized t in [0,1] to a color — with_colormap makes one active for a scope, every auto-colored plot_line takes the next color in the map, and a heatmap samples its cells from it.

with_colormap(ImPlotColormap.Viridis) {
    plot(HEAT, (title = "heatmap (Viridis)", size = float2(560.0f, 480.0f), flags = ImPlotFlags.None)) {
        setup_axes("col", "row")
        plot_heatmap("vals", g_heat, ROWS, COLS, 0.0lf, 1.0lf, "")
    }
    same_line()
    colormap_scale("scale", 0.0lf, 1.0lf, ImPlotColormap.Viridis, float2(80.0f, 480.0f))
}

Source: examples/tutorial/colormaps_and_style.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: colormaps_and_style — push a colormap so items + heatmaps auto-color
 12// from it, and draw the matching colorbar legend.
 13//
 14//   with_colormap(cmap) { ... }      — RAII colormap scope; items inside sample it.
 15//   colormap_scale(label, lo, hi)    — a colorbar for the CURRENT (pushed) colormap.
 16//   sample_colormap(t, cmap)         — sample a color at t in [0,1] (not shown here).
 17//
 18// `cmap` is the ImPlotColormap enum: Deep / Dark / Viridis / Plasma / Jet / Spectral
 19// / Greys / … Push one and every auto-colored item (each plot_line takes the next
 20// color) and heatmap inside the scope draws from it.
 21//
 22// STANDALONE: daslang.exe modules/dasImguiImplot/examples/tutorial/colormaps_and_style.das
 23// LIVE:       daslang-live modules/dasImguiImplot/examples/tutorial/colormaps_and_style.das
 24// =============================================================================
 25
 26let ROWS = 12
 27let COLS = 16
 28let SERIES = 6
 29
 30var g_ctx : ImPlotContext?
 31var g_heat : array<double>
 32var g_series : array<array<double>>
 33
 34[export]
 35def init() {
 36    harness_init("dasImguiImplot — colormaps_and_style", 1280, 760)
 37    g_ctx = implot::CreateContext()
 38    // A smooth 2D gradient (row-major, ROWS*COLS), values in [0,1].
 39    g_heat <- [for (idx in range(ROWS * COLS));
 40               double(sin(float(idx / COLS) * 0.5f) * cos(float(idx % COLS) * 0.4f)) * 0.5lf + 0.5lf]
 41    // SERIES sine waves at increasing phase — each plot_line auto-takes the next color.
 42    g_series |> reserve(SERIES)
 43    for (k in range(SERIES)) {
 44        var s <- [for (i in range(100)); double(sin(float(i) * 0.1f + float(k) * 0.6f))]
 45        g_series |> emplace(s)
 46    }
 47}
 48
 49[export]
 50def update() {
 51    if (!harness_begin_frame()) return
 52    harness_new_frame()
 53
 54    SetNextWindowPos(float2(20.0, 20.0), ImGuiCond.Always)
 55    SetNextWindowSize(float2(1240.0, 720.0), ImGuiCond.Always)
 56    window(PLOT_WIN, (text = "colormaps", closable = false,
 57                      flags = ImGuiWindowFlags.None)) {
 58        text("Push a colormap; items + heatmaps sample from it. colormap_scale draws the colorbar.")
 59        // Heatmap colored by Viridis, with its matching colorbar on the same line.
 60        with_colormap(ImPlotColormap.Viridis) {
 61            plot(HEAT, (title = "heatmap (Viridis)", size = float2(560.0f, 480.0f),
 62                        flags = ImPlotFlags.None)) {
 63                setup_axes("col", "row")
 64                plot_heatmap("vals", g_heat, ROWS, COLS, 0.0lf, 1.0lf, "")
 65            }
 66            same_line()
 67            colormap_scale("scale", 0.0lf, 1.0lf, ImPlotColormap.Viridis, float2(80.0f, 480.0f))
 68        }
 69        same_line()
 70        // Six sine series auto-colored by the Spectral colormap.
 71        with_colormap(ImPlotColormap.Spectral) {
 72            plot(LINES, (title = "auto-colored series (Spectral)", size = float2(-1.0f, 480.0f),
 73                         flags = ImPlotFlags.None)) {
 74                setup_axes_limits(0.0lf, 100.0lf, -1.2lf, 1.2lf)
 75                for (k in range(SERIES)) {
 76                    plot_line("series {k}", g_series[k])
 77                }
 78            }
 79        }
 80    }
 81
 82    harness_end_frame()
 83}
 84
 85[export]
 86def shutdown() {
 87    if (g_ctx != null) {
 88        DestroyContext(g_ctx)
 89    }
 90    harness_shutdown()
 91}
 92
 93[export]
 94def main() {
 95    init()
 96    while (!exit_requested()) {
 97        update()
 98    }
 99    shutdown()
100}

Walkthrough

A guided tour of the two ways a colormap shows up. The cursor drifts to the colorbar beside the heatmap — Viridis is a sequential colormap, so the bar reads as a smooth ramp from low to high (the natural fit for a heatmap, and the sequential-ramp case forward-referenced from heatmap and histogram) — then glides to the six auto-colored series, each taking the next color from one Spectral scope. The recording self-verifies that both plots render at every beat.

Note

Changing a colormap live does not recolor existing auto-colored items: ImPlot caches each item’s color by id on first draw, so with_colormap only colors items created inside its scope for the first time. To recolor a steady set of items after a colormap switch, call ImPlot’s BustColorCache(plot_title) (clears the cache so the items re-pull) or set each item’s color explicitly from sample_colormap / GetColormapColor.

The colormap scope

with_colormap(cmap) { ... } pushes cmap for the body and pops it after — the RAII form, so the pop can’t be skipped. cmap is the ImPlotColormap enum (Deep / Viridis / Plasma / Jet / Spectral / Greys / …); the binding exposes ImPlot’s typedef-int colormap handle directly as that enum. For manual control, push_colormap / pop_colormap are the non-scoped pair.

The colorbar

colormap_scale(label_id, lo, hi, cmap, size) draws a vertical colorbar legend spanning [lo, hi] for cmap. Pass the same colormap you pushed so the bar matches the heatmap beside it. (The parameter is label_id, not labellabel is a reserved word.) The colormap is a required argument here because the native ColormapScale takes a real colormap, not the IMPLOT_AUTO sentinel.

Auto-colored series

In the second plot, six plot_line calls inside a with_colormap(Spectral) scope each take the next color from the map — no per-series color set. This is the usual way to color a family of related series consistently.

sample_colormap(t, cmap) returns the color at t in [0,1] directly, for when you need a colormap color outside a plot (a legend swatch, a custom drawing).