Is there a way to plot negative numbers on a log scale?

I know we are not supposed to be able to take the log of a negative number (or 0), but sometimes the scale is really useful.

using Plots
x = -10:0.01:10
y = x
plot(x, y)
plot(x, y, yaxis = log10.(y .+ 100))

image

It’s not what I thought would happen.

image

Do you have any suggestions on how to do this?

I am sorry to tell you, but log has infinite complex values as a solution for negative arguments (if i recall that right) . Is there a way to keep the argument positive?

Edit: Oh i see, you added a hundred. So that should not be the issue.

I’m trying to keep it positive by adding 100 to each y value with yaxis = log10.(y .+ 100). I thought it would work but the yaxis loses its numbers.

I don’t know if Plots.jl supports this, but PyPlot.jl has a nifty axis scaling that’s called symlog: Symlog Demo — Matplotlib 3.1.0 documentation In essence, it makes large numbers logarithmic, both for positive and negative numbers, but keeps a small interval around the zero crossing linear.

1 Like

Often when working with logs only the absolute value of the argument is of interest. Other times I plot positive and negative values in different colors; eg (with pyplot, exploiting the fact that semilog silently ignores negative values) julia> semilogy(x, f.(x)); semilogy(x, .-f.(x)).

A little hack with yticklabels in GR or GRUtils - probably there is something similar in Plots, I didn’t look at it.

using GR
x = -10:0.01:10
y = x
yticklabels(x -> x-11)
plot(x, y.+11, ylog=true)
using GRUtils
x = -10:0.01:10
y = x
plot(x, y.+11, ylog=true)
yticklabels(x -> x-11)

In either case:

@rbange at https://gitter.im/tbreloff/Plots.jl suggested a log-modulus transformation, which works very nicely and preserves the signs and 0 values.

plot(x, sign.(y).*log10.(abs.(y).+1))

image

It would be ideal to have the yaxis show 10^ (like a regular log10 axis in Julia), but am not sure how to specify that.