# Makie: align y axes at the origin (y=0) for different y ranges

**URL:** https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282
**Category:** Visualization
**Tags:** question, makie
**Created:** [October 22, 2023, 3:34pm UTC](https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282 "2023-10-22T15:34:45Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [October 22, 2023, 3:34pm UTC](https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282/1 "2023-10-22T15:34:45Z")

</div>

I’m trying to create a single line graph plotting totally different multiple quantities with more than two y axes. I’m almost successful. See the plot below. One thing that I don’t know how to achieve is to align the y axes at y = 0. That is quite necessary to me.

I know I can specify the `limits` for each variable in such a way that y=0 comes at the same place, but that would be too tedious a program to write. . . .

 ![tmp](https://global.discourse-cdn.com/julialang/original/3X/3/9/39744f181e58be19e68fdc9b698334611fa02f59.png)

```julia
using CairoMakie

xax = 0:(pi/16):pi
co = cos.(xax)
si = sin.(xax) .* 100
ta = tan.(xax) .* 0.001

lims = ((0,3), nothing)
col1 = Makie.wong_colors()[1]
col2 = :gray
col3 = Makie.wong_colors()[2]

fig = Figure()
ax1 = Axis(fig[1,2], limits=lims)
ax2 = Axis(fig[1,2], limits=lims, ylabel="var 2")
ax3 = Axis(fig[1,2], limits=lims)

lines!(ax1, xax, co, color=col1)
lines!(ax2, xax, si, color=col2)
lines!(ax3, xax, ta, color=col3)

linkxaxes!(ax1,ax2,ax3)
hidespines!(ax1, :r, :l, :b, :t)
hidespines!(ax3, :r, :l, :b, :t)
hidedecorations!(ax1)
hidedecorations!(ax3)

ax1_2 = Axis(fig[1,1], ylabel="var 1",
    yticklabelcolor = col1,
    leftspinecolor = col1,
    ytickcolor = col1,
    ylabelcolor = col1,
)
ax3_2 = Axis(fig[1,3], ylabel="var 3",
    yticklabelcolor = col3,
    leftspinecolor = col3,
    ytickcolor = col3,
    ylabelcolor = col3,
)

linkyaxes!(ax1, ax1_2)
hidexdecorations!(ax1_2)
hideydecorations!(ax1_2, label=false, ticklabels=false, ticks=false)
hidespines!(ax1_2, :r, :b, :t)

linkyaxes!(ax3, ax3_2)
hidexdecorations!(ax3_2)
hideydecorations!(ax3_2, label=false, ticklabels=false, ticks=false)
hidespines!(ax3_2, :r, :b, :t)

colsize!(fig.layout, 1, 15)
colsize!(fig.layout, 3, 15)
save("tmp.png", fig)

```

---

<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: [October 22, 2023, 5:46pm UTC](https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282/2 "2023-10-22T17:46:44Z")

</div>

> [@ryofurue](#):
>
> I know I can specify the `limits` for each variable in such a way that y=0 comes at the same place, but that would be too tedious a program to write. . . .

I think there’s no way around that? 🙂

---

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [October 22, 2023, 7:01pm UTC](https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282/3 "2023-10-22T19:01:55Z")

</div>

> [@jules](#):
>
> I think there’s no way around that? 🙂

You added a question mark and yours is exactly my question, right? 😜

---

<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: [October 22, 2023, 7:10pm UTC](https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282/4 "2023-10-22T19:10:41Z")

</div>

Yeah I mean there’s no exact solution for this, I think. You’d have to pick one configuration in which all zeros are in the same place but still all the data is in view. You can get the current limits with `ax.finallimits[]`

---

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [October 23, 2023, 1:47am UTC](https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282/5 "2023-10-23T01:47:21Z")

</div>

> [@jules](#):
>
> You can get the current limits with `ax.finallimits[]`

Thanks! I wanted to hear something like that.

Okay, I have to set the limits manually, but I’d like to utilize the “machinery” that Makie already has, as much as possible.

I’ve found another thread in this forum (see the link at the bottom) and am exploring the idea:

```julia
using CairoMakie
xs = 0:(pi/16):pi
co = cos.(xs)
fig = Figure()
ax = Axis(fig[1,1])
lines!(ax, xs, co)
rect = ax.finallimits[]
yorg = rect.origin[2]
ywid = rect.widths[2]
ytop = # use yorg and ywid 
ybot = # use yorg and ywid
ylims!(ax, ybot, ytop)

```

But, what are these values? `rect.widths[2]` turns out to be 10 . . .

* * *

> [@Makie - how to set only lower or upper axis limit?](https://discourse.julialang.org/t/makie-how-to-set-only-lower-or-upper-axis-limit/58320/2):
>
> I would have to add that scenario specifically, I guess I could go with ((nothing, lim), nothing) for setting the upper x limit, for example. What is the scenario in which you want to do this, so I understand it better. Are you adding plots but don’t want zero to shift? Also, ax.finallimits is what contains the actual current limits

---

<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: [October 23, 2023, 9:10am UTC](https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282/6 "2023-10-23T09:10:09Z")

</div>

Ah that’s just because the limit calculation is only called before first display as an optimization. Before, we had it reset at every plot, but that kind of just resulted in lots of unnecessary updates. You can call `reset_limits!(ax)` to force it.

---

<div class="post-metadata">

### Author: ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)
#### Post date: [October 23, 2023, 5:18pm UTC](https://discourse.julialang.org/t/makie-align-y-axes-at-the-origin-y-0-for-different-y-ranges/105282/7 "2023-10-23T17:18:30Z")

</div>

So, following @jules 's advice, I’ve created a function to shift the origin of the y axis to a fixed place:

```julia
"""
Shift the origin of the y axis to vy0, which is a relative
position within the y axis such that 0 <= vy0 <= 1.
Positive y values will be fully included but negative values
may fall below the lower limit of the axis.
"""
function adjust_ylims!(ax, vy0)
  @assert 0 <= vy0 <= 1
  vdy2 = 1 - vy0 # above vy0
  vdy1 = vy0 # below vy0
  reset_limits!(ax)
  rect = ax.finallimits[]
  yorg = rect.origin[2]
  ywid = rect.widths[2]
  ytop = yorg + ywid
  @assert ytop > 0
  ybot = - ytop * (vdy1/vdy2)
  # ytop - ybot = ytop + ytop * (vdy1/vdy2)
  # = ytop * (1 + vdy1/vdy2) = ytop / vdy2
# @show ybot, ytop
  ylims!(ax, ybot, ytop)
end

```

This isn’t general enough but for my present purpose at hand, it works.
