Plots.jl icon indicating copy to clipboard operation
Plots.jl copied to clipboard

log plot with zeros

Open goretkin opened this issue 5 years ago • 5 comments

I think the backends (at least matplotlib) can handle this, but somehow Plots (Plots v0.25.1) causes errors:

julia> using Plots; pyplot();

julia> (x,y) = ([0.01, 0.02, 0.03], [0.01, 0.0, 0.01]);

julia> plot(x, y; yaxis=:log)

ERROR: PyError ($(Expr(:escape, :(ccall(#= /Users/goretkin/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:44 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'ValueError'>
ValueError("'linthreshx/linthreshy' must be positive")
  File "/Users/goretkin/.julia/conda/3/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 3548, in set_yscale
    ax.yaxis._set_scale(value, **kwargs)
  File "/Users/goretkin/.julia/conda/3/lib/python3.7/site-packages/matplotlib/axis.py", line 767, in _set_scale
    self._scale = mscale.scale_factory(value, self, **kwargs)
  File "/Users/goretkin/.julia/conda/3/lib/python3.7/site-packages/matplotlib/scale.py", line 568, in scale_factory
    return _scale_mapping[scale](axis, **kwargs)
  File "/Users/goretkin/.julia/conda/3/lib/python3.7/site-packages/matplotlib/scale.py", line 419, in __init__
    raise ValueError("'linthreshx/linthreshy' must be positive")

Stacktrace:
 [1] pyerr_check at /Users/goretkin/.julia/packages/PyCall/ttONZ/src/exception.jl:60 [inlined]
 [2] pyerr_check at /Users/goretkin/.julia/packages/PyCall/ttONZ/src/exception.jl:64 [inlined]
 [3] macro expansion at /Users/goretkin/.julia/packages/PyCall/ttONZ/src/exception.jl:84 [inlined]
 [4] __pycall!(::PyCall.PyObject, ::Ptr{PyCall.PyObject_struct}, ::PyCall.PyObject, ::PyCall.PyObject) at /Users/goretkin/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:44
 [5] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{String}, ::Int64, ::PyCall.PyObject) at /Users/goretkin/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:29
 [6] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{String}, ::Base.Iterators.Pairs{Symbol,Real,Tuple{Symbol,Symbol},NamedTuple{(:basey, :linthreshy),Tuple{Int64,Float64}}}) at /Users/goretkin/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:11
 [7] #call#111 at /Users/goretkin/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:89 [inlined]
 [8] (::getfield(PyCall, Symbol("#kw#PyObject")))(::NamedTuple{(:basey, :linthreshy),Tuple{Int64,Float64}}, ::PyCall.PyObject, ::String) at ./none:0
 [9] py_set_scale(::PyCall.PyObject, ::Plots.Axis) at /Users/goretkin/.julia/packages/Plots/oiirH/src/backends/pyplot.jl:933
 [10] _before_layout_calcs(::Plots.Plot{Plots.PyPlotBackend}) at /Users/goretkin/.julia/packages/Plots/oiirH/src/backends/pyplot.jl:1095
...
julia> using Plots; gr();
julia> (x,y) = ([0.01, 0.02, 0.03], [0.01, 0.0, 0.01]);
julia> plot(x, y; yaxis=:log)^C

ERROR: ArgumentError: At least one finite value must be provided to formatter.
Stacktrace:
 [1] showoff(::Array{Float64,1}, ::Symbol) at /Users/goretkin/.julia/dev/Showoff/src/Showoff.jl:108
 [2] optimal_ticks_and_labels(::Plots.Axis, ::Nothing) at /Users/goretkin/.julia/packages/Plots/oiirH/src/axes.jl:215
 [3] optimal_ticks_and_labels at /Users/goretkin/.julia/packages/Plots/oiirH/src/axes.jl:156 [inlined]
 [4] get_ticks(::Plots.Axis) at /Users/goretkin/.julia/packages/Plots/oiirH/src/axes.jl:264
...

goretkin avatar Jun 01 '19 03:06 goretkin

For reference, there's no error:

In [1]: import matplotlib.pyplot as plt

In [2]: plt.semilogy([1,2,3],[1,2,0])
Out[2]: [<matplotlib.lines.Line2D at 0x11c723240>]

In [3]: plt.show()

goretkin avatar Jun 01 '19 03:06 goretkin

Does "wont fix" mean that a patch for this would not be accepted? Why?

On Sat, Sep 25, 2021, 5:32 AM t-bltg @.***> wrote:

Closed #2046 https://github.com/JuliaPlots/Plots.jl/issues/2046.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/JuliaPlots/Plots.jl/issues/2046#event-5359456248, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEN3M522T42IWRSD3E6ZA3UDWJMVANCNFSM4HR7RZKA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

goretkin avatar Sep 25 '21 18:09 goretkin

wontfix because log(0) is undefined.

Current output:

using Plots; pyplot()
(x,y) = ([0.01, 0.02, 0.03], [0.01, 0.0, 0.01])
plot(x, y; yaxis=:log)
┌ Warning: Invalid negative or zero value 0.0 found at series index 2 for log10 based yscale
[...]
ERROR: PyError ($(Expr(:escape, :(ccall(#= [...]/PyCall/BD546/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'ValueError'>
ValueError('Axis limits cannot be NaN or Inf')

Of course a patch could be accepted if there is consensus on that matter. But obtaining a consensus on what to do with undefined behavior, is not guaranteed.

t-bltg avatar Sep 25 '21 18:09 t-bltg

I think the behaviour is already to skip points, fixed here: https://github.com/JuliaPlots/RecipesPipeline.jl/pull/61 . This follows the precedent of linear scale plots skipping NaN and Inf.

What fails, however, is the automatic calculation of the limits. For linear plots Inf is simply ignored, but on a log scale instead you get an error. But if you explicitly provide limits, then it can draw the plot.

julia> using Plots; gr();

julia> (x,y) = ([0.01, 0.02, 0.03], [0.01, 0.0, 0.01]);

julia> p1 = plot(1:8, [1,2,Inf,4,5,NaN,7,8], title="linear")

julia> p2 = scatter(x, y, yaxis=(:log10, [0.001, 0.1]))  # with x, y from above
┌ Warning: Invalid negative or zero value 0.0 found at series index 2 for log10 based yscale
└ @ Plots ~/.julia/packages/Plots/AJMX6/src/utils.jl:95

julia> p3 = plot(cumsum(randn(1000,4), dims=1), yaxis=(:log10, [0.1, :auto]), title="RecipesPipeline.jl#61")

julia> plot(p1, p2, p3)

(jl_Nt1QFi) pkg> st Plots
Status `/private/var/folders/yq/4p2zwd614y59gszh7y9ypyhh0000gn/T/jl_Nt1QFi/Project.toml`
  [91a5bcdd] Plots v1.25.0

issue2046

mcabbott avatar Dec 05 '21 22:12 mcabbott

upvoted since I don't want to use plot(log10.(a)) and manually set tick texts all the time.

wontfix because log(0) is undefined.

plot(log10.(a)) works, so it's not a good reason.

putianyi889 avatar Jul 11 '22 21:07 putianyi889