# Makie - xscale - no method matching defaultlimits

**URL:** <https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696>\
**Category:** General Usage\
**Tags:** makie\
**Created:** [March 28, 2023, 7:05am UTC](https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696 "2023-03-28T07:05:22Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [March 28, 2023, 7:05am UTC](https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696/1 "2023-03-28T07:05:22Z")

</div>

```julia
julia> scatter(1:1.0:10, rand(10); axis=(; xscale=x->2.0*x))
ERROR: MethodError: no method matching defaultlimits(::var"#118#119")

Closest candidates are:
  defaultlimits(::Tuple{Real, Real}, ::Any)
   @ Makie ~/.julia/packages/Makie/gAmAB/src/makielayout/blocks/axis.jl:1333
  defaultlimits(::NTuple{4, Real}, ::Any, ::Any)
   @ Makie ~/.julia/packages/Makie/gAmAB/src/makielayout/blocks/axis.jl:1320
  defaultlimits(::Tuple{Real, Nothing}, ::Any)
   @ Makie ~/.julia/packages/Makie/gAmAB/src/makielayout/blocks/axis.jl:1334

```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [March 28, 2023, 11:24am UTC](https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696/2 "2023-03-28T11:24:52Z")

</div>

You need to overload a couple methods for custom scales, that’s one of them

---

<div class="post-metadata">

**Author:** ![mhinsch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mhinsch/32/26676_2.png) [@mhinsch](https://discourse.julialang.org/u/mhinsch)\
**Post date:** [June 22, 2023, 4:32pm UTC](https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696/3 "2023-06-22T16:32:16Z")

</div>

I hope it’s ok if I hijack this thread, since I am trying (and failing) to do basically the same thing. I want to implement a general linear transform for axes. What I did was this:

```julia
struct LinearScale
    a::Float64
    b::Float64
end

(s::LinearScale)(x) = s.a * x + s.b

Makie.inverse_transform(s::LinearScale) = x->(x-s.b)/s.a
Makie.defined_interval(::LinearScale) = OpenInterval(-Inf, Inf)
Makie.defaultlimits(::LinearScale) = (0.0, 10.0)

```

Unfortunately it doesn’t work. Both of these:

```julia
scatter(rand(10); axis=(;xscale=LinearScale(5, 5)))
scatter(collect(1:10), rand(10); axis=(;xscale=LinearScale(5, 5)))

```

produce a standard axis with x values 1 to 10. The same works perfectly fine with a log scale, though.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 22, 2023, 5:54pm UTC](https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696/4 "2023-06-22T17:54:06Z")

</div>

It does work, it just works differently than you expect 😉 I actually did exactly the same thing a couple years ago while playing around with the scales.

If you think about what the result is of setting `xscale = log10`, if you plot data from 1 to 100 you still get the ticks from 1 to 100, not from 0 to 2 (which would be `log10(1)` and `log10(100)`). What happens is that the data is transformed, but the ticks are adjusted in accordance with that so that you know what the original values were.

So when you do this with your linear transformation, the data are linearly transformed, and the ticks adjusted such that you know what the original data was. However, that means the effect of the transform is canceled out.

---

<div class="post-metadata">

**Author:** ![mhinsch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mhinsch/32/26676_2.png) [@mhinsch](https://discourse.julialang.org/u/mhinsch)\
**Post date:** [June 22, 2023, 6:11pm UTC](https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696/5 "2023-06-22T18:11:44Z")

</div>

Ok, thanks that does make sense.

Is there a different way to “translate” x values to a different scale? As an example, assume I have simulation steps starting at 1, but they represent months of years since 1957. Is there a way to let the axis show `(x/12)+1957` instead of x? I’m aware that I could simply provide a vector of correct x values, but for a live graph displayed by a running simulation that would mean that I have to update x _and_ y values with every time step. It’s not a huge issue, admittedly, but I thought maybe there’s a simpler way to do it.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 22, 2023, 7:30pm UTC](https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696/6 "2023-06-22T19:30:38Z")

</div>

Yes you can, you can make a new ticks type for that. Here is an example implementation, where I overload `get_ticks` which returns both tick values and tick labels. We just transform the limits with our linear transformation, then pass them on to the actual tick finder (WilkinsonTicks, Makie’s default).  
We have to transform the found ticks back to our real limits at the end, otherwise they would not fit.

I haven’t touched the tick finding algorithm or the formatting here, so of course this could be improved given that the numbers are supposed to be years or months.

```julia
using CairoMakie

struct LinearTransformationTicks{T}
    ticks::T
    offset::Float64
    slope::Float64
end

function Makie.get_ticks(lt::LinearTransformationTicks, scale, formatter, vmin, vmax)
    lims_transformed = (vmin, vmax) .* lt.slope .+ lt.offset
    tickvals_transformed, ticklabels = Makie.get_ticks(lt.ticks, scale, formatter, lims_transformed...)
    tickvals_untransformed = (tickvals_transformed .- lt.offset) ./ lt.slope
    return tickvals_untransformed, ticklabels
end

lines(
    1:24,
    cumsum(randn(24)),
    axis=(; xticks=LinearTransformationTicks(WilkinsonTicks(5), 1958.0, 1 / 12))
)

```

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

---

<div class="post-metadata">

**Author:** ![mhinsch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mhinsch/32/26676_2.png) [@mhinsch](https://discourse.julialang.org/u/mhinsch)\
**Post date:** [June 23, 2023, 9:10am UTC](https://discourse.julialang.org/t/makie-xscale-no-method-matching-defaultlimits/96696/7 "2023-06-23T09:10:39Z")

</div>

Cool, thanks! I’ll give that a try.
