1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-10-09 23:57:26 -04:00

colormaps

This commit is contained in:
Evan Pezent 2020-06-02 12:34:14 -05:00
parent 468ffe9ead
commit 356e604bd2
3 changed files with 317 additions and 184 deletions

View File

@ -31,7 +31,7 @@ Below is a change-log of API breaking changes only. If you are using one of the
When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all implot files. When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all implot files.
You can read releases logs https://github.com/epezent/implot/releases for more details. You can read releases logs https://github.com/epezent/implot/releases for more details.
- 2020/06/01 (0.3) - SetPalette/RestorePalette were changed to SetColormap/RestoreColormap for consistency with other plotting libraries. - 2020/06/01 (0.3) - SetPalette was changed to `SetColormap` for consistency with other plotting libraries. `RestorePalette` was removed. Use `SetColormap(ImPlotColormap_Default)`.
- 2020/05/31 (0.3) - Plot functions taking custom ImVec2* getters were removed. Use the ImPlotPoint* getter versions instead. - 2020/05/31 (0.3) - Plot functions taking custom ImVec2* getters were removed. Use the ImPlotPoint* getter versions instead.
- 2020/05/29 (0.3) - The signature of ImPlotLimits::Contains was changed to take two doubles instead of ImVec2 - 2020/05/29 (0.3) - The signature of ImPlotLimits::Contains was changed to take two doubles instead of ImVec2
- 2020/05/16 (0.2) - All plotting functions were reverted to being prefixed with "Plot" to maintain a consistent VerbNoun style. `Plot` was split into `PlotLine` - 2020/05/16 (0.2) - All plotting functions were reverted to being prefixed with "Plot" to maintain a consistent VerbNoun style. `Plot` was split into `PlotLine`
@ -141,6 +141,16 @@ namespace {
// Private Utils // Private Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <int Count>
struct OffsetCalculator {
OffsetCalculator(int* sizes) {
Offsets[0] = 0;
for (int i = 1; i < Count; ++i)
Offsets[i] = Offsets[i-1] + sizes[i-1];
}
int Offsets[Count];
};
/// Returns true if a flag is set /// Returns true if a flag is set
template <typename TSet, typename TFlag> template <typename TSet, typename TFlag>
inline bool HasFlag(TSet set, TFlag flag) { inline bool HasFlag(TSet set, TFlag flag) {
@ -179,33 +189,6 @@ inline bool NanOrInf(double val) {
return val == HUGE_VAL || val == -HUGE_VAL || isnan(val); return val == HUGE_VAL || val == -HUGE_VAL || isnan(val);
} }
/// Utility function to that rounds x to powers of 2,5 and 10 for generating axis labels
/// Taken from Graphics Gems 1 Chapter 11.2, "Nice Numbers for Graph Labels"
inline double NiceNum(double x, bool round) {
double f; /* fractional part of x */
double nf; /* nice, rounded fraction */
int expv = (int)floor(ImLog10(x));
f = x / ImPow(10.0, (double)expv); /* between 1 and 10 */
if (round)
if (f < 1.5)
nf = 1;
else if (f < 3)
nf = 2;
else if (f < 7)
nf = 5;
else
nf = 10;
else if (f <= 1)
nf = 1;
else if (f <= 2)
nf = 2;
else if (f <= 5)
nf = 5;
else
nf = 10;
return nf * ImPow(10.0, expv);
}
/// Draws vertical text. The position is the bottom left of the text rect. /// Draws vertical text. The position is the bottom left of the text rect.
inline void AddTextVertical(ImDrawList *DrawList, const char *text, ImVec2 pos, ImU32 text_color) { inline void AddTextVertical(ImDrawList *DrawList, const char *text, ImVec2 pos, ImU32 text_color) {
pos.x = IM_ROUND(pos.x); pos.x = IM_ROUND(pos.x);
@ -336,7 +319,7 @@ struct ImPlotContext {
ImPlotContext() : RenderX(), RenderY() { ImPlotContext() : RenderX(), RenderY() {
CurrentPlot = NULL; CurrentPlot = NULL;
FitThisFrame = FitX = false; FitThisFrame = FitX = false;
RestoreColormap(); SetColormap(ImPlotColormap_Default);
} }
/// ALl Plots /// ALl Plots
@ -387,7 +370,8 @@ struct ImPlotContext {
// Mouse pos // Mouse pos
ImPlotPoint LastMousePos[MAX_Y_AXES]; ImPlotPoint LastMousePos[MAX_Y_AXES];
// Style // Style
ImVector<ImVec4> Colormap; ImVec4* Colormap;
int ColormapSize;
ImPlotStyle Style; ImPlotStyle Style;
ImVector<ImGuiColorMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector<ImGuiColorMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
@ -406,7 +390,7 @@ static ImPlotContext gp;
/// Returns the next unused default plot color /// Returns the next unused default plot color
ImVec4 NextColor() { ImVec4 NextColor() {
ImVec4 col = gp.Colormap[gp.CurrentPlot->ColorIdx % gp.Colormap.size()]; ImVec4 col = gp.Colormap[gp.CurrentPlot->ColorIdx % gp.ColormapSize];
gp.CurrentPlot->ColorIdx++; gp.CurrentPlot->ColorIdx++;
return col; return col;
} }
@ -553,6 +537,33 @@ struct TransformerLogLog {
// Legend Utils // Legend Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// Utility function to that rounds x to powers of 2,5 and 10 for generating axis labels
/// Taken from Graphics Gems 1 Chapter 11.2, "Nice Numbers for Graph Labels"
inline double NiceNum(double x, bool round) {
double f; /* fractional part of x */
double nf; /* nice, rounded fraction */
int expv = (int)floor(ImLog10(x));
f = x / ImPow(10.0, (double)expv); /* between 1 and 10 */
if (round)
if (f < 1.5)
nf = 1;
else if (f < 3)
nf = 2;
else if (f < 7)
nf = 5;
else
nf = 10;
else if (f <= 1)
nf = 1;
else if (f <= 2)
nf = 2;
else if (f <= 5)
nf = 5;
else
nf = 10;
return nf * ImPow(10.0, expv);
}
ImPlotItem* RegisterItem(const char* label_id) { ImPlotItem* RegisterItem(const char* label_id) {
ImGuiID id = ImGui::GetID(label_id); ImGuiID id = ImGui::GetID(label_id);
ImPlotItem* item = gp.CurrentPlot->Items.GetOrAddByKey(id); ImPlotItem* item = gp.CurrentPlot->Items.GetOrAddByKey(id);
@ -1868,107 +1879,6 @@ ImPlotStyle& GetStyle() {
return gp.Style; return gp.Style;
} }
void SetColormap(const ImVec4* colors, int num_colors) {
gp.Colormap.shrink(0);
gp.Colormap.reserve(num_colors);
for (int i = 0; i < num_colors; ++i) {
gp.Colormap.push_back(colors[i]);
}
}
void SetColormap(ImPlotColormap colormap) {
static ImVec4 maps[ImPlotColormap_COUNT][10] {
// ImPlotColormap_Default
{
ImVec4((0.0F), (0.7490196228F), (1.0F), (1.0F)), // Blues::DeepSkyBlue,
ImVec4((1.0F), (0.0F), (0.0F), (1.0F)), // Reds::Red,
ImVec4((0.4980392158F), (1.0F), (0.0F), (1.0F)), // Greens::Chartreuse,
ImVec4((1.0F), (1.0F), (0.0F), (1.0F)), // Yellows::Yellow,
ImVec4((0.0F), (1.0F), (1.0F), (1.0F)), // Cyans::Cyan,
ImVec4((1.0F), (0.6470588446F), (0.0F), (1.0F)), // Oranges::Orange,
ImVec4((1.0F), (0.0F), (1.0F), (1.0F)), // Purples::Magenta,
ImVec4((0.5411764979F), (0.1686274558F), (0.8862745166F), (1.0F)), // Purples::BlueViolet,
ImVec4((0.5f), (0.5f), (0.5f), (1.0F)), // Grays::Gray50,
ImVec4((0.8235294223F), (0.7058823705F), (0.5490196347F), (1.0F)) // Browns::Tan
},
// ImPlotColormap_Viridis
{
ImVec4(0.267004f, 0.004874f, 0.329415f, 1.f),
ImVec4(0.281412f, 0.155834f, 0.469201f, 1.f),
ImVec4(0.244972f, 0.287675f, 0.53726f, 1.f),
ImVec4(0.190631f, 0.407061f, 0.556089f, 1.f),
ImVec4(0.147607f, 0.511733f, 0.557049f, 1.f),
ImVec4(0.119699f, 0.618490f, 0.536347f, 1.f),
ImVec4(0.208030f, 0.718701f, 0.472873f, 1.f),
ImVec4(0.430983f, 0.808473f, 0.346476f, 1.f),
ImVec4(0.709898f, 0.868751f, 0.169257f, 1.f),
ImVec4(0.993248f, 0.906157f, 0.143936f, 1.f )
},
// ImPlotColormap_Plasma
{
ImVec4(0.050383f, 0.029803f, 0.527975f, 1.f),
ImVec4(0.274191f, 0.012109f, 0.622722f, 1.f),
ImVec4(0.447714f, 0.002080f, 0.660240f, 1.f),
ImVec4(0.610667f, 0.090204f, 0.619951f, 1.f),
ImVec4(0.740143f, 0.213864f, 0.524216f, 1.f),
ImVec4(0.846788f, 0.342551f, 0.420579f, 1.f),
ImVec4(0.928329f, 0.472975f, 0.326067f, 1.f),
ImVec4(0.983041f, 0.624131f, 0.227937f, 1.f),
ImVec4(0.991209f, 0.790537f, 0.149377f, 1.f),
ImVec4(0.940015f, 0.975158f, 0.131326f, 1.f)
},
// ImPlotColormap_Hot
{
ImVec4(0.3333f, 0.0f, 0.0f, 1.0f),
ImVec4(0.6667f, 0.0f, 0.0f, 1.0f),
ImVec4(1.0000f, 0.0f, 0.0f, 1.0f),
ImVec4(1.0000f, 0.3333f, 0.0f, 1.0f),
ImVec4(1.0000f, 0.6667f, 0.0f, 1.0f),
ImVec4(1.0000f, 1.0000f, 0.0f, 1.0f),
ImVec4(1.0000f, 1.0000f, 0.2500f, 1.0f),
ImVec4(1.0000f, 1.0000f, 0.5000f, 1.0f),
ImVec4(1.0000f, 1.0000f, 0.7500f, 1.0f),
ImVec4(1.0000f, 1.0000f, 1.0000f, 1.0f)
},
// ImPlotColormap_Cool
{
ImVec4( 0.0f, 1.0000f, 1.0000f, 1.0f),
ImVec4(0.1111f, 0.8889f, 1.0000f, 1.0f),
ImVec4(0.2222f, 0.7778f, 1.0000f, 1.0f),
ImVec4(0.3333f, 0.6667f, 1.0000f, 1.0f),
ImVec4(0.4444f, 0.5556f, 1.0000f, 1.0f),
ImVec4(0.5556f, 0.4444f, 1.0000f, 1.0f),
ImVec4(0.6667f, 0.3333f, 1.0000f, 1.0f),
ImVec4(0.7778f, 0.2222f, 1.0000f, 1.0f),
ImVec4(0.8889f, 0.1111f, 1.0000f, 1.0f),
ImVec4(1.0000f, 0.0f, 1.0000f, 1.0f)
}
// ImPlotColormap_Spring
// ImPlotColormap_Summer
// ImPlotColormap_Autumn
// ImPlotColormap_Winter
};
SetColormap(maps[colormap], 10);
}
/// Returns the next unused default plot color
void RestoreColormap() {
SetColormap(ImPlotColormap_Default);
}
ImVec4 SampleColormap(float t) {
t = ImClamp(t,0.0f,1.0f);
int i1 = (int)((gp.Colormap.Size-1) * t);
int i2 = i1 + 1;
if (i2 == gp.Colormap.Size)
return gp.Colormap[i1];
float t1 = (float)i1 / (float)gp.Colormap.Size;
float t2 = (float)i2 / (float)gp.Colormap.Size;
t = Remap(t, t1, t2, 0.0f, 1.0f);
return ImLerp(gp.Colormap[i1],gp.Colormap[i2],t);
}
void PushStyleColor(ImPlotCol idx, ImU32 col) { void PushStyleColor(ImPlotCol idx, ImU32 col) {
ImGuiColorMod backup; ImGuiColorMod backup;
backup.Col = idx; backup.Col = idx;
@ -2200,6 +2110,34 @@ inline void RenderLine(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p2,
DrawList._VtxCurrentIdx += 4; DrawList._VtxCurrentIdx += 4;
} }
inline void RenderRect(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p2, ImU32 col, ImVec2 uv) {
DrawList._VtxWritePtr[0].pos.x = p1.x;
DrawList._VtxWritePtr[0].pos.y = p1.y;
DrawList._VtxWritePtr[0].uv = uv;
DrawList._VtxWritePtr[0].col = col;
DrawList._VtxWritePtr[1].pos.x = p2.x;
DrawList._VtxWritePtr[1].pos.y = p1.y;
DrawList._VtxWritePtr[1].uv = uv;
DrawList._VtxWritePtr[1].col = col;
DrawList._VtxWritePtr[2].pos.x = p2.x;
DrawList._VtxWritePtr[2].pos.y = p2.y;
DrawList._VtxWritePtr[2].uv = uv;
DrawList._VtxWritePtr[2].col = col;
DrawList._VtxWritePtr[3].pos.x = p1.x;
DrawList._VtxWritePtr[3].pos.y = p2.y;
DrawList._VtxWritePtr[3].uv = uv;
DrawList._VtxWritePtr[3].col = col;
DrawList._VtxWritePtr += 4;
DrawList._IdxWritePtr[0] = (ImDrawIdx)(DrawList._VtxCurrentIdx);
DrawList._IdxWritePtr[1] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
DrawList._IdxWritePtr[2] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 3);
DrawList._IdxWritePtr[3] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1);
DrawList._IdxWritePtr[4] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 2);
DrawList._IdxWritePtr[5] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 3);
DrawList._IdxWritePtr += 6;
DrawList._VtxCurrentIdx += 4;
}
inline void RenderFill(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p2, float zero, ImU32 col_fill, ImVec2 uv) { inline void RenderFill(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p2, float zero, ImU32 col_fill, ImVec2 uv) {
const int crosses_zero = (p1.y > zero && p2.y < zero) || (p1.y < zero && p2.y > zero); // could do y*y < 0 earlier on const int crosses_zero = (p1.y > zero && p2.y < zero) || (p1.y < zero && p2.y > zero); // could do y*y < 0 earlier on
const float xmid = p1.x + (p2.x - p1.x) / (p2.y-p1.y) * (zero - p1.y); const float xmid = p1.x + (p2.x - p1.x) / (p2.y-p1.y) * (zero - p1.y);
@ -2903,40 +2841,54 @@ void PlotPieChart(const char** label_ids, double* values, int count, double x, d
// PLOT HEATMAP // PLOT HEATMAP
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void PlotHeatmap(const char* label_id, const double* values, int rows, int cols, double scale_min, double scale_max, bool show_labels) { void PlotHeatmap(const char* label_id, const double* values, int rows, int cols, double scale_min, double scale_max, bool show_labels, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max) {
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotHeatmap() Needs to be called between BeginPlot() and EndPlot()!"); IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotHeatmap() Needs to be called between BeginPlot() and EndPlot()!");
ImPlotItem* item = RegisterItem(label_id); ImPlotItem* item = RegisterItem(label_id);
if (!item->Show) if (!item->Show)
return; return;
if (gp.FitThisFrame) { if (gp.FitThisFrame) {
FitPoint(ImPlotPoint(0, 0)); FitPoint(bounds_min);
FitPoint(ImPlotPoint(1, 1)); FitPoint(bounds_max);
} }
ImDrawList& DrawList = *ImGui::GetWindowDrawList(); ImDrawList& DrawList = *ImGui::GetWindowDrawList();
double w = 1.0 / cols; const double w = (bounds_max.x - bounds_min.x) / cols;
double h = 1.0 / rows; const double h = (bounds_max.y - bounds_min.y) / rows;
const ImPlotPoint half_size(w*0.5,h*0.5); const ImPlotPoint half_size(w*0.5,h*0.5);
ImGui::PushClipRect(gp.BB_Grid.Min, gp.BB_Grid.Max, true); const int n = rows * cols;
int i = 0; int i = 0;
ImGui::PushClipRect(gp.BB_Grid.Min, gp.BB_Grid.Max, true);
DrawList.PrimReserve(6*n, 4*n);
const ImVec2 uv = DrawList._Data->TexUvWhitePixel;
for (int r = 0; r < rows; ++r) { for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) { for (int c = 0; c < cols; ++c) {
ImPlotPoint p; ImPlotPoint p;
p.x = 0.5*w + c*w; p.x = bounds_min.x + 0.5*w + c*w;
p.y = 1 - (0.5*h + r*h); p.y = bounds_min.y + 1 - (0.5*h + r*h);
ImVec2 px = PlotToPixels(p); ImVec2 px = PlotToPixels(p);
ImVec2 a = PlotToPixels(p.x - half_size.x, p.y - half_size.y); ImVec2 a = PlotToPixels(p.x - half_size.x, p.y - half_size.y);
ImVec2 b = PlotToPixels(p.x + half_size.x, p.y + half_size.y); ImVec2 b = PlotToPixels(p.x + half_size.x, p.y + half_size.y);
float t = (float)Remap(values[i], scale_min, scale_max, 0.0, 1.0); float t = (float)Remap(values[i], scale_min, scale_max, 0.0, 1.0);
ImVec4 color = SampleColormap(t); ImVec4 color = LerpColormap(t);
DrawList.AddRectFilled(a, b, ImGui::GetColorU32(color)); // DrawList.AddRectFilled(a, b, ImGui::GetColorU32(color));
if (show_labels) { RenderRect(DrawList, a, b, ImGui::GetColorU32(color), uv);
i++;
}
}
if (show_labels) {
// this has to go in its own loop due to PrimReserve above
i = 0;
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
ImPlotPoint p;
p.x = bounds_min.x + 0.5*w + c*w;
p.y = bounds_min.y + 1 - (0.5*h + r*h);
ImVec2 px = PlotToPixels(p);
char buff[32]; char buff[32];
sprintf(buff, "%g", values[i]); sprintf(buff, "%g", values[i]);
ImVec2 size = ImGui::CalcTextSize(buff); ImVec2 size = ImGui::CalcTextSize(buff);
DrawList.AddText(px - size * 0.5f, ImGui::GetColorU32(ImGuiCol_Text), buff); DrawList.AddText(px - size * 0.5f, ImGui::GetColorU32(ImGuiCol_Text), buff);
i++;
} }
i++;
} }
} }
ImGui::PopClipRect(); ImGui::PopClipRect();
@ -3066,4 +3018,168 @@ void PlotText(const char* text, double x, double y, bool vertical, const ImVec2&
PopPlotClipRect(); PopPlotClipRect();
} }
//------------------------------------------------------------------------------
// COLORMAPS
//------------------------------------------------------------------------------
void SetColormap(const ImVec4* colors, int num_colors) {
IM_ASSERT_USER_ERROR(num_colors > 0, "The number of colors cannot be 0!");
static ImVector<ImVec4> user_colormap;
user_colormap.shrink(0);
user_colormap.reserve(num_colors);
for (int i = 0; i < num_colors; ++i)
user_colormap.push_back(colors[i]);
gp.Colormap = &user_colormap[0];
gp.ColormapSize = num_colors;
}
// Returns the size of the current colormap
int GetColormapSize() {
return gp.ColormapSize;
}
/// Returns a color from the Color map given an index > 0
ImVec4 GetColormapColor(int index) {
IM_ASSERT_USER_ERROR(index >= 0, "The Colormap index must be greater than zero!");
return gp.Colormap[index % gp.ColormapSize];
}
ImVec4 LerpColormap(float t) {
t = ImClamp(t,0.0f,1.0f);
int i1 = (int)((gp.ColormapSize-1) * t);
int i2 = i1 + 1;
if (i2 == gp.ColormapSize)
return gp.Colormap[i1];
float t1 = (float)i1 / (float)gp.ColormapSize;
float t2 = (float)i2 / (float)gp.ColormapSize;
t = Remap(t, t1, t2, 0.0f, 1.0f);
return ImLerp(gp.Colormap[i1], gp.Colormap[i2], t);
}
void SetColormap(ImPlotColormap colormap) {
static int csizes[ImPlotColormap_COUNT] = {10,9,9,12,11,11,11,11,11,11};
static OffsetCalculator<ImPlotCol_COUNT> coffs(csizes);
static ImVec4 cdata[] {
// ImPlotColormap_Default // X11 Named Colors
ImVec4(0.0f, 0.7490196228f, 1.0f, 1.0f), // Blues::DeepSkyBlue,
ImVec4(1.0f, 0.0f, 0.0f, 1.0f), // Reds::Red,
ImVec4(0.4980392158f, 1.0f, 0.0f, 1.0f), // Greens::Chartreuse,
ImVec4(1.0f, 1.0f, 0.0f, 1.0f), // Yellows::Yellow,
ImVec4(0.0f, 1.0f, 1.0f, 1.0f), // Cyans::Cyan,
ImVec4(1.0f, 0.6470588446f, 0.0f, 1.0f), // Oranges::Orange,
ImVec4(1.0f, 0.0f, 1.0f, 1.0f), // Purples::Magenta,
ImVec4(0.5411764979f, 0.1686274558f, 0.8862745166f, 1.0f), // Purples::BlueViolet,
ImVec4(0.5f, 0.5f, 0.5f, 1.0f), // Grays::Gray50,
ImVec4(0.8235294223f, 0.7058823705f, 0.5490196347f, 1.0f), // Browns::Tan
// ImPlotColormap_Dark
ImVec4(0.894118f, 0.101961f, 0.109804f, 1.0f),
ImVec4(0.215686f, 0.494118f, 0.721569f, 1.0f),
ImVec4(0.301961f, 0.686275f, 0.290196f, 1.0f),
ImVec4(0.596078f, 0.305882f, 0.639216f, 1.0f),
ImVec4(1.000000f, 0.498039f, 0.000000f, 1.0f),
ImVec4(1.000000f, 1.000000f, 0.200000f, 1.0f),
ImVec4(0.650980f, 0.337255f, 0.156863f, 1.0f),
ImVec4(0.968627f, 0.505882f, 0.749020f, 1.0f),
ImVec4(0.600000f, 0.600000f, 0.600000f, 1.0f),
// ImPlotColormap_Pastel
ImVec4(0.984314f, 0.705882f, 0.682353f, 1.0f),
ImVec4(0.701961f, 0.803922f, 0.890196f, 1.0f),
ImVec4(0.800000f, 0.921569f, 0.772549f, 1.0f),
ImVec4(0.870588f, 0.796078f, 0.894118f, 1.0f),
ImVec4(0.996078f, 0.850980f, 0.650980f, 1.0f),
ImVec4(1.000000f, 1.000000f, 0.800000f, 1.0f),
ImVec4(0.898039f, 0.847059f, 0.741176f, 1.0f),
ImVec4(0.992157f, 0.854902f, 0.925490f, 1.0f),
ImVec4(0.949020f, 0.949020f, 0.949020f, 1.0f),
// ImPlotColormap_Paired
ImVec4(0.258824f, 0.807843f, 0.890196f, 1.0f),
ImVec4(0.121569f, 0.470588f, 0.705882f, 1.0f),
ImVec4(0.698039f, 0.874510f, 0.541176f, 1.0f),
ImVec4(0.200000f, 0.627451f, 0.172549f, 1.0f),
ImVec4(0.984314f, 0.603922f, 0.600000f, 1.0f),
ImVec4(0.890196f, 0.101961f, 0.109804f, 1.0f),
ImVec4(0.992157f, 0.749020f, 0.435294f, 1.0f),
ImVec4(1.000000f, 0.498039f, 0.000000f, 1.0f),
ImVec4(0.792157f, 0.698039f, 0.839216f, 1.0f),
ImVec4(0.415686f, 0.239216f, 0.603922f, 1.0f),
ImVec4(1.000000f, 1.000000f, 0.600000f, 1.0f),
ImVec4(0.694118f, 0.349020f, 0.156863f, 1.0f),
// ImPlotColormap_Viridis
ImVec4(0.267004f, 0.004874f, 0.329415f, 1.0f),
ImVec4(0.282623f, 0.140926f, 0.457517f, 1.0f),
ImVec4(0.253935f, 0.265254f, 0.529983f, 1.0f),
ImVec4(0.206756f, 0.371758f, 0.553117f, 1.0f),
ImVec4(0.163625f, 0.471133f, 0.558148f, 1.0f),
ImVec4(0.127568f, 0.566949f, 0.550556f, 1.0f),
ImVec4(0.134692f, 0.658636f, 0.517649f, 1.0f),
ImVec4(0.266941f, 0.748751f, 0.440573f, 1.0f),
ImVec4(0.477504f, 0.821444f, 0.318195f, 1.0f),
ImVec4(0.741388f, 0.873449f, 0.149561f, 1.0f),
ImVec4(0.993248f, 0.906157f, 0.143936f, 1.0f),
// ImPlotColormap_Plasma
ImVec4(5.03830e-02f, 2.98030e-02f, 5.27975e-01f, 1.00000e+00f),
ImVec4(2.54627e-01f, 1.38820e-02f, 6.15419e-01f, 1.00000e+00f),
ImVec4(4.17642e-01f, 5.64000e-04f, 6.58390e-01f, 1.00000e+00f),
ImVec4(5.62738e-01f, 5.15450e-02f, 6.41509e-01f, 1.00000e+00f),
ImVec4(6.92840e-01f, 1.65141e-01f, 5.64522e-01f, 1.00000e+00f),
ImVec4(7.98216e-01f, 2.80197e-01f, 4.69538e-01f, 1.00000e+00f),
ImVec4(8.81443e-01f, 3.92529e-01f, 3.83229e-01f, 1.00000e+00f),
ImVec4(9.49217e-01f, 5.17763e-01f, 2.95662e-01f, 1.00000e+00f),
ImVec4(9.88260e-01f, 6.52325e-01f, 2.11364e-01f, 1.00000e+00f),
ImVec4(9.88648e-01f, 8.09579e-01f, 1.45357e-01f, 1.00000e+00f),
ImVec4(9.40015e-01f, 9.75158e-01f, 1.31326e-01f, 1.00000e+00f),
// ImPlotColormap_Hot
ImVec4(0.2500f, 0.f, 0.f, 1.0f),
ImVec4(0.5000f, 0.f, 0.f, 1.0f),
ImVec4(0.7500f, 0.f, 0.f, 1.0f),
ImVec4(1.0000f, 0.f, 0.f, 1.0f),
ImVec4(1.0000f, 0.2500f, 0.f, 1.0f),
ImVec4(1.0000f, 0.5000f, 0.f, 1.0f),
ImVec4(1.0000f, 0.7500f, 0.f, 1.0f),
ImVec4(1.0000f, 1.0000f, 0.f, 1.0f),
ImVec4(1.0000f, 1.0000f, 0.3333f, 1.0f),
ImVec4(1.0000f, 1.0000f, 0.6667f, 1.0f),
ImVec4(1.0000f, 1.0000f, 1.0000f, 1.0f),
// ImPlotColormap_Cool
ImVec4( 0.f, 1.0000f, 1.0000f, 1.0f),
ImVec4(0.1000f, 0.9000f, 1.0000f, 1.0f),
ImVec4(0.2000f, 0.8000f, 1.0000f, 1.0f),
ImVec4(0.3000f, 0.7000f, 1.0000f, 1.0f),
ImVec4(0.4000f, 0.6000f, 1.0000f, 1.0f),
ImVec4(0.5000f, 0.5000f, 1.0000f, 1.0f),
ImVec4(0.6000f, 0.4000f, 1.0000f, 1.0f),
ImVec4(0.7000f, 0.3000f, 1.0000f, 1.0f),
ImVec4(0.8000f, 0.2000f, 1.0000f, 1.0f),
ImVec4(0.9000f, 0.1000f, 1.0000f, 1.0f),
ImVec4(1.0000f, 0.f, 1.0000f, 1.0f),
// ImPlotColormap_Pink
ImVec4(0.2887f, 0.f, 0.f, 1.0f),
ImVec4(0.4830f, 0.2582f, 0.2582f, 1.0f),
ImVec4(0.6191f, 0.3651f, 0.3651f, 1.0f),
ImVec4(0.7303f, 0.4472f, 0.4472f, 1.0f),
ImVec4(0.7746f, 0.5916f, 0.5164f, 1.0f),
ImVec4(0.8165f, 0.7071f, 0.5774f, 1.0f),
ImVec4(0.8563f, 0.8062f, 0.6325f, 1.0f),
ImVec4(0.8944f, 0.8944f, 0.6831f, 1.0f),
ImVec4(0.9309f, 0.9309f, 0.8028f, 1.0f),
ImVec4(0.9661f, 0.9661f, 0.9068f, 1.0f),
ImVec4(1.0000f, 1.0000f, 1.0000f, 1.0f),
// ImPlotColormap_Jet
ImVec4( 0.f, 0.f, 0.6667f, 1.0f),
ImVec4( 0.f, 0.f, 1.0000f, 1.0f),
ImVec4( 0.f, 0.3333f, 1.0000f, 1.0f),
ImVec4( 0.f, 0.6667f, 1.0000f, 1.0f),
ImVec4( 0.f, 1.0000f, 1.0000f, 1.0f),
ImVec4(0.3333f, 1.0000f, 0.6667f, 1.0f),
ImVec4(0.6667f, 1.0000f, 0.3333f, 1.0f),
ImVec4(1.0000f, 1.0000f, 0.f, 1.0f),
ImVec4(1.0000f, 0.6667f, 0.f, 1.0f),
ImVec4(1.0000f, 0.3333f, 0.f, 1.0f),
ImVec4(1.0000f, 0.f, 0.f, 1.0f)
};
// TODO: Calculate offsets at compile time
gp.Colormap = &cdata[coffs.Offsets[colormap]];
gp.ColormapSize = csizes[colormap];
}
} // namespace ImPlot } // namespace ImPlot

View File

@ -117,19 +117,16 @@ enum ImPlotMarker_ {
// Built-in colormaps // Built-in colormaps
enum ImPlotColormap_ { enum ImPlotColormap_ {
// Qualitative ImPlotColormap_Default = 0, // ImPlot default colormap (n=10)
ImPlotColormap_Default, ImPlotColormap_Dark = 1, // a.k.a. matplotlib "Set1" (n=9)
// Sequential ImPlotColormap_Pastel = 2, // a.k.a. matplotlib "Pastel1" (n=9)
ImPlotColormap_Viridis, ImPlotColormap_Paired = 3, // a.k.a. matplotlib "Paired" (n=12)
ImPlotColormap_Plasma, ImPlotColormap_Viridis = 4, // a.k.a. matplotlib "viridis" (n=11)
ImPlotColormap_Hot, ImPlotColormap_Plasma = 5, // a.k.a. matplotlib "plasma" (n=11)
ImPlotColormap_Cool, ImPlotColormap_Hot = 6, // a.k.a. matplotlib/MATLAB "hot" (n=11)
// ImPlotColormap_Spring, ImPlotColormap_Cool = 7, // a.k.a. matplotlib/MATLAB "cool" (n=11)
// ImPlotColormap_Summer, ImPlotColormap_Pink = 8, // a.k.a. matplotlib/MATLAB "pink" (n=11)
// ImPlotColormap_Autumn, ImPlotColormap_Jet = 9, // a.k.a. MATLAB "jet" (n=11)
// ImPlotColormap_Winter,
// Diverging
// ...
ImPlotColormap_COUNT ImPlotColormap_COUNT
}; };
@ -246,7 +243,7 @@ void PlotPieChart(const char** label_ids, float* values, int count, float x, flo
void PlotPieChart(const char** label_ids, double* values, int count, double x, double y, double radius, bool show_percents = true, double angle0 = 90); void PlotPieChart(const char** label_ids, double* values, int count, double x, double y, double radius, bool show_percents = true, double angle0 = 90);
// Plots a 2D heatmap chart. Values are expected to be in row-major order. // Plots a 2D heatmap chart. Values are expected to be in row-major order.
void PlotHeatmap(const char* label_id, const double* values, int rows, int cols, double scale_min, double scale_max, bool show_labels = true); void PlotHeatmap(const char* label_id, const double* values, int rows, int cols, double scale_min, double scale_max, bool show_labels = true, const ImPlotPoint& bounds_min = ImPlotPoint(0,0), const ImPlotPoint& bounds_max = ImPlotPoint(1,1));
// Plots digital data. // Plots digital data.
void PlotDigital(const char* label_id, const float* xs, const float* ys, int count, int offset = 0, int stride = sizeof(float)); void PlotDigital(const char* label_id, const float* xs, const float* ys, int count, int offset = 0, int stride = sizeof(float));
@ -279,15 +276,6 @@ ImPlotLimits GetPlotQuery(int y_axis = -1);
// Provides access to plot style structure for permanant modifications to colors, sizes, etc. // Provides access to plot style structure for permanant modifications to colors, sizes, etc.
ImPlotStyle& GetStyle(); ImPlotStyle& GetStyle();
// Switch to one of the built-in colormaps for plot items.
void SetColormap(ImPlotColormap colormap);
// Sets a custom colormap to be used for plot items.
void SetColormap(const ImVec4* colors, int num_colors);
// Restores the default ImPlot colormap.
void RestoreColormap();
// Linearly interpolates a color from the current colormap/
ImVec4 SampleColormap(float t);
// Temporarily modify a plot color. Don't forget to call PopStyleColor! // Temporarily modify a plot color. Don't forget to call PopStyleColor!
void PushStyleColor(ImPlotCol idx, ImU32 col); void PushStyleColor(ImPlotCol idx, ImU32 col);
// Temporarily modify a plot color. Don't forget to call PopStyleColor! // Temporarily modify a plot color. Don't forget to call PopStyleColor!
@ -302,6 +290,17 @@ void PushStyleVar(ImPlotStyleVar idx, int val);
// Undo temporary style modification. // Undo temporary style modification.
void PopStyleVar(int count = 1); void PopStyleVar(int count = 1);
// Switch to one of the built-in colormaps.
void SetColormap(ImPlotColormap colormap);
// Sets a custom colormap.
void SetColormap(const ImVec4* colors, int num_colors);
// Returns the size of the current colormap
int GetColormapSize();
/// Returns a color from the Color map given an index > 0 (modulo will be performed)
ImVec4 GetColormapColor(int index);
// Linearly interpolates a color from the current colormap given t between 0 and 1.
ImVec4 LerpColormap(float t);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Plot Utils // Plot Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -124,6 +124,7 @@ struct BenchmarkItem {
namespace ImPlot { namespace ImPlot {
void ShowDemoWindow(bool* p_open) { void ShowDemoWindow(bool* p_open) {
static const char* cmap_names[] = {"Default","Dark","Pastel","Paired","Viridis","Plasma","Hot","Cool","Pink","Jet"};
static bool show_app_metrics = false; static bool show_app_metrics = false;
static bool show_app_style_editor = false; static bool show_app_style_editor = false;
if (show_app_metrics) { ImGui::ShowMetricsWindow(&show_app_metrics); } if (show_app_metrics) { ImGui::ShowMetricsWindow(&show_app_metrics); }
@ -140,7 +141,7 @@ void ShowDemoWindow(bool* p_open) {
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
ImGui::Text("ImPlot says hello. (0.2 WIP)"); ImGui::Text("ImPlot says hello. (0.3 WIP)");
if (ImGui::CollapsingHeader("Help")) { if (ImGui::CollapsingHeader("Help")) {
ImGui::Text("USER GUIDE:"); ImGui::Text("USER GUIDE:");
ImGui::BulletText("Left click and drag within the plot area to pan X and Y axes."); ImGui::BulletText("Left click and drag within the plot area to pan X and Y axes.");
@ -264,6 +265,7 @@ void ShowDemoWindow(bool* p_open) {
ImPlot::PlotBars("Final Exam", final, 10, 0.2f, 0); ImPlot::PlotBars("Final Exam", final, 10, 0.2f, 0);
ImPlot::PlotBars("Course Grade", grade, 10, 0.2f, 0.2f); ImPlot::PlotBars("Course Grade", grade, 10, 0.2f, 0.2f);
} }
ImPlot::SetColormap(ImPlotColormap_Default);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
} }
@ -312,40 +314,46 @@ void ShowDemoWindow(bool* p_open) {
static const char* labels2[] = {"One","Two","Three","Four","Five"}; static const char* labels2[] = {"One","Two","Three","Four","Five"};
static t_float not_normalized[] = {1,2,3,4,5}; static t_float not_normalized[] = {1,2,3,4,5};
if (ImPlot::BeginPlot("##Pie2", NULL, NULL, ImVec2(250,250), ImPlotFlags_Legend, 0, 0)) { if (ImPlot::BeginPlot("##Pie2", NULL, NULL, ImVec2(250,250), ImPlotFlags_Legend, 0, 0)) {
ImPlot::PlotPieChart(labels2, not_normalized, 5, 0.5f, 0.5f, 0.4f); ImPlot::PlotPieChart(labels2, not_normalized, 5, 0.5f, 0.5f, 0.4f, false, 0);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImPlot::RestoreColormap(); ImPlot::SetColormap(ImPlotColormap_Default);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Heatmaps")) { if (ImGui::CollapsingHeader("Heatmaps")) {
static double values1[7][7] = {{0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0}, static double values1[7][7] = {{0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0},
{2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0}, {2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0},
{1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0}, {1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0},
{0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0}, {0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0},
{0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0}, {0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0},
{1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1}, {1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1},
{0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3}}; {0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3}};
static float scale_min = 0;
static float scale_max = 6.3f;
static double values2[100*100]; static double values2[100*100];
for (int i = 0; i < 100*100; ++i) { for (int i = 0; i < 100*100; ++i) {
values2[i] = RandomRange(0,1); values2[i] = RandomRange(0,1);
} }
static ImPlotColormap map = ImPlotColormap_Viridis; static ImPlotColormap map = ImPlotColormap_Viridis;
if (ImGui::Button("Cycle Colormaps")) if (ImGui::Button("Cycle Colormap"))
map = (map + 1) % ImPlotColormap_COUNT; map = (map + 1) % ImPlotColormap_COUNT;
ImGui::SameLine();
ImGui::LabelText("##Colormap Index", cmap_names[map]);
ImGui::DragFloatRange2("Scale (Left Only)",&scale_min,&scale_max,0.01f);
static ImPlotAxisFlags axes_flags = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax; static ImPlotAxisFlags axes_flags = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax;
if (ImPlot::BeginPlot("##Heatmap1",NULL,NULL,ImVec2(250,250),0,axes_flags,axes_flags)) { if (ImPlot::BeginPlot("##Heatmap1",NULL,NULL,ImVec2(250,250),0,axes_flags,axes_flags)) {
ImPlot::SetColormap(map); ImPlot::SetColormap(map);
ImPlot::PlotHeatmap("heat",values1[0],7,7,0,6.3); ImPlot::PlotHeatmap("heat",values1[0],7,7,scale_min,scale_max);
ImPlot::EndPlot(); ImPlot::EndPlot();
ImPlot::RestoreColormap(); ImPlot::SetColormap(ImPlotColormap_Default);
} }
ImGui::SameLine(); ImGui::SameLine();
SetNextPlotLimits(1,2,1,2);
if (ImPlot::BeginPlot("##Heatmap2",NULL,NULL,ImVec2(250,250),0,axes_flags,axes_flags)) { if (ImPlot::BeginPlot("##Heatmap2",NULL,NULL,ImVec2(250,250),0,axes_flags,axes_flags)) {
ImPlot::SetColormap(map); ImPlot::SetColormap(map);
ImPlot::PlotHeatmap("heat",values2,100,100,0,1,false); ImPlot::PlotHeatmap("heat",values2,100,100,0,1,false,{1,1},{2,2});
ImPlot::EndPlot(); ImPlot::EndPlot();
ImPlot::RestoreColormap(); ImPlot::SetColormap(ImPlotColormap_Default);
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -379,9 +387,16 @@ void ShowDemoWindow(bool* p_open) {
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Markers and Text")) { if (ImGui::CollapsingHeader("Colormaps, Markers, and Text")) {
static ImPlotColormap map = ImPlotColormap_Default;
if (ImGui::Button("Cycle Colormap"))
map = (map + 1) % ImPlotColormap_COUNT;
ImGui::SameLine();
ImGui::LabelText("##Colormap Index", cmap_names[map]);
ImGui::PushID(map); // NB: The merely a workaround so that the demo can cycle color maps. You wouldn't need to do this in your own code!
ImPlot::SetNextPlotLimits(0, 10, 0, 12); ImPlot::SetNextPlotLimits(0, 10, 0, 12);
if (ImPlot::BeginPlot("##MarkerStyles", NULL, NULL, ImVec2(-1,0), 0, 0, 0)) { if (ImPlot::BeginPlot("##MarkerStyles", NULL, NULL, ImVec2(-1,0), 0, 0, 0)) {
ImPlot::SetColormap(map);
t_float xs[2] = {1,4}; t_float xs[2] = {1,4};
t_float ys[2] = {10,11}; t_float ys[2] = {10,11};
// filled // filled
@ -451,8 +466,11 @@ void ShowDemoWindow(bool* p_open) {
ImPlot::PlotText("Open Markers", 6.75, 11.75); ImPlot::PlotText("Open Markers", 6.75, 11.75);
ImPlot::PlotText("Fancy Markers", 4.5, 4.25, true); ImPlot::PlotText("Fancy Markers", 4.5, 4.25, true);
ImPlot::SetColormap(ImPlotColormap_Default);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImGui::PopID();
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Log Scale")) { if (ImGui::CollapsingHeader("Log Scale")) {
@ -841,7 +859,7 @@ void ShowDemoWindow(bool* p_open) {
} }
ImPlot::PopStyleColor(5); ImPlot::PopStyleColor(5);
ImPlot::PopStyleVar(); ImPlot::PopStyleVar();
ImPlot::RestoreColormap(); ImPlot::SetColormap(ImPlotColormap_Default);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Custom Rendering")) { if (ImGui::CollapsingHeader("Custom Rendering")) {