# Makie: Axis through (0,0)

**URL:** https://discourse.julialang.org/t/makie-axis-through-0-0/103968
**Category:** Visualization
**Tags:** question, makie
**Created:** [September 18, 2023, 6:51am UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968 "2023-09-18T06:51:06Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![mpirke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpirke/32/44837_2.png) [@mpirke](https://discourse.julialang.org/u/mpirke)
#### Post date: [September 18, 2023, 6:51am UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/1 "2023-09-18T06:51:06Z")

</div>

Hi there!

I wondered whether the following is possible in Makie.

```python
import math
import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
    a = []
    for item in x:
        a.append(1/(1+math.exp(-item)))
    return a

    
x = np.arange(-10., 10., 0.2)
sig = sigmoid(x)

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

# Move left y-axis and bottom x-axis to centre, passing through (0,0)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')

# Eliminate upper and right axes
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')

# Show ticks in the left and lower axes only
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')

plt.plot(x,sig)
plt.show()

```

 ![example_plot](https://global.discourse-cdn.com/julialang/original/3X/f/5/f545f77a045909c0d1a0fd41c07c72daabe59438.jpeg)

I have looked through the documentation but not found something to change the position of the spines such that they are centered through (0,0).

Thanks for any help!

---

<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 18, 2023, 10:41am UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/2 "2023-09-18T10:41:46Z")

</div>

Not inbuilt, although one could probably hack it in several ways. You could look at `ax.xaxis`, I think it has an `endpoints` observable. You could try setting that to the vertical middle of the axis area you have in ax.scene.px\_area

---

<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: [September 18, 2023, 10:44am UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/3 "2023-09-18T10:44:05Z")

</div>

When I was using Plots.jl, I would always make my axis go through (0, 0). Nowaday, I am using Makie and not really missing that feature. But for some plots it is really nice to have the option. Are there plans to add built-in support for this?

---

<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 18, 2023, 3:11pm UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/4 "2023-09-18T15:11:11Z")

</div>

Not really plans, but it would in principle not be that difficult to add I think. It might just get a bit more messy with the observables if there are more possible states than top and bottom for xaxisposition etc.

In a quick try I already saw that the grid lines break when there’s an additional `:center` state, so stuff like that would need to be cleaned up.

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

---

<div class="post-metadata">

### Author: ![mpirke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpirke/32/44837_2.png) [@mpirke](https://discourse.julialang.org/u/mpirke)
#### Post date: [September 18, 2023, 3:20pm UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/5 "2023-09-18T15:20:04Z")

</div>

Thanks for the idea @jules, I gave it a try here’s what came out. I managed to make the axis go through the middle, however the grid is know messed up.

```julia
using GLMakie

fig = Figure()
xticks = -5:1:5
yticks = -5:1:5
ax = Axis(fig[1, 1], aspect=AxisAspect(1), xticks=xticks, yticks=yticks)
limits!(ax, -5.5, 5.5, -5.5, 5.5)
hidespines!(ax, :t, :r)
xend = ax.xaxis.attributes.endpoints
yend = ax.yaxis.attributes.endpoints

x1, x2 = xend[]
y1, y2= yend[]

Δy = (y2[2] - y1[2])/2
Δx = (x2[1] - x1[1])/2

xend[] = ([x1[1], x1[2] + Δy], [x2[1], x2[2] + Δy])
yend[] = ([y1[1] + Δx, y1[2]], [y2[1] + Δx, y2[2]])

xs = -5:0.1:5
lines!(ax, xs, 5*sin.(xs))

```

 ![foo](https://global.discourse-cdn.com/julialang/original/3X/6/8/6886a247b567058eab2fe7bb245fd2e14da891a1.jpeg)

---

<div class="post-metadata">

### Author: ![mpirke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpirke/32/44837_2.png) [@mpirke](https://discourse.julialang.org/u/mpirke)
#### Post date: [September 18, 2023, 3:20pm UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/6 "2023-09-18T15:20:52Z")

</div>

Ah sorry, did not see your last post. But yes I had the same problem 😃

---

<div class="post-metadata">

### Author: ![Iagoba\_Apellaniz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iagoba_apellaniz/32/34406_2.png) [@Iagoba\_Apellaniz](https://discourse.julialang.org/u/Iagoba_Apellaniz)
#### Post date: [November 7, 2024, 4:11pm UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/7 "2024-11-07T16:11:01Z")

</div>

Based on your solution, I obtained this

```julia
function cartesianaxis!(; origin=false)

    origin ? α = 1 : α = 0 
    # first include the (0,0) point into the plot
    scatter!([0],[0], marker = :circle, color = (:black, α))
    
    ax = current_axis()
    hidespines!(ax)
    ax.xticksvisible[] = false
    ax.yticksvisible[] = false

    autolimits!(ax) # TODO: Related with lifts

    # xlimitmargin = ax.xautolimitmargin[] 
    # ylimitmargin = ax.yautolimitmargin[]
    
    # # ax.xautolimitmargin[] = (0,0)
    # # ax.yautolimitmargin[] = (0,0)
    
    # data space
    xdatamin, xdatamax = ax.xaxis.attributes.limits[] 
    ydatamin, ydatamax = ax.yaxis.attributes.limits[]

    # pixel space Points
    xP1, xP2 = ax.xaxis.attributes.endpoints[]
    yP1, yP2 = ax.yaxis.attributes.endpoints[]

    # TODO: Work on lifts
    xtrs = - (xP2[1] - xP1[1]) / (xdatamax - xdatamin) * xdatamin
    ytrs = - (yP2[2] - yP1[2]) / (ydatamax - ydatamin) * ydatamin

    xP1 += [0, ytrs]
    xP2 += [0, ytrs]
    yP1 += [xtrs, 0]
    yP2 += [xtrs, 0]

    linesegments!(ax.blockscene, [xP1, xP2], color=:black, linewidth = 1.25)
    linesegments!(ax.blockscene, [yP1, yP2], color=:black, linewidth = 1.25)
    scatter!(ax.blockscene, [xP2], color =:black, marker=:rtriangle)
    scatter!(ax.blockscene, [yP2], color =:black, marker=:utriangle)

    f = current_figure()
end

```

This is the result for `fig, ax, plt = lines(rand(10)); lines!(-1 .* rand(10)); cartesianaxis!()`

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/0/10b471def83740593b8eac81838e93f863fa9120.png)

---

<div class="post-metadata">

### Author: ![Andy2K11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andy2k11/32/9967_2.png) [@Andy2K11](https://discourse.julialang.org/u/Andy2K11)
#### Post date: [December 19, 2024, 11:01pm UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/8 "2024-12-19T23:01:21Z")

</div>

You can hide the grid on your axis, then use a second axis just for the grid. It’s a bit messy but works ok if you can fix or don’t need zooming.

I also did a small tweak with the origin tick by excluding it from the ticks themselves and adding a text “0”.

 ![center-spines](https://global.discourse-cdn.com/julialang/original/3X/b/a/ba5eb2fe9fce667c6e98faab361a7868debb86c0.png)

This code could do with a tidy, but I’ll leave it here for now just as a reference for anyone else landing on this thread.

```julia
fig3 = Figure()
xlim = 7
ylim = 5
xticks = vcat([x for x in -xlim:-1], [x for x in 1:xlim])
yticks = vcat([x for x in -ylim:-1], [x for x in 1:ylim])

# Create second axis for gridlines only
ax4 = Axis(
    fig3[1, 1],
    xticks=xticks,
    yticks=yticks,
    xticklabelsvisible=false,
    xticksvisible=false,
    yticklabelsvisible=false,
    yticksvisible=false,
)
hidespines!(ax4)

# Now create axis to be transformed
ax3 = Axis(
    fig3[1, 1],
    xticks=xticks,
    yticks=yticks,
    xgridvisible=false,
    ygridvisible=false,
)
hidespines!(ax3, :t, :r)

margin = 0.5
limits!(ax3, -xlim-margin, xlim+margin, -ylim-margin, ylim+margin)
limits!(ax4, -xlim-margin, xlim+margin, -ylim-margin, ylim+margin)

# Adjust aspect ratio based on limits
ax3.aspect=xlim/ylim
ax4.aspect=xlim/ylim

# Translate spines
x1, x2 = ax3.xaxis.attributes.endpoints[]
xl, xo = x1
xr = x2[1]
y1, y2 = ax3.yaxis.attributes.endpoints[]
yo, yb = y1
yt = y2[2]
new_xo = yb + (yt - yb)/2.0
new_yo = xl + (xr - xl)/2.0

ax3.xaxis.attributes.endpoints[] = ([xl, new_xo], [xr, new_xo])
ax3.yaxis.attributes.endpoints[] = ([new_yo, yb], [new_yo, yt])

# Label origin
text!(ax3, -0.4, -0.5, text="0", color=:white)

# Test lines
xs = LinRange(-xlim, xlim, 150)
lines!(ax3, xs, x->0.25x^2 - 4)
lines!(ax3, [0, 0], [-5, 5], linestyle=:dash)
lines!(ax3, [-7, 7], [0, 0], linestyle=:dash)
lines!(ax3, [-7, 7], [-4, -4], linestyle=:dash)

save("center-spines.png", fig3)

```

---

<div class="post-metadata">

### Author: ![JosephPollacco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josephpollacco/32/51404_2.png) [@JosephPollacco](https://discourse.julialang.org/u/JosephPollacco)
#### Post date: [February 20, 2026, 12:03pm UTC](https://discourse.julialang.org/t/makie-axis-through-0-0/103968/9 "2026-02-20T12:03:23Z")

</div>

Did you try` yautolimitmargin = (0, 0)`,` xautolimitmargin=(0,0)`

```julia
   Ax_1 = Axis(Fig[1, 1]; ... yautolimitmargin = (0, 0), xautolimitmargin = (0, 0))

```
