Skip to content

Commit 6031373

Browse files
committed
add SetNextColorsData to give per point colors
Implementation and demo for lines, scatter, infinite lines, shaded plots and stairstep
1 parent 626e391 commit 6031373

File tree

4 files changed

+464
-149
lines changed

4 files changed

+464
-149
lines changed

implot.h

+2
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,8 @@ IMPLOT_API void SetNextFillStyle(const ImVec4& col = IMPLOT_AUTO_COL, float alph
11171117
IMPLOT_API void SetNextMarkerStyle(ImPlotMarker marker = IMPLOT_AUTO, float size = IMPLOT_AUTO, const ImVec4& fill = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO, const ImVec4& outline = IMPLOT_AUTO_COL);
11181118
// Set the error bar style for the next item only.
11191119
IMPLOT_API void SetNextErrorBarStyle(const ImVec4& col = IMPLOT_AUTO_COL, float size = IMPLOT_AUTO, float weight = IMPLOT_AUTO);
1120+
// Set color buffer for the next item only. The colors array must be keep alive until the next item plot.
1121+
IMPLOT_API void SetNextColorsData(ImPlotCol_ target, ImU32* const& colors, int stride = sizeof(ImU32));
11201122

11211123
// Gets the last item primary color (i.e. its legend icon color)
11221124
IMPLOT_API ImVec4 GetLastItemColor();

implot_demo.cpp

+181
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,186 @@ void Demo_MarkersAndText() {
960960
}
961961
}
962962

963+
void Demo_PlotColors() {
964+
// Lines
965+
{
966+
static float xs1[1001], ys1[1001];
967+
ImU32 cs1[1001];
968+
for (int i = 0; i < 1001; ++i) {
969+
xs1[i] = i * 0.001f;
970+
ys1[i] = 0.5f + 0.5f * sinf(50 * (xs1[i] + (float)ImGui::GetTime() / 10));
971+
ImVec4 lineColor = ImPlot::SampleColormap(ys1[i], ImPlotColormap_Spectral);
972+
lineColor.w = 1 - powf(1 - (i * 0.001f), 4);
973+
cs1[i] = ImGui::GetColorU32(lineColor);
974+
}
975+
static double xs2[11], ys2[11];
976+
ImU32 cms2[11];
977+
for (int i = 0; i < 11; ++i) {
978+
xs2[i] = i * 0.1f;
979+
ys2[i] = xs2[i] * xs2[i];
980+
cms2[i] = ImGui::GetColorU32(ImPlot::RandomColor());
981+
}
982+
if (ImPlot::BeginPlot("Line Plot with colors")) {
983+
ImPlot::SetupAxes("x", "f(x)");
984+
ImVec4 s1Color = ImPlot::SampleColormap(0.5f, ImPlotColormap_Spectral);
985+
ImPlot::SetNextLineStyle(s1Color);
986+
ImPlot::SetNextColorsData(ImPlotCol_Line, cs1);
987+
ImPlot::PlotLine("sin(x)", xs1, ys1, 1001);
988+
ImVec4 s2Color = ImPlot::SampleColormap(0.5f, ImPlotColormap_Twilight);
989+
ImPlot::SetNextLineStyle(s2Color);
990+
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
991+
ImPlot::SetNextColorsData(ImPlotCol_Line, cms2);
992+
ImPlot::SetNextColorsData(ImPlotCol_MarkerFill, cms2);
993+
ImPlot::SetNextColorsData(ImPlotCol_MarkerOutline, cms2);
994+
ImPlot::PlotLine("x^2", xs2, ys2, 11);
995+
ImPlot::EndPlot();
996+
}
997+
}
998+
// Scatter
999+
{
1000+
srand(0);
1001+
static float xs1[100], ys1[100];
1002+
static ImU32 cs1[1001];
1003+
for (int i = 0; i < 100; ++i) {
1004+
xs1[i] = i * 0.01f;
1005+
ys1[i] = xs1[i] + 0.1f * ((float)rand() / (float)RAND_MAX);
1006+
cs1[i] = ImGui::GetColorU32(ImPlot::SampleColormap(10 * (ys1[i] - xs1[i]), ImPlotColormap_Viridis));
1007+
}
1008+
static float xs2[50], ys2[50];
1009+
ImU32 cmos2[50], cmfs2[50];
1010+
1011+
for (int i = 0; i < 50; i++) {
1012+
xs2[i] = 0.25f + 0.2f * ((float)rand() / (float)RAND_MAX);
1013+
ys2[i] = 0.75f + 0.2f * ((float)rand() / (float)RAND_MAX);
1014+
1015+
ImVec4 markerOutlineColor = ImPlot::SampleColormap(((float)rand() / (float)RAND_MAX), ImPlotColormap_Plasma);
1016+
ImVec4 markerFillColor = ImVec4(markerOutlineColor.x, markerOutlineColor.x, markerOutlineColor.z, 0.5);
1017+
cmfs2[i] = ImGui::GetColorU32(markerFillColor);
1018+
cmos2[i] = ImGui::GetColorU32(markerOutlineColor);
1019+
}
1020+
1021+
if (ImPlot::BeginPlot("Scatter Plot with colors")) {
1022+
ImVec4 s1Color = ImPlot::SampleColormap(0.5f, ImPlotColormap_Viridis);
1023+
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle, 4, s1Color, IMPLOT_AUTO, s1Color);
1024+
ImPlot::SetNextColorsData(ImPlotCol_MarkerOutline, cs1);
1025+
ImPlot::SetNextColorsData(ImPlotCol_MarkerFill, cs1);
1026+
ImPlot::PlotScatter("Data 1", xs1, ys1, 100);
1027+
1028+
ImVec4 s2Color = ImPlot::SampleColormap(0.5f, ImPlotColormap_Plasma);
1029+
ImPlot::SetNextMarkerStyle(ImPlotMarker_Square, 6, s2Color, IMPLOT_AUTO, s2Color);
1030+
ImPlot::SetNextColorsData(ImPlotCol_MarkerOutline, cmos2);
1031+
ImPlot::SetNextColorsData(ImPlotCol_MarkerFill, cmfs2);
1032+
ImPlot::PlotScatter("Data 2", xs2, ys2, 50);
1033+
1034+
ImPlot::EndPlot();
1035+
}
1036+
}
1037+
1038+
// Infinite lines
1039+
{
1040+
static double vals[] = { 0.25, 0.5, 0.75 };
1041+
static ImU32 colors[] = { ImGui::GetColorU32(ImPlot::RandomColor()), ImGui::GetColorU32(ImPlot::RandomColor()), ImGui::GetColorU32(ImPlot::RandomColor()) };
1042+
if (ImPlot::BeginPlot("##Infinite with colors")) {
1043+
ImPlot::SetupAxes(NULL, NULL, ImPlotAxisFlags_NoInitialFit, ImPlotAxisFlags_NoInitialFit);
1044+
ImPlot::SetNextLineStyle(ImVec4(1, 1, 1, 0.5));
1045+
ImPlot::SetNextColorsData(ImPlotCol_Line, colors);
1046+
ImPlot::PlotInfLines("VLines", vals, 3);
1047+
ImPlot::SetNextLineStyle(ImVec4(1, 1, 1, 0.5));
1048+
ImPlot::SetNextColorsData(ImPlotCol_Line, colors);
1049+
ImPlot::PlotInfLines("HLines", vals, 3, ImPlotInfLinesFlags_Horizontal);
1050+
ImPlot::EndPlot();
1051+
}
1052+
}
1053+
1054+
// Shaded plots
1055+
{
1056+
static float xs[1001], ys[1001], ys1[1001], ys2[1001], ys3[1001], ys4[1001];
1057+
static ImU32 cl1[1001];
1058+
static ImU32 cf1[1001];
1059+
static ImU32 cf2[1001];
1060+
srand(0);
1061+
1062+
for (int i = 0; i < 1001; ++i) {
1063+
xs[i] = i * 0.001f;
1064+
ys[i] = 0.25f + 0.25f * sinf(25 * xs[i]) * sinf(5 * xs[i]) + RandomRange(-0.01f, 0.01f);
1065+
ys1[i] = ys[i] + RandomRange(0.1f, 0.12f);
1066+
ys2[i] = ys[i] - RandomRange(0.1f, 0.12f);
1067+
ys3[i] = 0.75f + 0.2f * sinf(37 * xs[i]);
1068+
ys4[i] = 0.75f + 0.1f * cosf(29 * xs[i]);
1069+
1070+
ImVec4 lineColor = ImPlot::SampleColormap(i/1001.f, ImPlotColormap_Hot);
1071+
ImVec4 fillColor = lineColor;
1072+
fillColor.w = 0.25f;
1073+
cl1[i] = ImGui::GetColorU32(lineColor);
1074+
cf1[i] = ImGui::GetColorU32(fillColor);
1075+
1076+
float diffNormalized = (float) fabs(ys3[i] - ys4[i]) / (0.3f);
1077+
ImVec4 fillColor2 = ImPlot::SampleColormap(diffNormalized, ImPlotColormap_Plasma);
1078+
fillColor2.w = 0.8f;
1079+
cf2[i] = ImGui::GetColorU32(fillColor2);
1080+
}
1081+
1082+
if (ImPlot::BeginPlot("Shaded Plots with colors")) {
1083+
ImPlot::SetNextColorsData(ImPlotCol_Fill, cf1);
1084+
ImPlot::PlotShaded("Uncertain Data", xs, ys1, ys2, 1001);
1085+
ImPlot::SetNextColorsData(ImPlotCol_Line, cl1);
1086+
ImPlot::PlotLine("Uncertain Data", xs, ys, 1001);
1087+
ImPlot::SetNextColorsData(ImPlotCol_Fill, cf2);
1088+
ImPlot::PlotShaded("Overlapping", xs, ys3, ys4, 1001);
1089+
ImPlot::PlotLine("Overlapping", xs, ys3, 1001);
1090+
ImPlot::PlotLine("Overlapping", xs, ys4, 1001);
1091+
ImPlot::EndPlot();
1092+
}
1093+
}
1094+
1095+
// Stairstep
1096+
{
1097+
static float ys1[21], ys2[21];
1098+
static ImU32 clys1[21], cfys1[21], clys2[21], cfys2[21];
1099+
for (int i = 0; i < 21; ++i) {
1100+
ys1[i] = 0.75f + 0.2f * sinf(10 * i * 0.05f);
1101+
ys2[i] = 0.25f + 0.2f * sinf(10 * i * 0.05f);
1102+
ImVec4 cl1 = ImPlot::RandomColor();
1103+
ImVec4 cl2 = ImPlot::RandomColor();
1104+
ImVec4 cf1 = cl1;
1105+
ImVec4 cf2 = cl2;
1106+
cf1.w = 0.5;
1107+
cf2.w = 0.5;
1108+
1109+
clys1[i] = ImGui::GetColorU32(cl1);
1110+
clys2[i] = ImGui::GetColorU32(cl2);
1111+
cfys1[i] = ImGui::GetColorU32(cf1);
1112+
cfys2[i] = ImGui::GetColorU32(cf2);
1113+
}
1114+
static ImPlotStairsFlags flags = 0;
1115+
CHECKBOX_FLAG(flags, ImPlotStairsFlags_Shaded);
1116+
if (ImPlot::BeginPlot("Stairstep Plot with colors")) {
1117+
ImPlot::SetupAxes("x", "f(x)");
1118+
ImPlot::SetupAxesLimits(0, 1, 0, 1);
1119+
1120+
ImPlot::PushStyleColor(ImPlotCol_Line, ImVec4(0.5f, 0.5f, 0.5f, 1.0f));
1121+
ImPlot::PlotLine("##1", ys1, 21, 0.05f);
1122+
ImPlot::PlotLine("##2", ys2, 21, 0.05f);
1123+
ImPlot::PopStyleColor();
1124+
1125+
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
1126+
ImPlot::SetNextFillStyle(IMPLOT_AUTO_COL, 0.25f);
1127+
ImPlot::SetNextColorsData(ImPlotCol_Line, clys1);
1128+
ImPlot::SetNextColorsData(ImPlotCol_Fill, cfys1);
1129+
ImPlot::SetNextColorsData(ImPlotCol_MarkerOutline, clys1);
1130+
ImPlot::PlotStairs("Post Step (default)", ys1, 21, 0.05f, 0, flags);
1131+
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
1132+
ImPlot::SetNextFillStyle(IMPLOT_AUTO_COL, 0.25f);
1133+
ImPlot::SetNextColorsData(ImPlotCol_Line, clys2);
1134+
ImPlot::SetNextColorsData(ImPlotCol_Fill, cfys2);
1135+
ImPlot::SetNextColorsData(ImPlotCol_MarkerOutline, clys2);
1136+
ImPlot::PlotStairs("Pre Step", ys2, 21, 0.05f, 0, flags | ImPlotStairsFlags_PreStep);
1137+
1138+
ImPlot::EndPlot();
1139+
}
1140+
}
1141+
}
1142+
9631143
//-----------------------------------------------------------------------------
9641144

9651145
void Demo_NaNValues() {
@@ -2214,6 +2394,7 @@ void ShowDemoWindow(bool* p_open) {
22142394
DemoHeader("Images", Demo_Images);
22152395
DemoHeader("Markers and Text", Demo_MarkersAndText);
22162396
DemoHeader("NaN Values", Demo_NaNValues);
2397+
DemoHeader("Plot Colors", Demo_PlotColors);
22172398
ImGui::EndTabItem();
22182399
}
22192400
if (ImGui::BeginTabItem("Subplots")) {

implot_internal.h

+5
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,8 @@ struct ImPlotNextPlotData
11751175
// Temporary data storage for upcoming item
11761176
struct ImPlotNextItemData {
11771177
ImVec4 Colors[5]; // ImPlotCol_Line, ImPlotCol_Fill, ImPlotCol_MarkerOutline, ImPlotCol_MarkerFill, ImPlotCol_ErrorBar
1178+
ImU32 const* ColorsData[5];
1179+
int ColorsDataStride[5];
11781180
float LineWeight;
11791181
ImPlotMarker Marker;
11801182
float MarkerSize;
@@ -1194,7 +1196,10 @@ struct ImPlotNextItemData {
11941196
ImPlotNextItemData() { Reset(); }
11951197
void Reset() {
11961198
for (int i = 0; i < 5; ++i)
1199+
{
11971200
Colors[i] = IMPLOT_AUTO_COL;
1201+
ColorsData[i] = nullptr;
1202+
}
11981203
LineWeight = MarkerSize = MarkerWeight = FillAlpha = ErrorBarSize = ErrorBarWeight = DigitalBitHeight = DigitalBitGap = IMPLOT_AUTO;
11991204
Marker = IMPLOT_AUTO;
12001205
HasHidden = Hidden = false;

0 commit comments

Comments
 (0)