Logplot with zeros / infinite values

I want to plot some data that contains zeros, with log-axes. This does not work easily:

using Plots
xs=[0.0,1.0,2.0]; ys=xs.^2;
plot(xs,ys; xaxis=:log)
#ArgumentError: At least one finite value must be provided to formatter.

The same for data with infinite values (which is the core issue).

Now, what is the kind of output I’d like? Well, infinite values like log(0.0)=-Inf should get a point to the left/right/above/below that smallest/largest finite value that occurs, and I’d ideally get an extra labled tick and an axis break for this.

Apart from the nice axes/ticks, this can be achieved by iterating over the data, computing the smallest/largest finite values, computing a threshold that is somewhat below/above and truncating the infinite values. However, the correct transformation depends on which axes are supposed to be logarithmic, and which ones are supposed to be absolute; so it is really the plot function that should do this transformation.

Why do I want this? First, logarithmic plots with zeros. Second, beyond-threshold sometimes wants to be represented as infinity. E.g. when plotting run-times of algorithms, it is quite sensible to represent out-of-memory as infinity.

So my question is, 1. does there exist a plot option for this? 2. If not, is there a recipe flying around for this?

3 Likes

The log of a value is only defined where the value is greater than zero. Just change the range of the value to be slightly greater than zero.

julia> log(0.0)
-Inf

is a perfectly fine Float64.

Re just changing the value: The annoying thing is, I am plotting quite a number of different shapes into the same plot, and the truncation of infinity depends on both the plot type and the entire spread of shapes: log(0)=-Inf wants to be truncated such that a fixed percentage of the plot window, e.g. 10%, separates the last finite value from infinity. And then my entire plotting code needs to know all the data (to know the range of the axis), as well as the axes-scalings, beforehand. I currently truncate/transform my data by hand, but this is really ugly messy code that is very specific to the kind of data I have. Since Plots.jl already understands how to choose a range it probably should do the truncation of infinities as well.

I mean, I can’t be the only one who wants log-plots for datasets that contain zeros (i.e. infinities after taking the log) to just work?