# 'tight\_layout' in Makie for plots with multiple subplots

**URL:** <https://discourse.julialang.org/t/tight-layout-in-makie-for-plots-with-multiple-subplots/86718>\
**Category:** General Usage\
**Tags:** plotting, makie, cairo\
**Created:** [September 3, 2022, 5:45am UTC](https://discourse.julialang.org/t/tight-layout-in-makie-for-plots-with-multiple-subplots/86718 "2022-09-03T05:45:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![yhchang96](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yhchang96/32/36499_2.png) [@yhchang96](https://discourse.julialang.org/u/yhchang96)\
**Post date:** [September 3, 2022, 5:45am UTC](https://discourse.julialang.org/t/tight-layout-in-makie-for-plots-with-multiple-subplots/86718/1 "2022-09-03T05:45:05Z")

</div>

I have the following code:

```julia
using CairoMakie

# create data
x = range(-1, 1, 129)
y = range(-1, 1, 129)

X = ones(length(y)) .* x'
Y = y .* ones(1,length(x))
R = sqrt.(X.^2 + Y.^2)

Z = ((R.^2 .- 1.5) .^ 2)
Z[R.>1] .= 0

clim = (0, maximum(Z)*4)

# create figure
fig_w = 2*(3+3/8) # in inch
fig_h = 2.5 # in inch
size_pt = 72 .* (fig_w, fig_h)

set_theme!(lightposition=Vec3f(0, 2, 1))

cmap1 = Reverse(:Spectral_4)

fig = Figure(resolution=size_pt)

axes1 = []
axes2 = []
hm2 = []

for (i,idx) in enumerate(t_idx)

    ax1 = Axis3(fig[1,i], elevation=pi/8, azimuth=-pi/6)
    push!(axes1, ax1)

    surface!(ax1, X, Y, i*Z, shininess=200f0, specular=Vec3f(0.8), colormap=cmap1,
        colorrange=clim, rasterize=10)
    
    limits!(ax1, -1, 1, -1, 1, clim...)

    hidedecorations!(ax1)
    hidespines!(ax1)

    ax2 = Axis(fig[2,i], aspect=AxisAspect(1))
    push!(axes2, ax2)

    hm = heatmap!(ax2, X, Y, i*Z, colormap=cmap1, colorrange=clim)
    push!(hm2, hm)

    hidedecorations!(ax2)
    hidespines!(ax2)
end

cb = Colorbar(fig[1:2,5], hm2[end])

save("test_fig.pdf", fig, pt_per_unit=1)

fig

```

And this is what I get:

 ![test_fig](https://global.discourse-cdn.com/julialang/original/3X/f/0/f0c4b4fda6e07dadcfe2add7888dfd45dce222fc.png)

A couple issues:

1. The numbers on the colorbar are missing i the produced pdf figure although they do appear in the figure preview in VSCode. I don’t know what’s wrong.

2. The bigger problem: how do I remove those empty space? I have played around using `colsize!`, `rowsize!`, `colgap!`, `rowgap!` but I don’t seem to figure out the proper way to do it. When I was using Matplotlob, `fig.tight_layout()` does a pretty good job, and if not I can just use `ax.set_position()` to set the axis position manually to eliminate the margin. I would like to know if similar methods exist in `Makie`, and if not what’s the `Makie` way to do it properly.

Thanks

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [September 3, 2022, 7:04am UTC](https://discourse.julialang.org/t/tight-layout-in-makie-for-plots-with-multiple-subplots/86718/2 "2022-09-03T07:04:13Z")

</div>

It looks like `hidedecorations!(...)` on an `Axis3` does not reclaim space like it does for a 2D `Axis`.

```julia
let
	fig = Figure(resolution=(700, 300))
	for i in 1:4
		ax1 = Axis3(fig[1, i])
		hidedecorations!(ax1) # same place taken if this is commented out
		ax2 = Axis(fig[2, i])
		hidedecorations!(ax2)
	end
	fig
end

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/e/a/ea274703b56ef5120c9bfeccc1bad7f749e61deb.png)  
without `hidedecorations`:  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/9/093f436115dbd5fa140f9c5fa4ac72d75da86fb8.png)

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [September 3, 2022, 7:22am UTC](https://discourse.julialang.org/t/tight-layout-in-makie-for-plots-with-multiple-subplots/86718/3 "2022-09-03T07:22:01Z")

</div>

Using the [`protrusions`](https://makie.juliaplots.org/v0.17.13/api/#Axis3) keyword seems to fix it.

> - `protrusions`: The protrusions on the sides of the axis, how much gap space is reserved for labels etc. Default: `30`

```julia
let
	fig = Figure(resolution=(700, 300))
	for i in 1:4
		ax1 = Axis3(fig[1, i]; protrusions=0)
		hidedecorations!(ax1)
		ax2 = Axis(fig[2, i])
		hidedecorations!(ax2)
	end
	fig
end

```

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

I would have expected `hidedecorations!` to do this automatically.

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [September 3, 2022, 7:28am UTC](https://discourse.julialang.org/t/tight-layout-in-makie-for-plots-with-multiple-subplots/86718/4 "2022-09-03T07:28:14Z")

</div>

In your case:

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

> **Code**
>
> ```julia
> # create data
> x = range(-1, 1, 129)
> y = range(-1, 1, 129)
> 
> X = ones(length(y)) .* x'
> Y = y .* ones(1,length(x))
> R = sqrt.(X.^2 + Y.^2)
> 
> Z = ((R.^2 .- 1.5) .^ 2)
> Z[R.>1] .= 0
> 
> clim = (0, maximum(Z)*4)
> 
> # create figure
> fig_w = 2*(3+3/8) # in inch
> fig_h = 2.5 # in inch
> size_pt = 72 .* (fig_w, fig_h)
> 
> set_theme!(lightposition=Vec3f(0, 2, 1))
> 
> cmap1 = Reverse(:Spectral_4)
> 
> fig = Figure(resolution=size_pt)
> 
> hm2 = []
> 
> for i in 1:4
> 
> ax1 = Axis3(fig[1,i]; elevation=pi/8, azimuth=-pi/6, protrusions=0)
> 
> surface!(ax1, X, Y, i*Z, shininess=200f0, specular=Vec3f(0.8), colormap=cmap1,
> colorrange=clim, rasterize=10)
>     
> limits!(ax1, -1, 1, -1, 1, clim...)
> 
> hidedecorations!(ax1)
> hidespines!(ax1)
> 
> ax2 = Axis(fig[2,i])
> 
> hm = heatmap!(ax2, X, Y, i*Z, colormap=cmap1, colorrange=clim)
> push!(hm2, hm)
> 
> hidedecorations!(ax2)
> hidespines!(ax2)
> 
> colsize!(fig.layout, i, Aspect(1, 1.0))
> end
> 
> cb = Colorbar(fig[1:2,5], hm2[end])
> 
> save("test_fig.pdf", fig, pt_per_unit=1)
> 
> fig
> 
> ```

and the PDF looks fine and sharp.

---

<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 3, 2022, 11:43am UTC](https://discourse.julialang.org/t/tight-layout-in-makie-for-plots-with-multiple-subplots/86718/5 "2022-09-03T11:43:51Z")

</div>

> [@ederag](#):
>
> I would have expected `hidedecorations!` to do this automatically.

We could think about doing that.  
The issue is that the `protrusions` value of `Axis3` is just a guess that works ok-ish by default, but not if you hide decorations, have really large ones, etc. The reason is that for `Axis`, how much the axis decorations protrude does only depend on the ticks, for `Axis3` it does also depend on the exact projection. But because the projection changes with the layout space given to `Axis3`, the protrusions cannot also depend on this, otherwise you’d have a cycle in the layout logic.

Another option would be adding a function like `auto_protrusions!(ax3)` that tries to compute how far out the labels are currently sticking, and using that value. If you hid all of them, this would zero out the protrusions.

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [September 6, 2022, 9:55am UTC](https://discourse.julialang.org/t/tight-layout-in-makie-for-plots-with-multiple-subplots/86718/6 "2022-09-06T09:55:25Z")

</div>

> otherwise you’d have a cycle in the layout logic

Thanks, I understand now, and fully support your approach,  
which made the new layout system so robust.  
Better having to enter some fixed values in a few known places  
than a solver that do frustrating things at the worst moment, on complex figures.

I filed [issue #2259](https://github.com/JuliaPlots/Makie.jl/issues/2259) to track potential improvements about 3D protrusions.
