Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Announcements and New Features (2020) #48

Closed
epezent opened this issue Jun 1, 2020 · 31 comments
Closed

Announcements and New Features (2020) #48

epezent opened this issue Jun 1, 2020 · 31 comments
Labels

Comments

@epezent
Copy link
Owner

epezent commented Jun 1, 2020

Announcements of changes and new features will be posted here. Click Subscribe to the right to receive updates!

PLEASE DO NOT COMMENT ... EMOJIS ARE WELCOME :)

@epezent
Copy link
Owner Author

epezent commented Jun 1, 2020

Filled Plots (v0.3 - 6/1/2020)

ImPlot::PlotLines can now be filled by pushing a color for ImPlotCol_Fill. The plot will be filled to the x-axis zero, and zero-crossings are appropriately handled.

Filled Plots

@epezent
Copy link
Owner Author

epezent commented Jun 1, 2020

Support for double (v0.3 - 6/1/2020)

The public API has been extended to support double precision data. Internally, ImPlot is also now using double precision to handle axes and scaling, which improves stability during extreme zooming and panning. Users of the previous float API should be unaffected and can continue as they were.

@epezent epezent pinned this issue Jun 1, 2020
@epezent
Copy link
Owner Author

epezent commented Jun 3, 2020

Colormaps and Heatmaps (v0.3 - 6/2/2020)

ImPlot now provides several built-in colormaps (previously "palettes").

colormaps

Heatmap Charts have been added. An optional utility function can be used to render a colormap scale. (Note the artifacting below is due to GIF compression. See the demo for a better representation.).

heatmaps

@epezent
Copy link
Owner Author

epezent commented Jun 3, 2020

User Defined Ticks (v0.3 - 6/3/2020)

Users can now add custom ticks to any axis. The ticks can optionally be decorated with a custom string label. The default generated ticks will be hidden by default, but can be kept if desired.

ticks

image

image

@epezent
Copy link
Owner Author

epezent commented Jun 7, 2020

16-bit Indices (v0.3 - 6/7/2020)

Issues related to data truncation and glitching when using 16-bit indices have been resolved by #41 and ocornut/imgui@f6120f8

Therefore it is important that you are using the latest version of ImGui to avoid glitching. 32-bit indices continue to work as before.

Moving forward, we recommend that users stick to 16-bit indices if possible. You may see a slight performance boost from this, and it is recommended by ImGui for compatibility's sake.

Special thanks to @sergeyn and @ocornut for their work on this.

@epezent
Copy link
Owner Author

epezent commented Jun 9, 2020

Horizontal Error Bars (v0.3 - 6/8/2020)

@ChiefSeaBiscuit has added support for horizontal error bars.

ErrorBarH

@epezent
Copy link
Owner Author

epezent commented Jun 14, 2020

PlotShaded (v0.4 - 6/14/2020)

  • PlotShaded has been introduced. This allows regions between two lines or a line and a horizontal reference to be filled. Note that this replaces the previous Fill Plots implementation above Announcements and New Features (2020) #48 (comment)
  • ImPlotStyleVar_FillAlpha was added so that the alpha of fills (e.g. shaded regions, bar fills, pie charts, marker fills) can be easily modified.
  • Plot items with the same label_id will be grouped together in the legend, appearing as one item. This can be seen on the Filled Line Plots, Shaded Plots, and Error Bars demos.
  • The flags ImPlotAxisFlag_Adaptive and ImPlotFlags_Cull were removed. Adaptive grid divisions were always the default, regardless of this flag, thus it is no longer needed. Culling is done by default where possible, as there's little reason not to.

image

fill

@epezent
Copy link
Owner Author

epezent commented Jun 16, 2020

ImPlotInputMap (v0.4 - 6/15/2020)

@JaapSuter has added support for input remapping. The current input mapping can be retrieved and modified with ImPlotInputMap& GetInputMap() where:

struct ImPlotInputMap {
    ImGuiMouseButton PanButton;             // LMB      enables panning when held
    ImGuiKeyModFlags PanMod;                // none     optional modifier that must be held for panning
    ImGuiMouseButton FitButton;             // LMB      fits visible data when double clicked
    ImGuiMouseButton ContextMenuButton;     // RMB      opens plot context menu (if enabled) when double clicked
    ImGuiMouseButton BoxSelectButton;       // RMB      begins box selection when pressed and confirms selection when released
    ImGuiKeyModFlags BoxSelectMod;          // none     optional modifier that must be held for box selection
    ImGuiMouseButton BoxSelectCancelButton; // LMB      cancels active box selection when pressed
    ImGuiMouseButton QueryButton;           // MMB      begins query selection when pressed and end query selection when released
    ImGuiKeyModFlags QueryMod;              // none     optional modifier that must be held for query selection
    ImGuiKeyModFlags QueryToggleMod;        // Ctrl     when held, active box selections turn into queries
    ImGuiKeyModFlags HorizontalMod;         // Alt      expands active box selection/query horizontally to plot edge when held
    ImGuiKeyModFlags VerticalMod;           // Shift    expands active box selection/query vertically to plot edge when held
    ImPlotInputMap();
};

This is somewhat experimental, and it may not enable all desired input approaches. If you find that you need more control/options, please submit an Issue or PR.

@epezent
Copy link
Owner Author

epezent commented Jun 24, 2020

Invisible Legend Entries (v0.4 - 6/23/2020)

Plot items with labels entirely prefixed with ## will no longer display an entry in the legend. This can be used to plot data that you don't want displayed in the legend. The data will continue to respond to double-clicks for fitting.

ImPlot::PlotLine("MyData1",x,y);    // displays "MyData1" in legend
ImPlot::PlotLine("MyData##2",x,y);  // displays "MyData" in legend
ImPlot::PlotLine("##MyData3",x,y);  // no legend entry displayed

@epezent epezent added the discussion Thread for discussions and idea generation label Jun 24, 2020
@epezent
Copy link
Owner Author

epezent commented Jul 27, 2020

Axis Hovering (v0.4 - 7/26/2020)

Axes can now be checked to see if they are hovered with IsPlotXAxisHovered and IsPlotYAxisHovered. If a drag and drop payload is available, a drag and drop rect will be drawn around hovered y-axes. As a result, drag and drop to specific y-axes is now possible (see demo for example code):

dnd

On a similar note, IsLegendEntryHovered has been introduced.

Special thanks to @ozlb!

Repository owner deleted a comment from ejyanezp Jul 28, 2020
Repository owner locked and limited conversation to collaborators Jul 28, 2020
@epezent
Copy link
Owner Author

epezent commented Aug 16, 2020

Explicit ImPlotContexts and Major Refactors (v0.5 - 8/16/2020)

Previously, the main ImPlot context and state manager was statically initialized in implot.cpp as a global variable. This approach worked fine for most users, but in some scenarios it is undesirable and results in hard to find bugs (see #75). Furthermore, it did not mirror ImGui's approach to context managment.

In v0.5 and onward, you must manually initialize and destroy an ImPlotContext before you can use the library API. This is done simply wherever you initialize/destroy your ImGui context:

ImGui::CreateContext();
ImPlot::CreateContext();
...
ImPlot::DestroyContext();
ImGui::DestroyContext();

You can keep a pointer to each ImPlotContext you create, and change contexts with SetCurrentContext if desired. The current context can be retrieved with GetCurrentContext. This exactly mirrors context management in ImGui.

ImPlot v0.5 also brings about major refactors to the internal code base as proposed in #70. A substantial portion of ImPlot's guts have been exposed in implot_internal.h. Like imgui_internal.h, you can use this file to debug, understand or extend ImPlot features but we don't provide any guarantee of forward compatibility. Expect frequent changes to this file!

Additionally, source code for rendering plot items has been moved to implot_items.cpp. This was done simply to keep the code base more manageable and easier for new contributors to comprehend.

Overall, these changes should not cause significant headaches for end-users. If you notice that something isn't working as it previously did, please submit an Issue or PR.

@epezent epezent changed the title Announcements and New Features Announcements and New Features (2020) Aug 17, 2020
@epezent
Copy link
Owner Author

epezent commented Aug 19, 2020

Per Axis Context Menus (v0.5 - 8/19/2020)

Individual axes can be double clicked to open their own context menus:

context

@epezent
Copy link
Owner Author

epezent commented Aug 24, 2020

Styling Overhaul (v0.5 - 08/23/2020)

A number of improvements have been made to ImPlot's styling API. As before, ImPlot, by default, will automatically deduce plot colors based on your current ImGui style.

However, it is now possible to customize nearly every aspect of plot styles. Both ImPlotStyleVar_ and ImPlotCol_ enums have been expanded to include more options. To demonstrate this, a Style Editor block has been added to the demo (Tools -> Style Editor (ImPlot)). You can invoke this editor from your own applications with ShowStyleEditor found in implot.h.

image

image

image

Using the Style Editor, you can create your own custom style or replicate the look of your other favorite plotting library. For example, here's an example replicating the look of seaborn (shown in the demo under Custom Styles)

image

Styles can be saved to memory, or exported to the clipboard or console.

Additionally, colormaps can now be pushed and popped with PushColormap and PopColormap, avoiding the unnecessary copying and loss of previous colormaps that SetColormap caused. A new colormap ImPlotColormap_Deep was added as well.

@epezent
Copy link
Owner Author

epezent commented Aug 24, 2020

Built-In Style Colors (v0.5 - 8/24/2020)

Three built-in style color sets were added. The three styles have been tuned to complement the default ImGui styles Classic, Dark, and Light. Automatic styling from the current ImGui style remains the default. The styles can be set with:

// Style colors from current ImGui style (default)
void StyleColorsAuto(ImPlotStyle* dst = NULL);
// Style colors for ImGui "Classic".
void StyleColorsClassic(ImPlotStyle* dst = NULL);
// Style colors for ImGui "Dark".
void StyleColorsDark(ImPlotStyle* dst = NULL);
// Style colors for ImGui "Light".
void StyleColorsLight(ImPlotStyle* dst = NULL);

Here you can see the difference between default Auto (left) and the built-in styles (right):

Classic + ImPlotColormap_Pastel

image (4)

Dark + ImPlotColormap_Deep

image (3)

Light + ImPlotColormap_Deep

image (5)

@epezent
Copy link
Owner Author

epezent commented Sep 1, 2020

Next Item Styling Functions (v0.5 - 9/1/2020)

The following functions have been added so that you can conveniently style items without pushing/popping style variables. The demo has been updated to use these where applicable.

// The following can be used to modify the style of the next plot item ONLY. They do
// NOT require calls to PopStyleX. Leave style attributes you don't want modified to
// IMPLOT_AUTO or IMPLOT_AUTO_COL. Automatic styles will be deduced from the current
// values in the your ImPlotStyle or from Colormap data.

// Set the line color and weight for the next item only.
void SetNextLineStyle(const ImVec4& col = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO);
// Set the fill color for the next item only.
void SetNextFillStyle(const ImVec4& col = IMPLOT_AUTO_COL, float alpha_mod = IMPLOT_AUTO);
// Set the marker style for the next item only.
void SetNextMarkerStyle(ImPlotMarker marker = IMPLOT_AUTO, float size = IMPLOT_AUTO, const ImVec4& fill = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO, const ImVec4& outline = IMPLOT_AUTO_COL);
// Set the error bar style for the next item only.
void SetNextErrorBarStyle(const ImVec4& col = IMPLOT_AUTO_COL, float size = IMPLOT_AUTO, float weight = IMPLOT_AUTO);

For example:

if (ImPlot::BeginPlot("My Plot")) {
    ImPlot::SetNextLineStyle(ImVec4(1,1,0,1));
    ImPlot::SetNextMarkerStyle(ImPlotMarker_Square);
    ImPlot::PlotLine("yellow line with square markers", xs, ys, 10);
    ImPlot::EndPlot();
}

@epezent
Copy link
Owner Author

epezent commented Sep 1, 2020

Legend Utilities - (v0.5 - 9/1/2020)

Two new legend utilities are available, thanks to @PeterJohnson!

The first allows for legend entries to be used as drag and drop sources. You can uses this to rearrange items on a single plot, move items between plots, or however else you choose.

// Begin a drag and drop source from a legend entry. The only supported flag is SourceNoPreviewTooltip
bool BeginLegendDragDropSource(const char* label_id, ImGuiDragDropFlags flags = 0);
// End legend drag and drop source.
void EndLegendDragDropSource();

dnd_legend

The second allows you to add context popup menus to legend entries. You can use this to inject item specific functionality, controls, styling options, etc.

// Begin a popup for a legend entry.
bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button = 1);
// End a popup for a legend entry.
void EndLegendPopup();

pop_legend

@epezent
Copy link
Owner Author

epezent commented Sep 2, 2020

PlotStems - (v0.6 - 9/2/2020)

Vertical stem plots have been added.

/// Plots vertical stems.
void PlotStems(const char* label_id, const float* values, int count, float y_ref = 0, int offset = 0, int stride = sizeof(float));
void PlotStems(const char* label_id, const double* values, int count, double y_ref = 0, int offset = 0, int stride = sizeof(double));
void PlotStems(const char* label_id, const float* xs, const float* ys, int count, float y_ref = 0, int offset = 0, int stride = sizeof(float));
void PlotStems(const char* label_id, const double* xs, const double* ys, int count, double y_ref = 0, int offset = 0, int stride = sizeof(double));

image

@epezent
Copy link
Owner Author

epezent commented Sep 6, 2020

Simplified Flags - (v0.7 - 9/6/2020)

Usage of ImPlotFlags and ImPlotAxisFlags was simplified so that a value of 0 (i.e. now ImPlotFlags_None or ImPlotAxisFlags_None) for either will give default results. This means that flags that were previously combined in ImPlotFlags_Default or ImPlotAxisFlags_Default have been inverted and that these default flagsets have been removed. For example, ImPlotFlags_Legend is now ImPlotFlags_NoLegend.

The rational for this decision was that:

  1. This is how ImGuiWindow_Flags etc behave
  2. It simplifies enabling non-default flags. For example to enable log scale you can do:
BeginPlot("plot", "x", "y", ImVec2(0,0), 0, ImPlotFlags_LogScale)

instead of what was previously required:

BeginPlot("plot", "x", "y", ImVec2(0,0), ImPlotFlags_Default, ImPlotAxisFlags_Default | ImPlotFlags_LogScale)

@epezent
Copy link
Owner Author

epezent commented Sep 6, 2020

Date/Time Formatting - (v0.7 9/7/2020)

Long overdue support for date/time formatting has finally been added (see #34 for history). The feature can be enabled with the flag ImPlotAxisFlags_Time. Some important details:

  • Currently it only works for the x-axis. Trying to enable it on a y-axis will trigger a user-error assertion.
  • It is mutually exclusive with ImPlotAxisFlags_LogScale. Combining these will also trigger an assertion.
  • When enabled, x-axis values are interpreted as UNIX timestamps in seconds (e.g. 1599243545).
  • By default, labels are shown as UTC time. You can enable local time with GetStyle().UseLocalTime = true.
  • The unit splits are: year, month, day, hour, minute, second, millisecond, and microsecond. The labels will intelligently change units based on the plot range and pixel width.
  • Months and years are subdivided so that each subdivision is on an exact day or month, respectively. This means that subdivisions are not always equally spaced.
  • Sub-second precision is possible down to the microsecond level using double (e.g. 1599243545.123456)
  • There are several time-related utility functions and a high precision timestamp struct, ImPlotTime, in implot_internal.h. You can use these if you choose. They may be added to the public API at some point in the future.

Special thanks to @Prinkesh for their initial PR, and @leeoniya for providing help and insight as well as offering a great example to go off of in his library uPlot.

Demo Example

time-zoom

Sub-Second Precision

time-us

UTC/Local Time

time-local

Candlestick Demo

time-candle

Repository owner unlocked this conversation Sep 6, 2020
@epezent
Copy link
Owner Author

epezent commented Sep 6, 2020

Linked Plot Limits - (v0.7 - 9/6/2020)

You can now link plot limits to externally owned values with LinkNextPlotLimits. With this, you can link or one or multiple plot axes together, so that they track each other. The system is generic enough to enable a number of other advanced use cases...use your imagination!

static double xmin = 0, xmax = 1, ymin = 0, ymax = 1;
double data[2] = {0,1};

ImPlot::LinkNextPlotLimits(&xmin, &xmax, &ymin, &ymax);
if (ImPlot::BeginPlot("Plot A")) { 
    ImPlot::PlotLine("Line",data,2);
    ImPlot::EndPlot(); 
}

ImPlot::LinkNextPlotLimits(&xmin, &xmax, &ymin, &ymax);
if (ImPlot::BeginPlot("Plot B")) { 
    ImPlot::PlotLine("Line",data,2);
    ImPlot::EndPlot(); 
}

linked-axes

@epezent
Copy link
Owner Author

epezent commented Sep 8, 2020

Support for Scalar Types - (v0.8 - 9/7/2020)

All plotting functions now support the following types:

float, double, ImS8, ImU8, ImS16, ImU16, ImS32, ImU32, ImS64, ImU64

Since those types are just typedefs, it's possible to use built-in types like int, short, size_t, etc too.

This was accomplished by forward declaring templated versions of the API in implot.hpp, and defining and explicitly instantiating them in implot_items.cpp. So, while the function declarations are templated, you are no intended to use them generically with custom types. You will get a linker issue if you try.

Consequently, I had to introduce a G post-fix to plotting functions that accept a custom getter function pointer, e.g. PlotLineG. Otherwise, you may continue as you were; no changes are necessary :)

Usage of different types has been sprinkled throughout the demo.

See #104 for more information and detail.

@epezent
Copy link
Owner Author

epezent commented Sep 10, 2020

Date/Time Pickers - (v0.8 - 9/9/2020)

When ImPlotAxisFlags_Time is enabled, the context menu range selectors will now display a date/time picker. These two widgets are available in implot_internal.h (ShowDatePicker and ShowTimePicker) if you wish to use them outside of the plot or in an entirely different context.

date

date-plot

@epezent
Copy link
Owner Author

epezent commented Sep 10, 2020

xscale and x0 - (v0.8 - 9/10/2020)

The single array version (i.e. T values*) of PlotLine, PlotScatter, PlotShaded, and PlotStems have been given two additional input arguments xscale and x0. Previously, the x value for these functions was determined by the index (0,1,2...). Now you can linearly scale and offset the index. This is particularly useful if you have a set of equally spaced y samples and don't want to generate a temporary array of x values. For example, if you have a set of 48 kHz audio samples, you can set xscale to 1/48000 to view the data in units of seconds instead of sample index.

Note that if you were using these functions previously with offset and/or stride, you will need to update the positions of these arguments since xscale and x0 precede them.

xscale

@epezent
Copy link
Owner Author

epezent commented Sep 18, 2020

PlotImage - (v0.8 - 9/17/2020)

You can now add images to plots:

// Plots an axis-aligned image. #bounds_min/bounds_max are in plot coordinatse (y-up) and #uv0/uv1 are in texture coordinates (y-down).
void PlotImage(const char* label_id, ImTextureID user_texture_id, const ImPlotPoint& bounds_min, const ImPlotPoint& bounds_max, const ImVec2& uv0=ImVec2(0,0), const ImVec2& uv1=ImVec2(1,1), const ImVec4& tint_col=ImVec4(1,1,1,1));

plotimage

@epezent
Copy link
Owner Author

epezent commented Sep 20, 2020

Annotations - (v0.8 - 9/19/2020)

An API for annotating plots has been added. Points can be annotated with the following:

void Annotate(double x, double y, const ImVec2& pix_offset, const char* fmt, ...);
void Annotate(double x, double y, const ImVec2& pix_offset, const ImVec4& color, const char* fmt, ...);
void AnnotateClamped(double x, double y, const ImVec2& pix_offset, const char* fmt, ...);
void AnnotateClamped(double x, double y, const ImVec2& pix_offset, const ImVec4& color, const char* fmt, ...);
  • The functions with a color argument produce callout bubbles as demonstrated on the left, while the the no-color-argument versions produce plain text as on the right.
  • The Clamped variants will clamp the annotation label so that it is always visible in the plot area even if the annotated point is outside the plot limits.
  • The offset is handled such that you don't have to consider the label size when offsetting to the left or above the annotated point. If you want to center the annotation at the annotated point, pass ImVec2(0,0).
  • Annotation padding can be adjusted with ImPlotStyleVar_AnnotationPadding.

image

@epezent
Copy link
Owner Author

epezent commented Sep 20, 2020

Drag Lines and Points - (v0.8 - 9/19/2020)

New tools for creating draggable reference lines and points have been added. You can use these to enhance the interactivity of your plot. Special thanks to @bear24rw and @ozlb for the initial idea.

bool DragLineX(const char* id, double* x_value, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
bool DragLineY(const char* id, double* y_value, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
bool DragPoint(const char* id, double* x, double* y, bool show_label = true, const ImVec4& col = IMPLOT_AUTO_COL, float radius = 4);

guides
bez

@epezent
Copy link
Owner Author

epezent commented Oct 19, 2020

ISO 8601 Date Formatting - (v0.8 - 10/18/2020)

Non-US users rejoice! Date formatting using ISO 8601 can now be enabled with ImPlotStyle::UseISO8601. Note that this will only affect date formatting. Time will still be formatted according to the value of ImPlotStyle::Use24HourClock.

iso

@epezent
Copy link
Owner Author

epezent commented Oct 19, 2020

Configurable Legend Locations - (v0.8 - 10/18/2020)

You can now configure the location and orientation of each plot's legend:

// Used to position items on a plot (e.g. legends, labels, etc.)
enum ImPlotLocation_ {
    ImPlotLocation_Center    = 0,                                          // center-center
    ImPlotLocation_North     = 1 << 0,                                     // top-center
    ImPlotLocation_South     = 1 << 1,                                     // bottom-center
    ImPlotLocation_West      = 1 << 2,                                     // center-left
    ImPlotLocation_East      = 1 << 3,                                     // center-right
    ImPlotLocation_NorthWest = ImPlotLocation_North | ImPlotLocation_West, // top-left
    ImPlotLocation_NorthEast = ImPlotLocation_North | ImPlotLocation_East, // top-right
    ImPlotLocation_SouthWest = ImPlotLocation_South | ImPlotLocation_West, // bottom-left
    ImPlotLocation_SouthEast = ImPlotLocation_South | ImPlotLocation_East  // bottom-right
};

// Used to orient items on a plot (e.g. legends, labels, etc.)
enum ImPlotOrientation_ {
    ImPlotOrientation_Horizontal, // left/right
    ImPlotOrientation_Vertical    // up/down
};

// Set the location of the current plot's legend.
void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation = ImPlotOrientation_Vertical, bool outside = false);

You can also change the location of the mouse position label text:

// Set the location of the current plot's mouse position text (default = South|East).
void SetMousePosLocation(ImPlotLocation location);

Usage:

if (ImPlot::BeginPlot("##Legend","x","y",ImVec2(-1,0))) {
    ImPlot::SetLegendLocation(ImPlotLocation_South, ImPlotOrientation_Horizontal, true);
    ...
    ImPlot::EndPlot();
}

Demo:

legend

Note that you may experience popping/shifting for outside legends on the first and second frames of a plot. This is because we don't know the labels in a legend and thus the legend's size until the second frame. There isn't much we can do about this at the moment; it's just a limitation of being an immediate mode plotting library :)

@epezent
Copy link
Owner Author

epezent commented Oct 19, 2020

Stairstep Plots - (v0.8 - 10/19/2020)

Stairstep plots have been added:

// Plots a a stairstep graph. The y value is continued constantly from every x position, i.e. the interval [x[i], x[i+1]) has the value y[i].
void PlotStairs(const char* label_id, const T* values, int count, double xscale=1, double x0=0, int offset=0, int stride=sizeof(T));
void PlotStairs(const char* label_id, const T* xs, const T* ys, int count, int offset=0, int stride=sizeof(T));
void PlotStairsG(const char* label_id, ImPlotPoint (*getter)(void* data, int idx), void* data, int count, int offset=0);

stairs

@epezent
Copy link
Owner Author

epezent commented Nov 16, 2020

ImPlotFlags_Equal - (v0.9 - 11/15/2020)

Primary X and Y axes can now be constrained to have equal aspect ratios with ImPlotFlags_Equal. See #111

euqal2

@epezent
Copy link
Owner Author

epezent commented Jan 7, 2021

See Announcements 2021

Repository owner locked and limited conversation to collaborators Mar 1, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Projects
None yet
Development

No branches or pull requests

1 participant