# How to define a custom Makie xscale function which needs an extra argument?

**URL:** <https://discourse.julialang.org/t/how-to-define-a-custom-makie-xscale-function-which-needs-an-extra-argument/119580>\
**Category:** General Usage\
**Tags:** visualization, makie\
**Created:** [September 19, 2024, 2:27am UTC](https://discourse.julialang.org/t/how-to-define-a-custom-makie-xscale-function-which-needs-an-extra-argument/119580 "2024-09-19T02:27:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![AUK1939](https://avatars.discourse-cdn.com/v4/letter/a/c57346/32.png) [@AUK1939](https://discourse.julialang.org/u/AUK1939)\
**Post date:** [September 19, 2024, 2:27am UTC](https://discourse.julialang.org/t/how-to-define-a-custom-makie-xscale-function-which-needs-an-extra-argument/119580/1 "2024-09-19T02:27:05Z")

</div>

Hi

To apply a custom scaling function in Makie as per the docs we need to overload some functions. The example below is taken from [here](https://github.com/MakieOrg/Makie.jl/issues/3089)

```julia
import Makie

function my_log(x)
    return log10(x)
end

function my_inverse_log(x)
    return 10.0^x
end

Makie.defaultlimits(::typeof(my_log)) = (1.0, 1000.0)
Makie.defined_interval(::typeof(my_log)) = Makie.OpenInterval(0.0, Inf)
Makie.inverse_transform(::typeof(my_log)) = my_inverse_log

using CairoMakie

x = collect(1.0:10.0)
y = rand(10)

fig, ax = lines(x,y)
ax.yscale = my_log

fig

```

My question is how can I create yscale or xscale functions that take an extra argument? For example suppose my scaling function requires an extra argument `b` which is fixed per plot. But I want to apply the same scaling with different `b` values to other plots and I don’t know `b` until runtime.

```julia
function my_log(x, b)
    return log(b,x)
end

function my_inverse_log(x, b)
    return b^x
end

```

To apply the scaling function we could simply write

```julia
b = 3.0
fig, ax = lines(x,y)

ax.yscale = x -> my_log(x, b)

```

but it’s not clear how to handle the inverse function since the extra argument `b` is defined in local scope but `Makie.inverse_transform` is defined in global space. It doesn’t have access to `b`

```julia
Makie.inverse_transform(::typeof(my_log)) = my_inverse_log

```

Is there a way around this? Can I pass the inverse function to the Axis constructor maybe?

---

<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:** [September 19, 2024, 4:28am UTC](https://discourse.julialang.org/t/how-to-define-a-custom-makie-xscale-function-which-needs-an-extra-argument/119580/2 "2024-09-19T04:28:54Z")

</div>

Someone refactored Symlog10 to use ReversibleScale with internal closures.  
I don’t remember what it looked like before but I thought I had used functor structs.  
[Makie.jl/src/layouting/transformation.jl at master · MakieOrg/Makie.jl · GitHub](https://github.com/MakieOrg/Makie.jl/blob/master/src/layouting/transformation.jl#L400)

---

<div class="post-metadata">

**Author:** ![AUK1939](https://avatars.discourse-cdn.com/v4/letter/a/c57346/32.png) [@AUK1939](https://discourse.julialang.org/u/AUK1939)\
**Post date:** [September 19, 2024, 12:11pm UTC](https://discourse.julialang.org/t/how-to-define-a-custom-makie-xscale-function-which-needs-an-extra-argument/119580/3 "2024-09-19T12:11:57Z")

</div>

Clever! Works great, thank you.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 19, 2024, 4:05pm UTC](https://discourse.julialang.org/t/how-to-define-a-custom-makie-xscale-function-which-needs-an-extra-argument/119580/4 "2024-09-19T16:05:03Z")

</div>

> [@AUK1939](#):
>
> ```julia
> ax.yscale = x -> my_log(x, b)
> 
> ```

> [@AUK1939](#):
>
> `Makie.inverse_transform(::typeof(my_log)) = my_inverse_log`

Do

```julia
ax.yscale = Base.Fix2(my_log, b)

```

and

```julia
Makie.inverse_transform(f::Base.Fix2(typeof(my_log))) = Base.Fix2(my_inverse_log, f.x)

```

instead.
