Announcements and New Features (2021) #168
Replies: 12 comments 4 replies
-
Labels for Auxiliary Y-Axes - (v0.9 - 1/6/2021)Labels can now be added to the second and third y-axes by passing strings to |
Beta Was this translation helpful? Give feedback.
-
PlotVLines / PlotHLines - (v0.9 - 1/15/2021)Horizontal and vertical reference lines that extend to +/- infinity can now be added with the following functions: void PlotVLines(const char* label_id, const T* xs, int count, int offset=0, int stride=sizeof(T));
void PlotHLines(const char* label_id, const T* ys, int count, int offset=0, int stride=sizeof(T)); |
Beta Was this translation helpful? Give feedback.
-
Single Right-Click Context Menus - (v0.9 - 1/18/2021)Plot context menus now open with single right-click. This is obviously more natural than the previous double right click requirement. See #170. Additionally, |
Beta Was this translation helpful? Give feedback.
-
Improve Drag and Drop Support - (v0.9 - 2/28/2021)Drag and drop support has been improved. Now, plot areas, axes, legends, and items can serve as either a target OR source. Get creative! // Turns the current plot's plotting area into a drag and drop target. Don't forget to call EndDragDropTarget!
bool BeginDragDropTarget();
// Turns the current plot's X-axis into a drag and drop target. Don't forget to call EndDragDropTarget!
bool BeginDragDropTargetX();
// Turns the current plot's Y-Axis into a drag and drop target. Don't forget to call EndDragDropTarget!
bool BeginDragDropTargetY(ImPlotYAxis axis = ImPlotYAxis_1);
// Turns the current plot's legend into a drag and drop target. Don't forget to call EndDragDropTarget!
bool BeginDragDropTargetLegend();
// Ends a drag and drop target (currently just an alias for ImGui::EndDragDropTarget).
void EndDragDropTarget();
// NB: By default, plot and axes drag and drop sources require holding the Ctrl modifier to initiate the drag.
// You can change the modifier if desired. If ImGuiKeyModFlags_None is provided, the axes will be locked from panning.
// Turns the current plot's plotting area into a drag and drop source. Don't forget to call EndDragDropSource!
bool BeginDragDropSource(ImGuiKeyModFlags key_mods = ImGuiKeyModFlags_Ctrl, ImGuiDragDropFlags flags = 0);
// Turns the current plot's X-axis into a drag and drop source. Don't forget to call EndDragDropSource!
bool BeginDragDropSourceX(ImGuiKeyModFlags key_mods = ImGuiKeyModFlags_Ctrl, ImGuiDragDropFlags flags = 0);
// Turns the current plot's Y-axis into a drag and drop source. Don't forget to call EndDragDropSource!
bool BeginDragDropSourceY(ImPlotYAxis axis = ImPlotYAxis_1, ImGuiKeyModFlags key_mods = ImGuiKeyModFlags_Ctrl, ImGuiDragDropFlags flags = 0);
// Turns an item in the current plot's legend into drag and drop source. Don't forget to call EndDragDropSource!
bool BeginDragDropSourceItem(const char* label_id, ImGuiDragDropFlags flags = 0);
// Ends a drag and drop source (currently just an alias for ImGui::EndDragDropSource).
void EndDragDropSource(); |
Beta Was this translation helpful? Give feedback.
-
Colormap Overhaul - (v0.9 - 3/17/2021)Colormaps have been given a significant overhaul in terms of the public API, features, and internal implementation. These changes were mostly added to support improvements to heatmaps and the addition of 2D histograms (see next post). New Features
API Changes
ImPlotColormap AddColormap(const char* name, const ImVec4* cols, int size, bool qual=true);
ImPlotColormap AddColormap(const char* name, const ImU32* cols, int size, bool qual=true);
Implementation Details
|
Beta Was this translation helpful? Give feedback.
-
PlotHistogram, PlotHistogram2D, and Heatmap Performance - (v0.9 - 3/17/2021)
// Plots a horizontal histogram. #bins can be a positive integer or an ImPlotBin_ method. If #cumulative is true, each bin contains its count plus the counts of all previous bins.
// If #density is true, the PDF is visualized. If both are true, the CDF is visualized. If #range is left unspecified, the min/max of #values will be used as the range.
// If #range is specified, outlier values outside of the range are not binned. However, outliers still count toward normalizing and cumulative counts unless #outliers is false. The largest bin count or density is returned.
template <typename T> IMPLOT_API double PlotHistogram(const char* label_id, const T* values, int count, int bins=ImPlotBin_Sturges, bool cumulative=false, bool density=false, ImPlotRange range=ImPlotRange(), bool outliers=true, double bar_scale=1.0);
// Plots two dimensional, bivariate histogram as a heatmap. #x_bins and #y_bins can be a positive integer or an ImPlotBin. If #density is true, the PDF is visualized.
// If #range is left unspecified, the min/max of #xs an #ys will be used as the ranges. If #range is specified, outlier values outside of range are not binned.
// However, outliers still count toward the normalizing count for density plots unless #outliers is false. The largest bin count or density is returned.
template <typename T> IMPLOT_API double PlotHistogram2D(const char* label_id, const T* xs, const T* ys, int count, int x_bins=ImPlotBin_Sturges, int y_bins=ImPlotBin_Sturges, bool density=false, ImPlotLimits range=ImPlotLimits(), bool outliers=true);
// Enums for different automatic histogram binning methods (k = bin count or w = bin width)
enum ImPlotBin_ {
ImPlotBin_Sqrt = -1, // k = sqrt(n)
ImPlotBin_Sturges = -2, // k = 1 + log2(n)
ImPlotBin_Rice = -3, // k = 2 * cbrt(n)
ImPlotBin_Scott = -4, // w = 3.49 * sigma / cbrt(n)
};
implot_spectogram.mp4 |
Beta Was this translation helpful? Give feedback.
-
Initial Fit and Auto Fitting - (v0.10 - 3/20/2021)By default, plot axes limits are now conveniently fit to data plotted on the first rendered frame. The previous behavior, which always initialized axes limits to [0,1] can be reenabled with float data[] = {1,2};
// new behavior - initial fit
if (ImPlot::BeginPlot("Plot1")) {
ImPlot::PlotLine("data",data,data,2);
ImPlot::EndPlot();
}
// old behavior - no initial fit
if (ImPlot::BeginPlot("Plot2",0,0,{-1,0},0,ImPlotAxisFlags_NoInitialFit,ImPlotAxisFlags_NoInitialFit)) {
ImPlot::PlotLine("data",data,data,2);
ImPlot::EndPlot();
}
// initial fit ignored if explicit limits given
ImPlot::SetNextPlotLimits(0,2,0,2);
if (ImPlot::BeginPlot("Plot3")) {
ImPlot::PlotLine("data",data,data,2);
ImPlot::EndPlot();
} It is also worth noting that |
Beta Was this translation helpful? Give feedback.
-
Custom Label Formatting - (v0.10 - 3/25/2021)Custom label format specifiers can be provided for each axis now using the following API. The format will be used for tick labels, mouse position, and potentially other numeric displays in the future. The default format is // Set the format for numeric X axis labels (default="%g"). Formated values will be doubles (i.e. don't supply %d, %i, etc.). Not applicable if ImPlotAxisFlags_Time enabled.
void SetNextPlotFormatX(const char* fmt);
// Set the format for numeric Y axis labels (default="%g"). Formated values will be doubles (i.e. don't supply %d, %i, etc.).
void SetNextPlotFormatY(const char* fmt, ImPlotYAxis y_axis=ImPlotYAxis_1); |
Beta Was this translation helpful? Give feedback.
-
Aligned Plots - (v0.10 - 7/7/2021)A log awaited PR from @ozlb has finally been merged. The functions below allow you to align the pixel padding of adjacent plots so that plot regions remain aligned. This is particularly useful for stacked plots that share a common x-axis: // Align axis padding over multiple plots in a single row or column. If this function returns true, EndAlignedPlots() must be called. #group_id must be unique.
bool BeginAlignedPlots(const char* group_id, ImPlotOrientation orientation = ImPlotOrientation_Vertical);
// Only call EndAlignedPlots() if BeginAlignedPlots() returns true!
void EndAlignedPlots(); |
Beta Was this translation helpful? Give feedback.
-
Subplots - (v0.10 - 7/7/2021)A new subplot API is available! Easily create 2D cells of plots using bool BeginSubplots(const char* title_id,
int rows,
int cols,
const ImVec2& size,
ImPlotSubplotFlags flags = ImPlotSubplotFlags_None,
float* row_ratios = NULL,
float* col_ratios = NULL);
void EndSubplots(); Once inside of a subplot context, just use if (BeginSubplots("My Subplot",2,3,ImVec2(800,400)) {
for (int i = 0; i < 6; ++i) {
if (BeginPlot(...)) {
ImPlot::PlotLine(...);
...
EndPlot();
}
}
EndSubplots();
} Subplot cells can be sized by providing row and column ratios, and provide resizable grips for end users. The ratios passed will out updated accordingly if users interact with resize grips, which you can disable entirely if desired. One cool feature of subplots is the ability to share items on a common legend. Of course, you can position the legend or set up drag and drop capabilities just as you can with individual plots: Finally, subplot axes can be easily linked, either on a row, column, or axis basis. The padding of adjacent subplots will be kept in alignment, as described in the previous post: |
Beta Was this translation helpful? Give feedback.
-
Demo Revamp - (v0.10 - 7/7/2021)ImPlot keeps growing, and so does our demo! To make things a bit more navigable, we've adopted tab organization for the demo. Also, code for demo examples are now more consumable in a self-contained function. Functions can be searched for using the example's header string, e.g.: void ShowDemo_StairstepPlots() {
static float ys1[101], ys2[101];
for (int i = 0; i < 101; ++i) {
ys1[i] = 0.5f + 0.4f * sinf(50 * i * 0.01f);
ys2[i] = 0.5f + 0.2f * sinf(25 * i * 0.01f);
}
if (ImPlot::BeginPlot("Stairstep Plot", "x", "f(x)")) {
ImPlot::PlotStairs("Signal 1", ys1, 101, 0.01f);
ImPlot::SetNextMarkerStyle(ImPlotMarker_Square, 2.0f);
ImPlot::PlotStairs("Signal 2", ys2, 101, 0.01f);
ImPlot::EndPlot();
}
} |
Beta Was this translation helpful? Give feedback.
-
Setup API, Axes Features, and Tools - (v0.13 - 10/19/2021)It's been quiet around here for several months but not due to a lack of progress. Tons of work has been poured into the new Setup API and accompanying features, and today we are rolling out the first batch of changes. Setup API (see #272)Previously, setting up a plot and its axes was done by passing several args to Taking a page out of ImGui's if (BeginPlot("My Plot",ImVec2(-1,-1),ImPlotFlags_Crosshairs) { // 1) begin a new plot
SetupAxis(ImAxis_X1, "Time", ImPlotAxisFlags_Time); // 2) make Setup calls
SetupAxis(ImAxis_Y1, "My Y-Axis");
SetupAxisLimits(ImAxis_Y1, 0, 1000);
SetupAxisFormat(ImAxis_Y1, "$%.0f");
SetupLegend(ImPlotLocation_North);
...
SetupFinish(); // 3) [optional] explicitly finish setup
PlotLine(...); // 4) plot items
...
EndPlot(); // 5) end the plot
} All of the functionality you previously had with the original signature of // Begin a new plot.
bool BeginPlot(const char* title_id, const ImVec2& size = ImVec2(-1,0), ImPlotFlags flags = ImPlotFlags_None); // Enables an axis or sets the label and/or flags for an existing axis. Leave #label = NULL for no label.
void SetupAxis(ImAxis axis, const char* label = NULL, ImPlotAxisFlags flags = ImPlotAxisFlags_None);
// Sets an axis range limits. If ImPlotCond_Always is used, the axes limits will be locked.
void SetupAxisLimits(ImAxis axis, double v_min, double v_max, ImPlotCond cond = ImPlotCond_Once);
// Links an axis range limits to external values. Set to NULL for no linkage. The pointer data must remain valid until EndPlot.
void SetupAxisLinks(ImAxis axis, double* link_min, double* link_max);
// Sets the format of numeric axis labels via formater specifier (default="%g"). Formated values will be double (i.e. use %f).
void SetupAxisFormat(ImAxis axis, const char* fmt);
// Sets the format of numeric axis labels via formatter callback. Given #value, write a label into #buff. Optionally pass user data.
void SetupAxisFormat(ImAxis axis, ImPlotFormatter formatter, void* data = NULL);
// Sets an axis' ticks and optionally the labels. To keep the default ticks, set #keep_default=true.
void SetupAxisTicks(ImAxis axis, const double* values, int n_ticks, const char* const labels[] = NULL, bool keep_default = false);
// Sets an axis' ticks and optionally the labels for the next plot. To keep the default ticks, set #keep_default=true.
void SetupAxisTicks(ImAxis axis, double v_min, double v_max, int n_ticks, const char* const labels[] = NULL, bool keep_default = false);
// Sets the label and/or flags for primary X and Y axes (shorthand for two calls to SetupAxis).
void SetupAxes(const char* x_label, const char* y_label, ImPlotAxisFlags x_flags = ImPlotAxisFlags_None, ImPlotAxisFlags y_flags = ImPlotAxisFlags_None);
// Sets the primary X and Y axes range limits. If ImPlotCond_Always is used, the axes limits will be locked (shorthand for two calls to SetupAxisLimits).
void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, ImPlotCond cond = ImPlotCond_Once);
// Sets up the plot legend.
void SetupLegend(ImPlotLocation location, ImPlotLegendFlags flags = ImPlotLegendFlags_None);
// Set the location of the current plot's mouse position text (default = South|East).
void SetupMouseText(ImPlotLocation location, ImPlotMouseTextFlags flags = ImPlotMouseTextFlags_None);
// Explicitly finalize plot setup. Once you call this, you cannot make anymore Setup calls for the current plot!
// Note that calling this function is OPTIONAL; it will be called by the first subsequent setup-locking API call.
void SetupFinish(); A few notes:
New Axes FeaturesThe new Setup API allows us to easily extend and add functionality to axes. Here are a few new features you can start using today, with more expected to come in the near future.
Improved Tooling
Return of ImPlotInputMap
struct ImPlotInputMap {
ImGuiMouseButton Pan; // LMB enables panning when held,
ImGuiKeyModFlags PanMod; // none optional modifier that must be held for panning/fitting
ImGuiMouseButton Fit; // LMB initiates fit when double clicked
ImGuiMouseButton Select; // RMB begins box selection when pressed and confirms selection when released
ImGuiMouseButton SelectCancel; // LMB cancels active box selection when pressed; cannot be same as Select
ImGuiKeyModFlags SelectMod; // none optional modifier that must be held for box selection
ImGuiKeyModFlags SelectHorzMod; // Alt expands active box selection horizontally to plot edge when held
ImGuiKeyModFlags SelectVertMod; // Shift expands active box selection vertically to plot edge when held
ImGuiMouseButton Menu; // RMB opens context menus (if enabled) when clicked
ImGuiKeyModFlags OverrideMod; // Ctrl when held, all input is ignored; used to enable axis/plots as DND sources
ImGuiKeyModFlags ZoomMod; // none optional modifier that must be held for scroll wheel zooming
float ZoomRate; // 0.1f zoom rate for scroll (e.g. 0.1f = 10% plot range every scroll click); make negative to invert
ImPlotInputMap();
};
// Provides access to input mapping structure for permanent modifications to controls for pan, select, etc.
ImPlotInputMap& GetInputMap();
// Default input mapping: pan = LMB drag, box select = RMB drag, fit = LMB double click, context menu = RMB click, zoom = scroll.
void MapInputDefault(ImPlotInputMap* dst = NULL);
// Reverse input mapping: pan = RMB drag, box select = LMB drag, fit = LMB double click, context menu = RMB click, zoom = scroll.
void MapInputReverse(ImPlotInputMap* dst = NULL); |
Beta Was this translation helpful? Give feedback.
-
Announcements of changes and new features will be posted here. Click
Subscribe
to the right to receive updates!Feel free to comment on announcements, but please do not clutter the main thread with comments.
Previous Announcements:
Announcements and New Features (2020)
Beta Was this translation helpful? Give feedback.
All reactions