v0.14
Pre-releasePlot Item Flags
Each of ImPlot's PlotX
functions now takes an optional ImPlotXFlags
parameter. This decision (1) allows us to easily add more options for plot items and (2) allows us to consolidate and clean up some of the API. Here's what this looks like for PlotLine
:
// Flags for ANY PlotX function
enum ImPlotItemFlags_ {
ImPlotItemFlags_None = 0,
ImPlotItemFlags_NoLegend = 1 << 0, // the item won't have a legend entry displayed
ImPlotItemFlags_NoFit = 1 << 1, // the item won't be considered for plot fits
};
// Flags for PlotLine
enum ImPlotLineFlags_ {
ImPlotLineFlags_None = 0, // default
ImPlotLineFlags_Segments = 1 << 10, // a line segment will be rendered from every two consecutive points
ImPlotLineFlags_Loop = 1 << 11, // the last and first point will be connected to form a closed loop
ImPlotLineFlags_SkipNaN = 1 << 12, // NaNs values will be skipped instead of rendered as missing data
ImPlotLineFlags_NoClip = 1 << 13, // markers (if displayed) on the edge of a plot will not be clipped
};
...
void PlotLine(const char* label_id, const T* xs, const T* ys, int count, ImPlotLineFlags flags=0, int offset=0, int stride=sizeof(T));
As you can see, PlotLine
has some new bells and whistles that are enabled with the ImPlotLineFlags_
parameter, like rendering lines as segments or as a closed loop. Several other plotters have also gained new abilities through their respective flags (see the full list below). The special flags in ImPlotItemFlags
can be combined with ANY ImPlotXFlags
, e.g. ImPlotItemFlags_NoLegend|ImPlotLineFlags_Segments
is valid code.
Here's a complete list of flags available for our current plotters:
ImPlotItemFlags_NoLegend // the item won't have a legend entry displayed
ImPlotItemFlags_NoFit // the item won't be considered for plot fits
ImPlotLineFlags_Segments // a line segment will be rendered from every two consecutive points
ImPlotLineFlags_Loop // the last and first point will be connected to form a closed loop
ImPlotLineFlags_SkipNaN // NaNs values will be skipped instead of rendered as missing data
ImPlotLineFlags_NoClip // markers (if displayed) on the edge of a plot will not be clipped
ImPlotScatterFlags_NoClip // markers on the edge of a plot will not be clipped
ImPlotStairsFlags_PreStep // the y value is continued constantly to the left from every x position, i.e. the interval (x[i-1], x[i]] has the value y[i]
ImPlotBarsFlags_Horizontal // bars will be rendered horizontally on the current y-axis
ImPlotBarGroupsFlags_Horizontal // bar groups will be rendered horizontally on the current y-axis
ImPlotBarGroupsFlags_Stacked // items in a group will be stacked on top of each other
ImPlotErrorBarsFlags_Horizontal // error bars will be rendered horizontally on the current y-axis
ImPlotStemsFlags_Horizontal // stems will be rendered horizontally on the current y-axis
ImPlotInfLinesFlags_Horizontal // lines will be rendered horizontally on the current y-axis
ImPlotPieChartFlags_Normalize // force normalization of pie chart values (i.e. always make a full circle if sum < 0)
ImPlotHeatmapFlags_ColMajor // data will be read in column major order
ImPlotHistogramFlags_Horizontal // histogram bars will be rendered horizontally (not supported by PlotHistogram2D)
ImPlotHistogramFlags_Cumulative // each bin will contain its count plus the counts of all previous bins (not supported by PlotHistogram2D)
ImPlotHistogramFlags_Density // counts will be normalized, i.e. the PDF will be visualized, or the CDF will be visualized if Cumulative is also set
ImPlotHistogramFlags_NoOutliers // exclude values outside the specifed histogram range from the count toward normalizing and cumulative counts
ImPlotHistogramFlags_ColMajor // data will be read in column major order (not supported by PlotHistogram)
ImPlotTextFlags_Vertical // text will be rendered vertically
SUPER IMPORTANT NOTE: Each PlotX
function's ImPlotLineFlags flags=0
parameter has been positioned before int offset=0, int stride=sizeof(T)
where applicable. This unfortunately means that folks making use of offset and/or stride will need to update their function calls to include a flags parameter, else they will likely see strange results or crashes without any warning. This may rub some users the wrong way, but it was a necessary evil as it stylistically makes the most sense for the flags parameter to take priority over stride and offset in the default argument order for most use cases and users.
Besides that, items flags brings about a few other API breaking changes users should be aware of:
PlotBarsH
has been removed; usePlotBars
+ImPlotBarsFlags_Horizontal
insteadPlotErrorBarsH
has been removed; usePlotErrorBars
+ImPlotErrorBarsFlags_Horizontal
PlotVLines
andPlotHLines
replaced withPlotInfLines
(+ImPlotInfLinesFlags_Horizontal
)PlotHistogram
/PlotHistogram2D
signatures changed;cumulative
,density
, andoutliers
options now specified viaImPlotHistogramFlags
PlotPieChart
signature changed;normalize
option now specified viaImPlotPieChartFlags
PlotText
signature changes;vertical
option now specified viaImPlotTextFlags_Vertical
Again, this change will likely cause headaches for some users, but with this new system in place you can expect more plotting options to be added in future updates in a flexible and, importantly, maintainable way. Thanks for understanding.
SetupAxisScale
Previously, users could define time and log scales with ImPlotAxisFlags_Log
, and ImPlotAxisFlags_Time
. These flags have been replaced with a more general system using a new the setup function SetupAxisScale
:
// Axis scale
enum ImPlotScale_ {
ImPlotScale_Linear = 0, // default linear scale
ImPlotScale_Time, // date/time scale
ImPlotScale_Log10, // base 10 logartithmic scale
ImPlotScale_SymLog, // symmetric log scale
};
// Sets an axis' scale using built-in options.
void SetupAxisScale(ImAxis axis, ImPlotScale scale);
ImPlotScale_SymLog
is a new scale that produces a symmertic log scale with a linear region roughly between -1 and 1:
More built-in scales may be added in the future. Until then, you can also now define YOUR OWN scales using ImPlotTransform
to provide a forward and inverse function:
// Callback signature for axis transform.
typedef double (*ImPlotTransform)(double value, void* user_data);
// Sets an axis' scale using user supplied forward and inverse transfroms.
void SetupAxisScale(ImAxis axis, ImPlotTransform forward, ImPlotTransform inverse, void* data=NULL);
Example:
static inline double TransformForward_Sqrt(double v, void*) {
return sqrt(v);
}
static inline double TransformInverse_Sqrt(double v, void*) {
return v*v;
}
...
if (ImPlot::BeginPlot("Sqrt")) {
ImPlot::SetupAxis(ImAxis_X1, "Linear");
ImPlot::SetupAxis(ImAxis_Y1, "Sqrt");
ImPlot::SetupAxisScale(ImAxis_Y1, TransformForward_Sqrt, TransformInverse_Sqrt);
ImPlot::PlotLine(...);
ImPlot::EndPlot();
}
New Axis Constraints
You can now constrain axes limits so that users can't pan beyond a min or max value, or zoom beyond a min or max width/height. This is nice if you don't want users straying away from displayed data or zooming too far into view. It is demonstrated in the candlestick demo in implot_demo.cpp
(see Custom Plotters and Tooltips).
// Sets an axis' limits constraints.
void SetupAxisLimitsConstraints(ImAxis axis, double v_min, double v_max);
// Sets an axis' zoom constraints.
void SetupAxisZoomConstraints(ImAxis axis, double z_min, double z_max);
Customize Supported Types
You can now customize the supported types by defining IMPLOT_CUSTOM_NUMERIC_TYPES
at compile time to define your own type list. As an example, you could use the compile time define given by the line below in order to support only float and double.
-DIMPLOT_CUSTOM_NUMERIC_TYPES="(float)(double)"
In order to support all known C++ types, use:
-DIMPLOT_CUSTOM_NUMERIC_TYPES="(signed char)(unsigned char)(signed short)(unsigned short)(signed int)(unsigned int)(signed long)(unsigned long)(signed long long)(unsigned long long)(float)(double)(long double)"
Special thanks to @pthom for inplementing this feature (#397) and greatly simplifying our plotter insantiation pipeline with some mean macro magic!
Continuous Integration
The ImPlot repository now provides CI through GitHub Actions. The jobs are setup to build ImPlot and a headless example application against the latest ImGui version across several compilers and platforms. Jobs are triggered for all new PRs.
Special thanks to @rokups for setting this up (#395), @ozlb for the initial push (#393), @pthom for further improvements (#397), and @ocornut for his thoughtful comments.
Misc. Improvements
- Line plots now honor ImGui's
AntiAliasedLines
andAntiAliasedLinesUseTex
. That's right, ImPlot now uses texture based AA! If you weren't using MSAA, you can now expect signficantly smoother lines for very little performance cost. - Markers and bar plots now render through ImPlot's custom render pipeline instead of ImGui's drawing API. This should speed up those plotters a good bit.
- Compile times for
implot_items.cpp
should now be much quicker now. - Legend entries can be sorted using
ImPlotLegendFlags_Sort