Skip to content

Symmetric logarithmic plotting #245

@Cazadorro

Description

@Cazadorro

For most data I deal with, I don't really care about displaying values lograrithmicaly between -1 -> 1, and in fact, this gets in the way of plotting. Other plotting APIs use the term "symmetric log plotting" to handle this, ie matplot lib:

https://matplotlib.org/stable/gallery/scales/symlog_demo.html

see here for more details .

Basically symlog/symmetric log plots log but only after a certain absolute value threshold. This allows it to plot around zero. One benefit of this is that, for example, the example histogram plot does not appear to extend all the way down to infinity.

As an example use case where this would be helpful, I'm trying to plot histograms that have some extreme value differences. When switching to a normal log plot, all the bars look the same and the Y axis space taken up becomes very very large (due to them all encompassing 1). The graph is pretty much un-navigable and impossible to read. With symmetric log plotting in matplotlib, the values become visible within one screen with out special axis grid spacing rules.

Looking through the code it looks like a change like this may be difficult, I don't exactly understand how flags propagate through ImPlot. Additionally there would need to be some way to feed in this "Linear threshold" parameter to ImPlot. But in the future there's likely going to be more plotting functions that should be used. In those cases there's likely going to be a need to specify user defined functions for mapping to avoid work for every function needed.

Matplotlib takes straight functions and is able to use those to plot. ImPlot appears to rely on being able to transform between pixels and plot space and vice versa, and I think Matplotlib does as well (forward and inverse functions must be provided in matplotlib) To support custom functions currently then, two functions would have to be provided. Allowing user defined functions for plotting mitigates issues if the API doesn't handle certain edge cases.

To that end it would be nice to have:

ImPlotAxisFlags_SymLogScale which maintains the same exclusion as ImPlotAxisFlags_LogScale, and adds exclusion to both (so log can't be used along with symlog).

Some method of setting the "linear threshold" parameter, either through some sort of style push/pop or something else

ImPlotAxisFlags_CustomScale which uses some user specified function to plotting function (forward/inverse) potentially with the signature double(double x, void* user_data), or if C++11 features are fine to add: std::function<double(double)> where user data can be added as a closure parameter and not have to specifically be dealt with by the API. Right now it is possible to create a custom plot, but for only scaling it is kind of overkill since all work for any graph you want to user the scaling for needs to be re-done.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions