Skip to content

Per-Index Color Support with ImPlotSpec#672

Open
brenocq wants to merge 40 commits intomasterfrom
feat/spec-colors
Open

Per-Index Color Support with ImPlotSpec#672
brenocq wants to merge 40 commits intomasterfrom
feat/spec-colors

Conversation

@brenocq
Copy link
Collaborator

@brenocq brenocq commented Feb 13, 2026

Per-Index Color Support with ImPlotSpec

image image

image image

Summary

This PR introduces comprehensive per-index color support across all ImPlot plot types. Users can now specify an array of colors to apply different colors to each vertex, segment, bar, marker, or other primitive in their plots, enabling rich data visualizations with color-coded information.

This implementation is based on previous work #332 by @niavok and #665 by @vincentjzy.

Features

New Properties

Four new ImPlotSpec properties have been added to enable per-index coloring:

  • ImPlotProp_LineColors - Array of ImU32 colors for line segments/vertices
  • ImPlotProp_FillColors - Array of ImU32 colors for filled regions
  • ImPlotProp_MarkerLineColors - Array of ImU32 colors for marker outlines
  • ImPlotProp_MarkerFillColors - Array of ImU32 colors for marker fills

Supported Plot Types

Per-index colors are now supported in:

  • Line plots (PlotLine)
  • Shaded plots (PlotShaded)
  • Scatter plots (PlotScatter)
  • Bubble plots (PlotBubble)
  • Bar plots (PlotBars)
  • Stairstep plots (PlotStairs)
  • Stem plots (PlotStems)
  • Infinite line plots (PlotInfLines)

Usage Example

Constant Color (Existing Behavior)

The existing single-color properties continue to work as before:

static float xs[100], ys[100];
for (int i = 0; i < 100; ++i) {
    xs[i] = i * 0.01f;
    ys[i] = sinf(xs[i] * 20.0f);
}

if (ImPlot::BeginPlot("Single Color Line")) {
    ImPlot::PlotLine("Data", xs, ys, 100, {
        ImPlotProp_LineColor, ImVec4(1.0f, 0.5f, 0.0f, 1.0f),
        ImPlotProp_LineWeight, 2.0f
    });
    ImPlot::EndPlot();
}

Per-Index Colors (New Feature)

To use per-index colors, provide an array of ImU32 colors:

static float xs[100], ys[100];
static ImU32 colors[100];

for (int i = 0; i < 100; ++i) {
    xs[i] = i * 0.01f;
    ys[i] = sinf(xs[i] * 20.0f);
    
    // Generate rainbow colors
    float hue = i / 99.0f;
    colors[i] = ImColor::HSV(hue, 0.8f, 0.9f);
}

if (ImPlot::BeginPlot("Rainbow Line")) {
    ImPlot::PlotLine("Data", xs, ys, 100, {
        ImPlotProp_LineColors, colors,  // Per-vertex colors
        ImPlotProp_LineWeight, 2.0f
    });
    ImPlot::EndPlot();
}

Scatter Plot with Per-Marker Colors

static float xs[50], ys[50];
static ImU32 fill_colors[50], line_colors[50];

for (int i = 0; i < 50; ++i) {
    xs[i] = i * 0.02f;
    ys[i] = xs[i] + 0.1f * ((float)rand() / (float)RAND_MAX);
    
    // Sample from a colormap
    float t = i / 49.0f;
    ImVec4 color = ImPlot::SampleColormap(t, ImPlotColormap_Viridis);
    fill_colors[i] = ImGui::GetColorU32(color);
    line_colors[i] = ImGui::GetColorU32(ImVec4(color.x * 0.7f, color.y * 0.7f, color.z * 0.7f, 1.0f));
}

if (ImPlot::BeginPlot("Colorful Scatter")) {
    ImPlot::PlotScatter("Data", xs, ys, 50, {
        ImPlotProp_Marker, ImPlotMarker_Circle,
        ImPlotProp_MarkerSize, 8.0f,
        ImPlotProp_MarkerFillColors, fill_colors,
        ImPlotProp_MarkerLineColors, line_colors
    });
    ImPlot::EndPlot();
}

Bar Plot with Per-Bar Colors

static double data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
static ImU32 colors[10];

for (int i = 0; i < 10; ++i) {
    float hue = i / 9.0f;
    colors[i] = ImColor::HSV(hue, 0.8f, 0.9f);
}

if (ImPlot::BeginPlot("Colorful Bars")) {
    ImPlot::PlotBars("Data", data, 10, 0.7, 1, {
        ImPlotProp_FillColors, colors,
        ImPlotProp_LineColors, colors
    });
    ImPlot::EndPlot();
}

Implementation Details

Color Getter Architecture

The implementation uses a template-based color getter system:

  • GetterConstColor - Returns a constant color for all indices (used when single color is specified)
  • GetterIdxColor - Returns per-index colors from an array (used when color array is specified)

Both getters support alpha blending via a constructor parameter.

Backward Compatibility

All existing code continues to work without modification. The new per-index color properties are optional and only used when explicitly provided. When not specified, plots use the existing single-color properties (ImPlotProp_LineColor, ImPlotProp_FillColor, etc.).

Demo

A comprehensive "Per-Index Colors" demo has been added to implot_demo.cpp showcasing:

  • Colorful Lines (animated rainbow line and discrete colormap line)
  • Colorful Scatter (rainbow and colormap markers)
  • Colorful Shaded Plots (per-vertex colors with shading)
  • Colorful Bubbles (per-bubble rainbow and colormap colors)
  • Colorful Stairstep Plots (pre-step and post-step with colors)
  • Colorful Bar Plots (vertical and horizontal colored bars)
  • Colorful Stem Plots (colored stems with markers)
  • Colorful Infinite Lines (colored vertical and horizontal lines)

Run the demo to see all the colorful plot examples in action!

Testing

  • Verified compilation on Linux, Windows (MSVC), and macOS
  • All existing demos continue to work correctly
  • New colorful demos showcase the feature across all plot types
  • Backward compatibility maintained - no breaking changes

Notes

  • Color arrays must have at least as many elements as data points in the plot
  • Colors are specified as ImU32 (use ImGui::GetColorU32() or ImColor to convert from ImVec4)
  • Alpha values in per-index colors are multiplied by FillAlpha property when applicable
  • The feature integrates seamlessly with existing ImPlot styling and theming

epezent and others added 30 commits November 30, 2025 21:52
@brenocq brenocq added this to the v0.18 - ImPlotSpec milestone Feb 13, 2026
@brenocq brenocq self-assigned this Feb 13, 2026
@brenocq brenocq added type:feat New feature or request prio:high High priority status:review The task is under review labels Feb 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prio:high High priority status:review The task is under review type:feat New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants