From 8931a8d36bd4bd4287591c9d8dc838dbaa2f1220 Mon Sep 17 00:00:00 2001 From: Adriano Parisi Date: Sun, 7 Jun 2020 23:39:25 +0100 Subject: [PATCH 1/8] Function decs for vert/hori error bars --- implot.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/implot.h b/implot.h index 6f5e60e..9f2706d 100644 --- a/implot.h +++ b/implot.h @@ -238,6 +238,12 @@ void PlotErrorBars(const char* label_id, const double* xs, const double* ys, con void PlotErrorBars(const char* label_id, const float* xs, const float* ys, const float* neg, const float* pos, int count, int offset = 0, int stride = sizeof(float)); void PlotErrorBars(const char* label_id, const double* xs, const double* ys, const double* neg, const double* pos, int count, int offset = 0, int stride = sizeof(double)); +// Plots both vertical and horizontal error bars +void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* err_v, const float* err_h, int count, int offset = 0, int stride = sizeof(float)); +void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* err_v, const double* err_h, int count, int offset = 0, int stride = sizeof(double)); +void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* neg_v, const float* pos_v, const float* neg_h, const float* pos_h, int count, int offset = 0, int stride = sizeof(float)); +void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* neg_v, const double* pos_v, const double* neg_h, const double* pos_h, int count, int offset = 0, int stride = sizeof(double)); + // Plots a pie chart. If the sum of values > 1 or normalize is true, each value will be normalized. Center and radius are in plot coordinates. void PlotPieChart(const char** label_ids, const float* values, int count, float x, float y, float radius, bool normalize = false, const char* label_fmt = "%.1f", float angle0 = 90); void PlotPieChart(const char** label_ids, const double* values, int count, double x, double y, double radius, bool normalize = false, const char* label_fmt = "%.1f", double angle0 = 90); From 3f84f4391917e7f2431e3bbf658188545ab69812 Mon Sep 17 00:00:00 2001 From: Adriano Parisi Date: Mon, 8 Jun 2020 00:05:56 +0100 Subject: [PATCH 2/8] Building and showing in demo, now for adding horizontal errors --- implot.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ implot_demo.cpp | 8 +++++ 2 files changed, 102 insertions(+) diff --git a/implot.cpp b/implot.cpp index 5567c1a..80f85ef 100644 --- a/implot.cpp +++ b/implot.cpp @@ -2916,6 +2916,100 @@ void PlotErrorBars(const char* label_id, const double* xs, const double* ys, con PlotErrorBarsEx(label_id, getter); } +//----------------------------------------------------------------------------- +// PLOT ERROR BARS H +//----------------------------------------------------------------------------- + +struct ImPlotPointErrorH { + ImPlotPointErrorH(double _x, double _y, double _neg_v, double _pos_v, double _neg_h, double _pos_h) { + x = _x; y = _y; neg_v = _neg_v; pos_v = _pos_v; neg_h = _neg_h; pos_h = _pos_h; + } + double x, y, neg_v, pos_v, neg_h, pos_h; +}; + +template +struct GetterErrorH { + const T* Xs; const T* Ys; const T* Neg_v; const T* Pos_v; const T* Neg_h; const T* Pos_h; int Count; int Offset; int Stride; + GetterErrorH(const T* xs, const T* ys, const T* neg_v, const T* pos_v, const T* neg_h, const T* pos_h, int count, int offset, int stride) { + Xs = xs; Ys = ys; Neg_v = neg_v; Pos_v = pos_v; Neg_h = neg_h; Pos_h = pos_h; Count = count; Offset = offset; Stride = stride; + } + ImPlotPointErrorH operator()(int idx) { + return ImPlotPointErrorH(OffsetAndStride(Xs, idx, Count, Offset, Stride), + OffsetAndStride(Ys, idx, Count, Offset, Stride), + OffsetAndStride(Neg_v, idx, Count, Offset, Stride), + OffsetAndStride(Pos_v, idx, Count, Offset, Stride), + OffsetAndStride(Neg_h, idx, Count, Offset, Stride), + OffsetAndStride(Pos_h, idx, Count, Offset, Stride)); + } +}; + +template +void PlotErrorBarsHEx(const char* label_id, Getter getter) { + IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotErrorBars() needs to be called between BeginPlot() and EndPlot()!"); + + ImGuiID id = ImGui::GetID(label_id); + ImPlotItem* item = gp.CurrentPlot->Items.GetByKey(id); + if (item != NULL && item->Show == false) + return; + + ImDrawList& DrawList = *ImGui::GetWindowDrawList(); + + PushPlotClipRect(); + + const ImU32 col = gp.Style.Colors[ImPlotCol_ErrorBar].w == -1 ? ImGui::GetColorU32(ImGuiCol_Text) : ImGui::GetColorU32(gp.Style.Colors[ImPlotCol_ErrorBar]); + const bool rend_whisker = gp.Style.ErrorBarSize > 0; + + const float half_whisker = gp.Style.ErrorBarSize * 0.5f; + + // find data extents + if (gp.FitThisFrame) { + for (int i = 0; i < getter.Count; ++i) { + ImPlotPointErrorH e = getter(i); + FitPoint(ImPlotPoint(e.x, e.y - e.neg_v)); + FitPoint(ImPlotPoint(e.x, e.y + e.pos_v)); + } + } + + for (int i = 0; i < getter.Count; ++i) { + ImPlotPointErrorH e = getter(i); + ImVec2 p1 = PlotToPixels(e.x, e.y - e.neg_v); + ImVec2 p2 = PlotToPixels(e.x, e.y + e.pos_v); + DrawList.AddLine(p1, p2, col, gp.Style.ErrorBarWeight); + if (rend_whisker) { + DrawList.AddLine(p1 - ImVec2(half_whisker, 0), p1 + ImVec2(half_whisker, 0), col, gp.Style.ErrorBarWeight); + DrawList.AddLine(p2 - ImVec2(half_whisker, 0), p2 + ImVec2(half_whisker, 0), col, gp.Style.ErrorBarWeight); + } + } + PopPlotClipRect(); +} + +//----------------------------------------------------------------------------- +// float + +void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* err_v, const float* err_h, int count, int offset, int stride) { + GetterErrorH getter(xs, ys, err_v, err_v, err_h, err_h, count, offset, stride); + PlotErrorBarsHEx(label_id, getter); +} + +void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* neg_v, const float* pos_v, const float* neg_h, const float* pos_h, int count, int offset, int stride) { + GetterErrorH getter(xs, ys, neg_v, pos_v, neg_h, pos_h, count, offset, stride); + PlotErrorBarsHEx(label_id, getter); +} + +//----------------------------------------------------------------------------- +// double + +void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* err_v, const double* err_h, int count, int offset, int stride) { + GetterErrorH getter(xs, ys, err_v, err_v, err_h, err_h, count, offset, stride); + PlotErrorBarsHEx(label_id, getter); +} + +void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* neg_v, const double* pos_v, const double* neg_h, const double* pos_h, int count, int offset, int stride) { + GetterErrorH getter(xs, ys, neg_v, pos_v, neg_h, pos_h, count, offset, stride); + PlotErrorBarsHEx(label_id, getter); +} + + //----------------------------------------------------------------------------- // PLOT PIE CHART //----------------------------------------------------------------------------- diff --git a/implot_demo.cpp b/implot_demo.cpp index 4256b5e..b88a4e0 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -281,6 +281,7 @@ void ShowDemoWindow(bool* p_open) { if (ImGui::CollapsingHeader("Error Bars")) { t_float xs[5] = {1,2,3,4,5}; t_float lin[5] = {8,8,9,7,8}; + t_float lin2[5] = { 6,7,6,9,6}; t_float bar[5] = {1,2,5,3,4}; t_float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f}; t_float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f}; @@ -295,6 +296,13 @@ void ShowDemoWindow(bool* p_open) { ImPlot::PlotLine("Line", xs, lin, 5); ImPlot::PopStyleVar(2); ImPlot::PopStyleColor(); + ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square); + ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 3); + ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImVec4(0, 1, 0, 1)); + ImPlot::PlotErrorBarsH("Line##ErrorBarH", xs, lin2, err1, err2, 5); + ImPlot::PlotLine("Line##ErrorBarH", xs, lin2, 5); + ImPlot::PopStyleVar(2); + ImPlot::PopStyleColor(); ImPlot::EndPlot(); } } From ef549d1ab5ae57526a4400e9f614f5c65605fc88 Mon Sep 17 00:00:00 2001 From: Adriano Parisi Date: Mon, 8 Jun 2020 00:16:50 +0100 Subject: [PATCH 3/8] Added whiskers for H error bars, now showing desired feature --- implot.cpp | 7 +++++++ implot_demo.cpp | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/implot.cpp b/implot.cpp index 80f85ef..c40253d 100644 --- a/implot.cpp +++ b/implot.cpp @@ -2967,6 +2967,8 @@ void PlotErrorBarsHEx(const char* label_id, Getter getter) { ImPlotPointErrorH e = getter(i); FitPoint(ImPlotPoint(e.x, e.y - e.neg_v)); FitPoint(ImPlotPoint(e.x, e.y + e.pos_v)); + FitPoint(ImPlotPoint(e.x - e.neg_h, e.y)); + FitPoint(ImPlotPoint(e.x + e.pos_h, e.y)); } } @@ -2974,10 +2976,15 @@ void PlotErrorBarsHEx(const char* label_id, Getter getter) { ImPlotPointErrorH e = getter(i); ImVec2 p1 = PlotToPixels(e.x, e.y - e.neg_v); ImVec2 p2 = PlotToPixels(e.x, e.y + e.pos_v); + ImVec2 p3 = PlotToPixels(e.x - e.neg_h, e.y); + ImVec2 p4 = PlotToPixels(e.x + e.pos_h, e.y); DrawList.AddLine(p1, p2, col, gp.Style.ErrorBarWeight); + DrawList.AddLine(p3, p4, col, gp.Style.ErrorBarWeight); if (rend_whisker) { DrawList.AddLine(p1 - ImVec2(half_whisker, 0), p1 + ImVec2(half_whisker, 0), col, gp.Style.ErrorBarWeight); DrawList.AddLine(p2 - ImVec2(half_whisker, 0), p2 + ImVec2(half_whisker, 0), col, gp.Style.ErrorBarWeight); + DrawList.AddLine(p3 - ImVec2(0, half_whisker), p3 + ImVec2(0, half_whisker), col, gp.Style.ErrorBarWeight); + DrawList.AddLine(p4 - ImVec2(0, half_whisker), p4 + ImVec2(0, half_whisker), col, gp.Style.ErrorBarWeight); } } PopPlotClipRect(); diff --git a/implot_demo.cpp b/implot_demo.cpp index b88a4e0..7c734d5 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -285,6 +285,7 @@ void ShowDemoWindow(bool* p_open) { t_float bar[5] = {1,2,5,3,4}; t_float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f}; t_float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f}; + t_float err3[5] = {0.02f, 0.04f, 0.05f, 0.03f, 0.06f}; ImPlot::SetNextPlotLimits(0, 6, 0, 10); if (ImPlot::BeginPlot("##ErrorBars",NULL,NULL)) { ImPlot::PlotBars("Bar", xs, bar, 5, 0.5f); @@ -299,8 +300,8 @@ void ShowDemoWindow(bool* p_open) { ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 3); ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImVec4(0, 1, 0, 1)); - ImPlot::PlotErrorBarsH("Line##ErrorBarH", xs, lin2, err1, err2, 5); - ImPlot::PlotLine("Line##ErrorBarH", xs, lin2, 5); + ImPlot::PlotErrorBarsH("Line2##ErrorBarH", xs, lin2, err1, err3, 5); + ImPlot::PlotLine("Line2##ErrorBarH", xs, lin2, 5); ImPlot::PopStyleVar(2); ImPlot::PopStyleColor(); ImPlot::EndPlot(); From 47bb80534873fe02a2a4c4367c17f98f942edc94 Mon Sep 17 00:00:00 2001 From: Adriano Parisi Date: Mon, 8 Jun 2020 00:19:14 +0100 Subject: [PATCH 4/8] Increase H errors to highlight them --- implot_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/implot_demo.cpp b/implot_demo.cpp index 7c734d5..2c771ac 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -285,7 +285,7 @@ void ShowDemoWindow(bool* p_open) { t_float bar[5] = {1,2,5,3,4}; t_float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f}; t_float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f}; - t_float err3[5] = {0.02f, 0.04f, 0.05f, 0.03f, 0.06f}; + t_float err3[5] = {0.09f, 0.14f, 0.09f, 0.12f, 0.16f}; ImPlot::SetNextPlotLimits(0, 6, 0, 10); if (ImPlot::BeginPlot("##ErrorBars",NULL,NULL)) { ImPlot::PlotBars("Bar", xs, bar, 5, 0.5f); From 4293345c542e0d1944317368f1a7ff0649b5ecd9 Mon Sep 17 00:00:00 2001 From: Adriano Parisi Date: Mon, 8 Jun 2020 00:24:33 +0100 Subject: [PATCH 5/8] Very minor change --- implot_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/implot_demo.cpp b/implot_demo.cpp index 2c771ac..e5f1ab9 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -281,7 +281,7 @@ void ShowDemoWindow(bool* p_open) { if (ImGui::CollapsingHeader("Error Bars")) { t_float xs[5] = {1,2,3,4,5}; t_float lin[5] = {8,8,9,7,8}; - t_float lin2[5] = { 6,7,6,9,6}; + t_float lin2[5] = {6,7,6,9,6}; t_float bar[5] = {1,2,5,3,4}; t_float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f}; t_float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f}; From 1d11b1a1a39af395a3f8ba2b069359970e1b7a10 Mon Sep 17 00:00:00 2001 From: Adriano Parisi Date: Mon, 8 Jun 2020 20:45:31 +0100 Subject: [PATCH 6/8] Refactored to only draw the horizontal bars, updated demo --- implot.cpp | 62 +++++++++++++------------------------------------ implot.h | 10 ++++---- implot_demo.cpp | 4 +++- 3 files changed, 24 insertions(+), 52 deletions(-) diff --git a/implot.cpp b/implot.cpp index c40253d..730ff8a 100644 --- a/implot.cpp +++ b/implot.cpp @@ -2920,29 +2920,6 @@ void PlotErrorBars(const char* label_id, const double* xs, const double* ys, con // PLOT ERROR BARS H //----------------------------------------------------------------------------- -struct ImPlotPointErrorH { - ImPlotPointErrorH(double _x, double _y, double _neg_v, double _pos_v, double _neg_h, double _pos_h) { - x = _x; y = _y; neg_v = _neg_v; pos_v = _pos_v; neg_h = _neg_h; pos_h = _pos_h; - } - double x, y, neg_v, pos_v, neg_h, pos_h; -}; - -template -struct GetterErrorH { - const T* Xs; const T* Ys; const T* Neg_v; const T* Pos_v; const T* Neg_h; const T* Pos_h; int Count; int Offset; int Stride; - GetterErrorH(const T* xs, const T* ys, const T* neg_v, const T* pos_v, const T* neg_h, const T* pos_h, int count, int offset, int stride) { - Xs = xs; Ys = ys; Neg_v = neg_v; Pos_v = pos_v; Neg_h = neg_h; Pos_h = pos_h; Count = count; Offset = offset; Stride = stride; - } - ImPlotPointErrorH operator()(int idx) { - return ImPlotPointErrorH(OffsetAndStride(Xs, idx, Count, Offset, Stride), - OffsetAndStride(Ys, idx, Count, Offset, Stride), - OffsetAndStride(Neg_v, idx, Count, Offset, Stride), - OffsetAndStride(Pos_v, idx, Count, Offset, Stride), - OffsetAndStride(Neg_h, idx, Count, Offset, Stride), - OffsetAndStride(Pos_h, idx, Count, Offset, Stride)); - } -}; - template void PlotErrorBarsHEx(const char* label_id, Getter getter) { IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotErrorBars() needs to be called between BeginPlot() and EndPlot()!"); @@ -2964,27 +2941,20 @@ void PlotErrorBarsHEx(const char* label_id, Getter getter) { // find data extents if (gp.FitThisFrame) { for (int i = 0; i < getter.Count; ++i) { - ImPlotPointErrorH e = getter(i); - FitPoint(ImPlotPoint(e.x, e.y - e.neg_v)); - FitPoint(ImPlotPoint(e.x, e.y + e.pos_v)); - FitPoint(ImPlotPoint(e.x - e.neg_h, e.y)); - FitPoint(ImPlotPoint(e.x + e.pos_h, e.y)); + ImPlotPointError e = getter(i); + FitPoint(ImPlotPoint(e.x - e.neg, e.y)); + FitPoint(ImPlotPoint(e.x + e.pos, e.y)); } } for (int i = 0; i < getter.Count; ++i) { - ImPlotPointErrorH e = getter(i); - ImVec2 p1 = PlotToPixels(e.x, e.y - e.neg_v); - ImVec2 p2 = PlotToPixels(e.x, e.y + e.pos_v); - ImVec2 p3 = PlotToPixels(e.x - e.neg_h, e.y); - ImVec2 p4 = PlotToPixels(e.x + e.pos_h, e.y); + ImPlotPointError e = getter(i); + ImVec2 p1 = PlotToPixels(e.x - e.neg, e.y); + ImVec2 p2 = PlotToPixels(e.x + e.pos, e.y); DrawList.AddLine(p1, p2, col, gp.Style.ErrorBarWeight); - DrawList.AddLine(p3, p4, col, gp.Style.ErrorBarWeight); if (rend_whisker) { - DrawList.AddLine(p1 - ImVec2(half_whisker, 0), p1 + ImVec2(half_whisker, 0), col, gp.Style.ErrorBarWeight); - DrawList.AddLine(p2 - ImVec2(half_whisker, 0), p2 + ImVec2(half_whisker, 0), col, gp.Style.ErrorBarWeight); - DrawList.AddLine(p3 - ImVec2(0, half_whisker), p3 + ImVec2(0, half_whisker), col, gp.Style.ErrorBarWeight); - DrawList.AddLine(p4 - ImVec2(0, half_whisker), p4 + ImVec2(0, half_whisker), col, gp.Style.ErrorBarWeight); + DrawList.AddLine(p1 - ImVec2(0, half_whisker), p1 + ImVec2(0, half_whisker), col, gp.Style.ErrorBarWeight); + DrawList.AddLine(p2 - ImVec2(0, half_whisker), p2 + ImVec2(0, half_whisker), col, gp.Style.ErrorBarWeight); } } PopPlotClipRect(); @@ -2993,26 +2963,26 @@ void PlotErrorBarsHEx(const char* label_id, Getter getter) { //----------------------------------------------------------------------------- // float -void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* err_v, const float* err_h, int count, int offset, int stride) { - GetterErrorH getter(xs, ys, err_v, err_v, err_h, err_h, count, offset, stride); +void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* err, int count, int offset, int stride) { + GetterError getter(xs, ys, err, err, count, offset, stride); PlotErrorBarsHEx(label_id, getter); } -void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* neg_v, const float* pos_v, const float* neg_h, const float* pos_h, int count, int offset, int stride) { - GetterErrorH getter(xs, ys, neg_v, pos_v, neg_h, pos_h, count, offset, stride); +void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* neg, const float* pos, int count, int offset, int stride) { + GetterError getter(xs, ys, neg, pos, count, offset, stride); PlotErrorBarsHEx(label_id, getter); } //----------------------------------------------------------------------------- // double -void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* err_v, const double* err_h, int count, int offset, int stride) { - GetterErrorH getter(xs, ys, err_v, err_v, err_h, err_h, count, offset, stride); +void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* err, int count, int offset, int stride) { + GetterError getter(xs, ys, err, err, count, offset, stride); PlotErrorBarsHEx(label_id, getter); } -void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* neg_v, const double* pos_v, const double* neg_h, const double* pos_h, int count, int offset, int stride) { - GetterErrorH getter(xs, ys, neg_v, pos_v, neg_h, pos_h, count, offset, stride); +void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* neg, const double* pos, int count, int offset, int stride) { + GetterError getter(xs, ys, neg, pos, count, offset, stride); PlotErrorBarsHEx(label_id, getter); } diff --git a/implot.h b/implot.h index 9f2706d..6011bc2 100644 --- a/implot.h +++ b/implot.h @@ -238,11 +238,11 @@ void PlotErrorBars(const char* label_id, const double* xs, const double* ys, con void PlotErrorBars(const char* label_id, const float* xs, const float* ys, const float* neg, const float* pos, int count, int offset = 0, int stride = sizeof(float)); void PlotErrorBars(const char* label_id, const double* xs, const double* ys, const double* neg, const double* pos, int count, int offset = 0, int stride = sizeof(double)); -// Plots both vertical and horizontal error bars -void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* err_v, const float* err_h, int count, int offset = 0, int stride = sizeof(float)); -void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* err_v, const double* err_h, int count, int offset = 0, int stride = sizeof(double)); -void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* neg_v, const float* pos_v, const float* neg_h, const float* pos_h, int count, int offset = 0, int stride = sizeof(float)); -void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* neg_v, const double* pos_v, const double* neg_h, const double* pos_h, int count, int offset = 0, int stride = sizeof(double)); +// Plots horizontal error bars +void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* err, int count, int offset = 0, int stride = sizeof(float)); +void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* err, int count, int offset = 0, int stride = sizeof(double)); +void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* neg, const float* pos, int count, int offset = 0, int stride = sizeof(float)); +void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* neg, const double* pos, int count, int offset = 0, int stride = sizeof(double)); // Plots a pie chart. If the sum of values > 1 or normalize is true, each value will be normalized. Center and radius are in plot coordinates. void PlotPieChart(const char** label_ids, const float* values, int count, float x, float y, float radius, bool normalize = false, const char* label_fmt = "%.1f", float angle0 = 90); diff --git a/implot_demo.cpp b/implot_demo.cpp index e5f1ab9..913a34f 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -286,6 +286,7 @@ void ShowDemoWindow(bool* p_open) { t_float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f}; t_float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f}; t_float err3[5] = {0.09f, 0.14f, 0.09f, 0.12f, 0.16f}; + t_float err4[5] = {0.02f, 0.08f, 0.15f, 0.05f, 0.2f}; ImPlot::SetNextPlotLimits(0, 6, 0, 10); if (ImPlot::BeginPlot("##ErrorBars",NULL,NULL)) { ImPlot::PlotBars("Bar", xs, bar, 5, 0.5f); @@ -300,7 +301,8 @@ void ShowDemoWindow(bool* p_open) { ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 3); ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImVec4(0, 1, 0, 1)); - ImPlot::PlotErrorBarsH("Line2##ErrorBarH", xs, lin2, err1, err3, 5); + ImPlot::PlotErrorBars("Line2##ErrorBarH", xs, lin2, err2, 5); + ImPlot::PlotErrorBarsH("Line2##ErrorBarH", xs, lin2, err3, err4, 5); ImPlot::PlotLine("Line2##ErrorBarH", xs, lin2, 5); ImPlot::PopStyleVar(2); ImPlot::PopStyleColor(); From 7e4e683ce64701c657ac65c744e837f79797360a Mon Sep 17 00:00:00 2001 From: Adriano Parisi Date: Mon, 8 Jun 2020 20:49:22 +0100 Subject: [PATCH 7/8] Update assert --- implot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/implot.cpp b/implot.cpp index 730ff8a..64a352b 100644 --- a/implot.cpp +++ b/implot.cpp @@ -2922,7 +2922,7 @@ void PlotErrorBars(const char* label_id, const double* xs, const double* ys, con template void PlotErrorBarsHEx(const char* label_id, Getter getter) { - IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotErrorBars() needs to be called between BeginPlot() and EndPlot()!"); + IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "PlotErrorBarsH() needs to be called between BeginPlot() and EndPlot()!"); ImGuiID id = ImGui::GetID(label_id); ImPlotItem* item = gp.CurrentPlot->Items.GetByKey(id); From 0b3617668bbe18b0450a3ef4e7fe6a832b13b4cb Mon Sep 17 00:00:00 2001 From: Evan Pezent Date: Mon, 8 Jun 2020 20:26:15 -0500 Subject: [PATCH 8/8] tidy up error bars h, add sliders for misc styling variables to demo --- implot.cpp | 2 +- implot.h | 6 +++--- implot_demo.cpp | 49 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/implot.cpp b/implot.cpp index 64a352b..fe1b2fc 100644 --- a/implot.cpp +++ b/implot.cpp @@ -2986,7 +2986,7 @@ void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, co PlotErrorBarsHEx(label_id, getter); } - + //----------------------------------------------------------------------------- // PLOT PIE CHART //----------------------------------------------------------------------------- diff --git a/implot.h b/implot.h index 6011bc2..f58b318 100644 --- a/implot.h +++ b/implot.h @@ -70,7 +70,7 @@ enum ImPlotAxisFlags_ { // Plot styling colors. enum ImPlotCol_ { - ImPlotCol_Line, // plot line/outline color (defaults to a rotating color set) + ImPlotCol_Line, // plot line/outline color (defaults to next unused color in current colormap) ImPlotCol_Fill, // plot fill color for bars (defaults to the current line color) ImPlotCol_MarkerOutline, // marker outline color (defaults to the current line color) ImPlotCol_MarkerFill, // marker fill color (defaults to the current line color) @@ -232,13 +232,13 @@ void PlotBarsH(const char* label_id, const float* xs, const float* ys, int count void PlotBarsH(const char* label_id, const double* xs, const double* ys, int count, double height, int offset = 0, int stride = sizeof(double)); void PlotBarsH(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, double height, int offset = 0); -// Plots vertical error bar. +// Plots vertical error bar. The label_id should match the label_id of the associated line or bar plot. void PlotErrorBars(const char* label_id, const float* xs, const float* ys, const float* err, int count, int offset = 0, int stride = sizeof(float)); void PlotErrorBars(const char* label_id, const double* xs, const double* ys, const double* err, int count, int offset = 0, int stride = sizeof(double)); void PlotErrorBars(const char* label_id, const float* xs, const float* ys, const float* neg, const float* pos, int count, int offset = 0, int stride = sizeof(float)); void PlotErrorBars(const char* label_id, const double* xs, const double* ys, const double* neg, const double* pos, int count, int offset = 0, int stride = sizeof(double)); -// Plots horizontal error bars +// Plots horizontal error bars. The label_id should match the label_id of the associated line or bar plot. void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* err, int count, int offset = 0, int stride = sizeof(float)); void PlotErrorBarsH(const char* label_id, const double* xs, const double* ys, const double* err, int count, int offset = 0, int stride = sizeof(double)); void PlotErrorBarsH(const char* label_id, const float* xs, const float* ys, const float* neg, const float* pos, int count, int offset = 0, int stride = sizeof(float)); diff --git a/implot_demo.cpp b/implot_demo.cpp index 913a34f..d145d5b 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -164,7 +164,7 @@ void ShowDemoWindow(bool* p_open) { ImGui::Indent(); ImGui::BulletText("Software AA can be enabled per plot with ImPlotFlags_AntiAliased."); ImGui::BulletText("AA for demo plots can be enabled from the plot's context menu."); - ImGui::BulletText("If allowable, you are better off using hardware AA (e.g. MSAA)."); + ImGui::BulletText("If permitable, you are better off using hardware AA (e.g. MSAA)."); ImGui::Unindent(); #ifdef IMPLOT_DEMO_USE_DOUBLE ImGui::BulletText("The demo data precision is: double"); @@ -185,11 +185,15 @@ void ShowDemoWindow(bool* p_open) { xs2[i] = i * 0.1f; ys2[i] = xs2[i] * xs2[i]; } + static float weight = ImPlot::GetStyle().LineWeight; + ImGui::BulletText("Anti-aliasing can be enabled from the plot's context menu (see Help)."); + ImGui::DragFloat("Line Weight", &weight, 0.05f, 1.0f, 5.0f, "%.2f px"); if (ImPlot::BeginPlot("Line Plot", "x", "f(x)")) { + ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, weight); ImPlot::PlotLine("0.5 + 0.5*sin(50*x)", xs1, ys1, 1001); ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle); ImPlot::PlotLine("x^2", xs2, ys2, 11); - ImPlot::PopStyleVar(); + ImPlot::PopStyleVar(2); ImPlot::EndPlot(); } } @@ -280,32 +284,37 @@ void ShowDemoWindow(bool* p_open) { //------------------------------------------------------------------------- if (ImGui::CollapsingHeader("Error Bars")) { t_float xs[5] = {1,2,3,4,5}; - t_float lin[5] = {8,8,9,7,8}; - t_float lin2[5] = {6,7,6,9,6}; t_float bar[5] = {1,2,5,3,4}; + t_float lin1[5] = {8,8,9,7,8}; + t_float lin2[5] = {6,7,6,9,6}; t_float err1[5] = {0.2f, 0.4f, 0.2f, 0.6f, 0.4f}; t_float err2[5] = {0.4f, 0.2f, 0.4f, 0.8f, 0.6f}; t_float err3[5] = {0.09f, 0.14f, 0.09f, 0.12f, 0.16f}; t_float err4[5] = {0.02f, 0.08f, 0.15f, 0.05f, 0.2f}; + static float size = ImPlot::GetStyle().ErrorBarSize; + static float weight = ImPlot::GetStyle().ErrorBarWeight; + ImGui::DragFloat("Error Bar Size", &size, 0.1f, 0, 10,"%.2f px"); + ImGui::DragFloat("Error Bar Weight",&weight,0.01f,1,3,"%.2f px"); ImPlot::SetNextPlotLimits(0, 6, 0, 10); if (ImPlot::BeginPlot("##ErrorBars",NULL,NULL)) { + ImPlot::PushStyleVar(ImPlotStyleVar_ErrorBarSize, size); + ImPlot::PushStyleVar(ImPlotStyleVar_ErrorBarWeight, weight); ImPlot::PlotBars("Bar", xs, bar, 5, 0.5f); + // error bars should have the same label ID as the associated plot ImPlot::PlotErrorBars("Bar", xs, bar, err1, 5); ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 3); - ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImVec4(1,0,0,1)); - ImPlot::PlotErrorBars("Line", xs, lin, err1, err2, 5); - ImPlot::PlotLine("Line", xs, lin, 5); - ImPlot::PopStyleVar(2); - ImPlot::PopStyleColor(); + ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImPlot::GetColormapColor(1)); + ImPlot::PlotErrorBars("Line1", xs, lin1, err1, err2, 5); + ImPlot::PlotLine("Line1", xs, lin1, 5); ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Square); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 3); - ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImVec4(0, 1, 0, 1)); - ImPlot::PlotErrorBars("Line2##ErrorBarH", xs, lin2, err2, 5); - ImPlot::PlotErrorBarsH("Line2##ErrorBarH", xs, lin2, err3, err4, 5); - ImPlot::PlotLine("Line2##ErrorBarH", xs, lin2, 5); - ImPlot::PopStyleVar(2); - ImPlot::PopStyleColor(); + ImPlot::PushStyleColor(ImPlotCol_ErrorBar, ImPlot::GetColormapColor(2)); + ImPlot::PlotErrorBars("Line2", xs, lin2, err2, 5); + ImPlot::PlotErrorBarsH("Line2", xs, lin2, err3, err4, 5); + ImPlot::PlotLine("Line2", xs, lin2, 5); + ImPlot::PopStyleVar(6); + ImPlot::PopStyleColor(2); ImPlot::EndPlot(); } } @@ -419,15 +428,21 @@ 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("Change Colormap##2")) map = (map + 1) % ImPlotColormap_COUNT; ImGui::SameLine(); ImGui::LabelText("##Colormap Index", "%s", cmap_names[map]); + static float mk_size = ImPlot::GetStyle().MarkerSize; + static float mk_weight = ImPlot::GetStyle().MarkerWeight; + ImGui::DragFloat("Marker Size",&mk_size,0.1f,2.0f,10.0f,"%.2f px"); + ImGui::DragFloat("Marker Weight", &mk_weight,0.05f,0.5f,3.0f,"%.2f px"); ImGui::PushID(map); // NB: This is 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::PushStyleVar(ImPlotStyleVar_MarkerSize, mk_size); + ImPlot::PushStyleVar(ImPlotStyleVar_MarkerWeight, mk_weight); ImPlot::SetColormap(map); t_float xs[2] = {1,4}; t_float ys[2] = {10,11}; @@ -491,7 +506,7 @@ void ShowDemoWindow(bool* p_open) { ImPlot::PushStyleColor(ImPlotCol_MarkerFill, ImVec4(1,1,1,1)); ImPlot::PushStyleColor(ImPlotCol_Line, ImVec4(0,0,0,1)); ImPlot::PlotLine("Circle|Cross", xs, ys, 2); - ImPlot::PopStyleVar(4); + ImPlot::PopStyleVar(6); ImPlot::PopStyleColor(3); ImPlot::PlotText("Filled Markers", 1.5, 11.75);