From ea51c41b4ae381ba809d15daccb730741977102f Mon Sep 17 00:00:00 2001 From: Evan Pezent Date: Tue, 2 Jun 2020 22:07:27 -0500 Subject: [PATCH] finish heatmaps --- implot.cpp | 213 +++++++++++++++++++++++++++++++++--------------- implot.h | 4 + implot_demo.cpp | 51 ++++++------ 3 files changed, 176 insertions(+), 92 deletions(-) diff --git a/implot.cpp b/implot.cpp index 94c3658..de4df52 100644 --- a/implot.cpp +++ b/implot.cpp @@ -537,33 +537,6 @@ struct TransformerLogLog { // 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) { ImGuiID id = ImGui::GetID(label_id); ImPlotItem* item = gp.CurrentPlot->Items.GetOrAddByKey(id); @@ -595,6 +568,33 @@ const char* GetLegendLabel(int i) { // Tick 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); +} + inline void GetTicks(const ImPlotRange& range, int nMajor, int nMinor, bool logscale, ImVector &out) { out.shrink(0); if (logscale) { @@ -616,7 +616,6 @@ inline void GetTicks(const ImPlotRange& range, int nMajor, int nMinor, bool logs } } else { - const double nice_range = NiceNum(range.Size() * 0.99, 0); const double interval = NiceNum(nice_range / (nMajor - 1), 1); const double graphmin = floor(range.Min / interval) * interval; @@ -1340,17 +1339,17 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons //----------------------------------------------------------------------------- template -bool Dragdouble(const char* label, F* v, float v_speed, F v_min, F v_max) { +bool DragFloat(const char* label, F* v, float v_speed, F v_min, F v_max) { return false; } template <> -bool Dragdouble(const char* label, double* v, float v_speed, double v_min, double v_max) { +bool DragFloat(const char* label, double* v, float v_speed, double v_min, double v_max) { return ImGui::DragScalar(label, ImGuiDataType_Double, v, v_speed, &v_min, &v_max, "%.3f", 1); } template <> -bool Dragdouble(const char* label, float* v, float v_speed, float v_min, float v_max) { +bool DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max) { return ImGui::DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, "%.3f", 1); } @@ -1370,7 +1369,7 @@ inline void AxisMenu(ImPlotAxis& Axis) { ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.25f); } - Dragdouble("Min", &Axis.Range.Min, 0.01f + 0.01f * (float)Axis.Range.Size(), -HUGE_VAL, Axis.Range.Max - DBL_EPSILON); + DragFloat("Min", &Axis.Range.Min, 0.01f + 0.01f * (float)Axis.Range.Size(), -HUGE_VAL, Axis.Range.Max - DBL_EPSILON); if (lock_min) { ImGui::PopItemFlag(); ImGui::PopStyleVar(); } @@ -1381,7 +1380,7 @@ inline void AxisMenu(ImPlotAxis& Axis) { if (lock_max) { ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.25f); } - Dragdouble("Max", &Axis.Range.Max, 0.01f + 0.01f * (float)Axis.Range.Size(), Axis.Range.Min + DBL_EPSILON, HUGE_VAL); + DragFloat("Max", &Axis.Range.Max, 0.01f + 0.01f * (float)Axis.Range.Size(), Axis.Range.Min + DBL_EPSILON, HUGE_VAL); if (lock_max) { ImGui::PopItemFlag(); ImGui::PopStyleVar(); @@ -1561,7 +1560,6 @@ void EndPlot() { gp.Col_Border, 1); } } - ImGui::PopClipRect(); PushPlotClipRect(); @@ -2110,23 +2108,23 @@ inline void RenderLine(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p2, DrawList._VtxCurrentIdx += 4; } -inline void RenderRect(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p2, ImU32 col, ImVec2 uv) { +inline void RenderRect(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p2, ImU32 col_ul, ImU32 col_ur, ImU32 col_bl, ImU32 col_br, 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[0].col = col_ul; 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[1].col = col_ur; 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[2].col = col_br; 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[3].col = col_bl; DrawList._VtxWritePtr += 4; DrawList._IdxWritePtr[0] = (ImDrawIdx)(DrawList._VtxCurrentIdx); DrawList._IdxWritePtr[1] = (ImDrawIdx)(DrawList._VtxCurrentIdx + 1); @@ -2841,22 +2839,13 @@ void PlotPieChart(const char** label_ids, double* values, int count, double x, d // PLOT HEATMAP //----------------------------------------------------------------------------- -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()!"); - ImPlotItem* item = RegisterItem(label_id); - if (!item->Show) - return; - if (gp.FitThisFrame) { - FitPoint(bounds_min); - FitPoint(bounds_max); - } - ImDrawList& DrawList = *ImGui::GetWindowDrawList(); +template +void RenderHeatmap(Transformer transformer, ImDrawList& DrawList, const T* values, int rows, int cols, T scale_min, T scale_max, bool show_labels, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max) { const double w = (bounds_max.x - bounds_min.x) / cols; const double h = (bounds_max.y - bounds_min.y) / rows; const ImPlotPoint half_size(w*0.5,h*0.5); const int n = rows * cols; 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) { @@ -2864,13 +2853,13 @@ void PlotHeatmap(const char* label_id, const double* values, int rows, int cols, 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); - 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); - float t = (float)Remap(values[i], scale_min, scale_max, 0.0, 1.0); + ImVec2 px = transformer(p); + ImVec2 a = transformer(p.x - half_size.x, p.y - half_size.y); + ImVec2 b = transformer(p.x + half_size.x, p.y + half_size.y); + float t = (float)Remap(values[i], scale_min, scale_max, T(0), T(1)); ImVec4 color = LerpColormap(t); - // DrawList.AddRectFilled(a, b, ImGui::GetColorU32(color)); - RenderRect(DrawList, a, b, ImGui::GetColorU32(color), uv); + ImU32 col = ImGui::GetColorU32(color); + RenderRect(DrawList, a, b, col, col, col, col, uv); i++; } } @@ -2882,7 +2871,7 @@ void PlotHeatmap(const char* label_id, const double* values, int rows, int cols, 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); + ImVec2 px = transformer(p); char buff[32]; sprintf(buff, "%g", values[i]); ImVec2 size = ImGui::CalcTextSize(buff); @@ -2891,9 +2880,48 @@ void PlotHeatmap(const char* label_id, const double* values, int rows, int cols, } } } +} + +template +void PlotHeatmapEx(const char* label_id, const T* values, int rows, int cols, T scale_min, T 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(scale_min != scale_max, "Scale values must be different!"); + ImPlotItem* item = RegisterItem(label_id); + if (!item->Show) + return; + if (gp.FitThisFrame) { + FitPoint(bounds_min); + FitPoint(bounds_max); + } + ImDrawList& DrawList = *ImGui::GetWindowDrawList(); + ImGui::PushClipRect(gp.BB_Grid.Min, gp.BB_Grid.Max, true); + ImPlotState* plot = gp.CurrentPlot; + int y_axis = plot->CurrentYAxis; + if (HasFlag(plot->XAxis.Flags, ImPlotAxisFlags_LogScale) && HasFlag(plot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale)) + RenderHeatmap(TransformerLogLog(y_axis), DrawList, values, rows, cols, scale_min, scale_max, show_labels, bounds_min, bounds_max); + else if (HasFlag(plot->XAxis.Flags, ImPlotAxisFlags_LogScale)) + RenderHeatmap(TransformerLogLin(y_axis), DrawList, values, rows, cols, scale_min, scale_max, show_labels, bounds_min, bounds_max); + else if (HasFlag(plot->YAxis[y_axis].Flags, ImPlotAxisFlags_LogScale)) + RenderHeatmap(TransformerLinLog(y_axis), DrawList, values, rows, cols, scale_min, scale_max, show_labels, bounds_min, bounds_max); + else + RenderHeatmap(TransformerLinLin(y_axis), DrawList, values, rows, cols, scale_min, scale_max, show_labels, bounds_min, bounds_max); ImGui::PopClipRect(); } +//----------------------------------------------------------------------------- +// float + +void PlotHeatmap(const char* label_id, const float* values, int rows, int cols, float scale_min, float scale_max, bool show_labels, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max) { + return PlotHeatmapEx(label_id, values, rows, cols, scale_min, scale_max, show_labels, bounds_min, bounds_max); +} + +//----------------------------------------------------------------------------- +// double + +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) { + return PlotHeatmapEx(label_id, values, rows, cols, scale_min, scale_max, show_labels, bounds_min, bounds_max); +} + //----------------------------------------------------------------------------- // PLOT DIGITAL //----------------------------------------------------------------------------- @@ -3023,12 +3051,12 @@ void PlotText(const char* text, double x, double y, bool vertical, const ImVec2& //------------------------------------------------------------------------------ void SetColormap(const ImVec4* colors, int num_colors) { - IM_ASSERT_USER_ERROR(num_colors > 0, "The number of colors cannot be 0!"); + IM_ASSERT_USER_ERROR(num_colors > 1, "The number of colors must be greater than 1!"); static ImVector 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]); + for (int i = 0; i < num_colors; ++i) + user_colormap.push_back(colors[i]); gp.Colormap = &user_colormap[0]; gp.ColormapSize = num_colors; } @@ -3045,15 +3073,68 @@ ImVec4 GetColormapColor(int index) { } ImVec4 LerpColormap(float t) { - t = ImClamp(t,0.0f,1.0f); - int i1 = (int)((gp.ColormapSize-1) * t); + float tc = ImClamp(t,0.0f,1.0f); + int i1 = (int)((gp.ColormapSize -1 ) * tc); 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); + float t1 = (float)i1 / (float)(gp.ColormapSize - 1); + float t2 = (float)i2 / (float)(gp.ColormapSize - 1); + float tr = Remap(t, t1, t2, 0.0f, 1.0f); + return ImLerp(gp.Colormap[i1], gp.Colormap[i2], tr); +} + +void ShowColormapScale(double scale_min, double scale_max, float height) { + static ImVector ticks; + static ImGuiTextBuffer txt_buff; + ImPlotRange range; + range.Min = scale_min; + range.Max = scale_max; + GetTicks(range, 10, 0, false, ticks); + LabelTicks(ticks, false, txt_buff); + float max_width = 0; + for (int i = 0; i < ticks.Size; ++i) + max_width = ticks[i].Size.x > max_width ? ticks[i].Size.x : max_width; + + ImGuiContext &G = *GImGui; + ImGuiWindow * Window = G.CurrentWindow; + if (Window->SkipItems) + return; + const ImGuiStyle &Style = G.Style; + const float txt_off = 5; + const float bar_w = 20; + + ImDrawList &DrawList = *Window->DrawList; + ImVec2 size(bar_w + txt_off + max_width + 2 * Style.WindowPadding.x, height); + ImRect bb_frame = ImRect(Window->DC.CursorPos, Window->DC.CursorPos + size); + ImGui::ItemSize(bb_frame); + if (!ImGui::ItemAdd(bb_frame, 0, &bb_frame)) + return; + ImGui::RenderFrame(bb_frame.Min, bb_frame.Max, ImGui::GetColorU32(ImGuiCol_FrameBg)); + ImRect bb_grad(bb_frame.Min + Style.WindowPadding, bb_frame.Min + ImVec2(bar_w + Style.WindowPadding.x, height - Style.WindowPadding.y)); + + int num_cols = GetColormapSize(); + float h_step = (height - 2 * Style.WindowPadding.y) / (num_cols - 1); + const ImVec2 uv = DrawList._Data->TexUvWhitePixel; + for (int i = 0; i < num_cols-1; ++i) { + ImRect rect(bb_grad.Min.x, bb_grad.Min.y + h_step * i, bb_grad.Max.x, bb_grad.Min.y + h_step * (i + 1)); + ImU32 col1 = ImGui::GetColorU32(GetColormapColor(num_cols - 1 - i)); + ImU32 col2 = ImGui::GetColorU32(GetColormapColor(num_cols - 1 - (i+1))); + DrawList.AddRectFilledMultiColor(rect.Min, rect.Max, col1, col1, col2, col2); + } + ImU32 col_border = gp.Style.Colors[ImPlotCol_PlotBorder].w == -1 ? ImGui::GetColorU32(ImGuiCol_Text, 0.5f) : ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_PlotBorder]); + + ImGui::PushClipRect(bb_frame.Min, bb_frame.Max, true); + for (int i = 0; i < ticks.Size; ++i) { + float ypos = Remap((float)ticks[i].PlotPos, (float)range.Max, (float)range.Min, bb_grad.Min.y, bb_grad.Max.y); + if (ypos < bb_grad.Max.y - 2 && ypos > bb_grad.Min.y + 2) + DrawList.AddLine(ImVec2(bb_grad.Max.x-1, ypos), ImVec2(bb_grad.Max.x - (ticks[i].Major ? 10.0f : 5.0f), ypos), col_border, 1.0f); + DrawList.AddText(ImVec2(bb_grad.Max.x-1, ypos) + ImVec2(txt_off, -ticks[i].Size.y * 0.5f), ImGui::GetColorU32(ImGuiCol_Text), txt_buff.Buf.Data + ticks[i].TextOffset); + } + ImGui::PopClipRect(); + + DrawList.AddRect(bb_grad.Min, bb_grad.Max, col_border); + } void SetColormap(ImPlotColormap colormap) { diff --git a/implot.h b/implot.h index c18b4a1..cdbb4c6 100644 --- a/implot.h +++ b/implot.h @@ -243,6 +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); // Plots a 2D heatmap chart. Values are expected to be in row-major order. +void PlotHeatmap(const char* label_id, const float* values, int rows, int cols, float scale_min, float scale_max, bool show_labels = true, const ImPlotPoint& bounds_min = ImPlotPoint(0,0), const ImPlotPoint& bounds_max = ImPlotPoint(1,1)); 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. @@ -325,6 +326,9 @@ ImPlotPoint PixelsToPlot(const ImVec2& pix, int y_axis = -1); // Convert a position in the current plot's coordinate system to pixels. A negative y_axis uses the current value of SetPlotYAxis (0 initially). ImVec2 PlotToPixels(const ImPlotPoint& plt, int y_axis = -1); +// Renders a vertical color scale using the current color map +void ShowColormapScale(double scale_min, double scale_max, float height); + // Push clip rect for rendering to current plot area. void PushPlotClipRect(); // Pop plot clip rect. diff --git a/implot_demo.cpp b/implot_demo.cpp index 68707c1..fd5431c 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -54,7 +54,7 @@ typedef ImVec2 t_float2; #define Fmod fmodf #endif -namespace { +namespace ImPlot { t_float RandomRange(t_float min, t_float max) { t_float scale = rand() / (t_float) RAND_MAX; @@ -119,10 +119,6 @@ struct BenchmarkItem { ImVec4 Col; }; -} // private namespace - -namespace ImPlot { - 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; @@ -321,40 +317,43 @@ void ShowDemoWindow(bool* p_open) { } //------------------------------------------------------------------------- if (ImGui::CollapsingHeader("Heatmaps")) { - 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}, - {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.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}, - {0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3}}; + static t_float values1[7][7] = {{0.8f, 2.4f, 2.5f, 3.9f, 0.0f, 4.0f, 0.0f}, + {2.4f, 0.0f, 4.0f, 1.0f, 2.7f, 0.0f, 0.0f}, + {1.1f, 2.4f, 0.8f, 4.3f, 1.9f, 4.4f, 0.0f}, + {0.6f, 0.0f, 0.3f, 0.0f, 3.1f, 0.0f, 0.0f}, + {0.7f, 1.7f, 0.6f, 2.6f, 2.2f, 6.2f, 0.0f}, + {1.3f, 1.2f, 0.0f, 0.0f, 0.0f, 3.2f, 5.1f}, + {0.1f, 2.0f, 0.0f, 1.4f, 0.0f, 1.9f, 6.3f}}; static float scale_min = 0; static float scale_max = 6.3f; - static double values2[100*100]; + static t_float values2[100*100]; for (int i = 0; i < 100*100; ++i) { values2[i] = RandomRange(0,1); } static ImPlotColormap map = ImPlotColormap_Viridis; - if (ImGui::Button("Cycle Colormap")) + if (ImGui::Button("Cycle Colormap",ImVec2(225,0))) map = (map + 1) % ImPlotColormap_COUNT; + ImPlot::SetColormap(map); ImGui::SameLine(); ImGui::LabelText("##Colormap Index", cmap_names[map]); - ImGui::DragFloatRange2("Scale (Left Only)",&scale_min,&scale_max,0.01f); + ImGui::SetNextItemWidth(225); + ImGui::DragFloat("Max",&scale_max,0.01f,0.1f,20); static ImPlotAxisFlags axes_flags = ImPlotAxisFlags_LockMin | ImPlotAxisFlags_LockMax; - if (ImPlot::BeginPlot("##Heatmap1",NULL,NULL,ImVec2(250,250))) { - ImPlot::SetColormap(map); + if (ImPlot::BeginPlot("##Heatmap1",NULL,NULL,ImVec2(225,225),ImPlotFlags_ContextMenu,axes_flags,axes_flags)) { ImPlot::PlotHeatmap("heat",values1[0],7,7,scale_min,scale_max); ImPlot::EndPlot(); - ImPlot::SetColormap(ImPlotColormap_Default); } ImGui::SameLine(); - SetNextPlotLimits(1,2,1,2); - if (ImPlot::BeginPlot("##Heatmap2",NULL,NULL,ImVec2(250,250),0,axes_flags,axes_flags)) { - ImPlot::SetColormap(map); - ImPlot::PlotHeatmap("heat",values2,100,100,0,1,false,{1,1},{2,2}); + ImPlot::ShowColormapScale(scale_min, scale_max, 225); + ImPlot::SetColormap(ImPlotColormap_Default); + ImGui::SameLine(); + static ImVec4 gray[2] = {ImVec4(0,0,0,1), ImVec4(1,1,1,1)}; + ImPlot::SetColormap(&gray[0], 2); + if (ImPlot::BeginPlot("##Heatmap2",NULL,NULL,ImVec2(225,225),ImPlotFlags_ContextMenu,0,0)) { + ImPlot::PlotHeatmap("heat",values2,100,100,0,1,false); ImPlot::EndPlot(); - ImPlot::SetColormap(ImPlotColormap_Default); } + ImPlot::SetColormap(ImPlotColormap_Default); } //------------------------------------------------------------------------- if (ImGui::CollapsingHeader("Realtime Plots")) { @@ -387,13 +386,13 @@ void ShowDemoWindow(bool* p_open) { } } //------------------------------------------------------------------------- - if (ImGui::CollapsingHeader("Colormaps, Markers, and Text")) { + if (ImGui::CollapsingHeader("Markers and Text")) { static ImPlotColormap map = ImPlotColormap_Default; - if (ImGui::Button("Cycle Colormap")) + if (ImGui::Button("Cycle Colormap##2")) 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! + 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); if (ImPlot::BeginPlot("##MarkerStyles", NULL, NULL, ImVec2(-1,0), 0, 0, 0)) { ImPlot::SetColormap(map);