# Logarithmic scaling with plotly

**URL:** <https://discourse.julialang.org/t/logarithmic-scaling-with-plotly/59026>\
**Category:** General Usage\
**Tags:** plotting\
**Created:** [April 11, 2021, 9:53am UTC](https://discourse.julialang.org/t/logarithmic-scaling-with-plotly/59026 "2021-04-11T09:53:48Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [April 11, 2021, 9:53am UTC](https://discourse.julialang.org/t/logarithmic-scaling-with-plotly/59026/1 "2021-04-11T09:53:48Z")

</div>

I want to create my own recipe for bodeplots, where both the x and y axis normally has logarithmic scaling. So I can easily create a plot with with an exponential relation:

```julia
using Plots
plotly()

xs = 0:0.001:10
ys = exp.(xs)
plot(xs, ys)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/c/7ca5733816f43806d9590dbc94738f9a6eb15fa3.png)

And I can get a logarithmic scaling on the y-axis by

```julia
plot(xs, ys, yaxis=:log)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/e/6/e6d2716aae1921a3196fd0cffe5d6ab7047a5ffb.png)

However, when trying to set the scale if the x-axis or both (by setting the `xaxis` or `axis` kwargs. Replacing `axis` with `scale` does seems like it does exactly the same in all cases), I get the following error:

```julia
julia> plot(xs, ys, xaxis=:log)
┌ Warning: No strict ticks found
└ @ PlotUtils C:\Users\densb\.julia\packages\PlotUtils\es5pb\src\ticks.jl:283
Error showing value of type Plots.Plot{Plots.PlotlyJSBackend}:
ERROR: ArgumentError: At least one finite value must be provided to formatter.
Stacktrace:
  [1] showoff(xs::Vector{Float64}, style::Symbol)
    @ Showoff ~\.julia\packages\Showoff\C1Bj4\src\Showoff.jl:111
  [2] optimal_ticks_and_labels(ticks::Nothing, alims::Tuple{Float64, Float64}, scale::Symbol, formatter::Symbol)
    @ Plots ~\.julia\packages\Plots\SVksJ\src\axes.jl:197
  [3] get_ticks(::Symbol, ::Vector{Float64}, ::Vector{Any}, ::Tuple{Float64, Float64}, ::Vararg{Any, N} where N)
    @ Plots ~\.julia\packages\Plots\SVksJ\src\axes.jl:251
  [4] get_ticks(sp::Plots.Subplot{Plots.PlotlyJSBackend}, axis::Plots.Axis; update::Bool)
    @ Plots ~\.julia\packages\Plots\SVksJ\src\axes.jl:232
  [5] get_ticks
    @ ~\.julia\packages\Plots\SVksJ\src\axes.jl:221 [inlined]
  [6] tick_padding(sp::Plots.Subplot{Plots.PlotlyJSBackend}, axis::Plots.Axis)
    @ Plots ~\.julia\packages\Plots\SVksJ\src\backends.jl:76
  [7] _update_min_padding!(sp::Plots.Subplot{Plots.PlotlyJSBackend})
    @ Plots ~\.julia\packages\Plots\SVksJ\src\backends.jl:109
  [8] iterate
    @ .\generator.jl:47 [inlined]
  [9] _collect(c::Matrix{AbstractLayout}, itr::Base.Generator{Matrix{AbstractLayout}, typeof(Plots._update_min_padding!)}, #unused#::Base.EltypeUnknown, isz::Base.HasShape{2})
    @ Base .\array.jl:691
 [10] collect_similar
    @ .\array.jl:606 [inlined]
 [11] map
    @ .\abstractarray.jl:2294 [inlined]
 [12] _update_min_padding!(layout::Plots.GridLayout)
    @ Plots ~\.julia\packages\Plots\SVksJ\src\layouts.jl:282
 [13] prepare_output(plt::Plots.Plot{Plots.PlotlyJSBackend})
    @ Plots ~\.julia\packages\Plots\SVksJ\src\plot.jl:189
 [14] display(d::VSCodeServer.InlineDisplay, m::MIME{Symbol("application/vnd.plotly.v1+json")}, x::Plots.Plot{Plots.PlotlyJSBackend})      
    @ VSCodeServer ~\.vscode\extensions\julialang.language-julia-1.1.38\scripts\packages\VSCodeServer\src\display.jl:0
 [15] display(d::VSCodeServer.InlineDisplay, mime::String, x::Any)
    @ Base.Multimedia .\multimedia.jl:216
 [16] display(d::VSCodeServer.InlineDisplay, x::Plots.Plot{Plots.PlotlyJSBackend})
    @ VSCodeServer ~\.vscode\extensions\julialang.language-julia-1.1.38\scripts\packages\VSCodeServer\src\display.jl:108
 [17] display(x::Any)
    @ Base.Multimedia .\multimedia.jl:328
 [18] #invokelatest#2
    @ .\essentials.jl:708 [inlined]
 [19] invokelatest
    @ .\essentials.jl:706 [inlined]
 [20] print_response(errio::IO, response::Any, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})        
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:247
 [21] (::REPL.var"#40#41"{REPL.LineEditREPL, Pair{Any, Bool}, Bool, Bool})(io::Any)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:231
 [22] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:462
 [23] print_response(repl::REPL.AbstractREPL, response::Any, show_value::Bool, have_color::Bool)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:229
 [24] (::REPL.var"#do_respond#61"{Bool, Bool, REPL.var"#72#82"{REPL.LineEditREPL, REPL.REPLHistoryProvider}, REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::Any, ok::Bool)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:798
 [25] #invokelatest#2
    @ .\essentials.jl:708 [inlined]
 [26] invokelatest
    @ .\essentials.jl:706 [inlined]
 [27] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
    @ REPL.LineEdit C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\LineEdit.jl:2441
 [28] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:1126
 [29] (::REPL.var"#44#49"{REPL.LineEditREPL, REPL.REPLBackendRef})()
    @ REPL .\task.jl:406

```

I don’t know what “strict ticks” means, and I don’t see why I should supply ticks.

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [April 11, 2021, 10:01am UTC](https://discourse.julialang.org/t/logarithmic-scaling-with-plotly/59026/2 "2021-04-11T10:01:44Z")

</div>

During the time of writing this post, I solved my problem. I decided to post and answer it anyways, in case someone else googles the same problem.

The problem is that determening x-ticks is not trivial for a logarithmic scale. Normal plots often go from 0 to something, but on a logarithmic scale, there is an infinite number of logarithmically spaced ticks between 0 and 1.

My hacky solution is this:  
I have an idea that most things I want to plot will be between 10^-10 and 10^20. So I define the following function:

```julia
function get_x_ticks(x_lower, x_upper)
    initial_range = -10:1.0:20
    ticks = Float64[]
    for i in initial_range
        if x_lower ≤ 10^i ≤ x_upper
            push!(ticks, i)
        end
    end
    return 10 .^ ticks
end

```

When plotting, I generally supply a vector (or range) of x-values, `xs`. So create my plot with something like

```julia
plot(xs, ys, xticks=get_x_ticks(xs[1], xs[end]), scale=:log10

```

In my test, the lowest x-tick was -3 where I expected -10. But as I zoom and and use the mouse-over display of data from Plotly, this solution is good enough for me.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [April 11, 2021, 10:46am UTC](https://discourse.julialang.org/t/logarithmic-scaling-with-plotly/59026/3 "2021-04-11T10:46:34Z")

</div>

The `xlims` argument seems to do the job here:

```julia
using Plots; plotly()

xs = 0:0.001:10
ys = exp.(xs)
plot(xs, ys, xlims=(1e-3, 1e1), scale=:log10)

```

 ![plotly_log10_log10_xlims](https://global.discourse-cdn.com/julialang/original/3X/b/b/bb602aa6d2f991bd720c6dfba0e93756906b5dd8.png)

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [April 11, 2021, 10:58am UTC](https://discourse.julialang.org/t/logarithmic-scaling-with-plotly/59026/4 "2021-04-11T10:58:13Z")

</div>

Interesting… Any idea why the smallest and largest x-vals are not automatically taken as xlims? Or, I mean - they are in terms of the actual limits, but not when it comes to this behaviour.

Maybie a PR could explicitly supply xlims from `(minimum(xs), maximum(xs)` for xscale/scale/axis/xaxis = log/log10

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [April 11, 2021, 11:06am UTC](https://discourse.julialang.org/t/logarithmic-scaling-with-plotly/59026/5 "2021-04-11T11:06:58Z")

</div>

In your example, xmin = 0, so we need to avoid log(0). Otherwise, for xmin\>0, it should behave as you expect.
