# Makie plots with equal height + unequal width + data aspect ratio

**URL:** <https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628>\
**Category:** Visualization\
**Tags:** question, makie, makielayout\
**Created:** [May 6, 2021, 8:10am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628 "2021-05-06T08:10:24Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [May 6, 2021, 8:10am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/1 "2021-05-06T08:10:24Z")

</div>

I’d like to have a few plots arranged in a row that have both a data aspect ratio and equal heights, and therefore unequal widths. I can’t seem to get it to work no matter what combination of `DataAspect`, `height`, `limits`, `autolimitaspect`, `tellhegith`, etc I use.  
Here’s the MWE:

```julia
n = 100
scene, layout = layoutscene(resolution = (1000, 300))
spans = range(0.2, 1, length = 5)
for (i, span) in enumerate(spans)
  x = rand(n) .* span
  # y = rand(n) .* span
  ax = layout[1, i] = Axis(scene, aspect = DataAspect(), height = 200, limits = (extrema(x)..., 0.0, 1.0))
  # lines!(ax, x, y)
end
# rowsize!(layout, 1, Fixed(200))
scene

```

(I intentionally commented out stuff that shouldn’t make a difference)  
Here’s the result (note the unequal heights):

 ![mwe](https://global.discourse-cdn.com/julialang/original/3X/0/4/04408fc943fec57cd7c12c70093d3a3254b15f21.png)  
I’m on `GLMakie v0.2.9`.

---

<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:** [May 6, 2021, 8:17am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/2 "2021-05-06T08:17:19Z")

</div>

Ok so the height should be the same but the width change given the data aspect? That means the plot size is completely deterministic and needs to fit the figure size exactly. So probably you should choose a height, plot your data and check the ax.finallimits of each axis, set each axis height and width in the correct ratio given the limits, then do the figure resize thing I posted on Slack the other day.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [May 6, 2021, 8:19am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/3 "2021-05-06T08:19:56Z")

</div>

I’ll try to set the width and height manually then.

> [@jules](#):
>
> the figure resize thing I posted on Slack the other day

slack hole, or can’t find it.

But I’ll try what you suggested now and report back here 🙂

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [May 6, 2021, 8:29am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/4 "2021-05-06T08:29:32Z")

</div>

OK, so this works well enough:

```julia
height = 200
ym = 0.0
yM = 1.0
n = 100
scene, layout = layoutscene(resolution = (1000, 300))
spans = range(0.2, 1, length = 5)
for (i, span) in enumerate(spans)
  x = rand(n) .* span
  xm, xM = extrema(x)
  y = rand(n) .* span
  ax = layout[1, i] = Axis(scene, width = height/(yM - ym)*(xM - xm), height = height, limits = (xm, xM, ym, yM))
  lines!(ax, x, y)
  poly!(ax, Circle(Point2f0((xM - xm)/2, (yM - ym)/2), 0.2), color = :red)
end
scene

```

The red disk is just to check the aspect ratio, indeed it’s correct:

 ![mwe](https://global.discourse-cdn.com/julialang/original/3X/0/3/038371511410e2747794839945134d764715fd7f.jpeg)

Let me know if this isn’t a Makie-approved way…

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [May 6, 2021, 9:22am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/5 "2021-05-06T09:22:53Z")

</div>

this should go into the Documentation. 😃

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [May 6, 2021, 9:25am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/6 "2021-05-06T09:25:01Z")

</div>

The lesson here is a bit weird:  
“When things don’t work out as expected with aspect ratio, heights, etc just manually set the axis size.”  
I’m not sure Jules would be ok with that…?

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [May 6, 2021, 10:18am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/7 "2021-05-06T10:18:24Z")

</div>

You could think about it this way. Given a global resolution, there needs to be a procedure to find optimal axis sizes that respect the constraints. This may not have an exact solution for the given resolution, so you might “flip” the problem: you pass the axis sizes and let MakieLayout figure out what overall resolution will come out.

The code Julius refers to is something like the following (taken from his slack snippet):

```julia
using GridLayoutBase: Col, Row, determinedirsize

function resizetocontent!(fig::Figure)
    figsize = size(fig.scene)
    sz = map((Col(), Row()), figsize) do dir, currentsize
        inferredsize = determinedirsize(fig.layout, dir)
        return ceil(Int, something(inferredsize, currentsize))
    end
    sz == figsize || resize!(fig.scene, sz)
    return fig
end

```

That is to say, if the resolution can be computed starting from the layout (and is different from the resolution initially chosen) resize the figure. Some utility like this could probably live in Makie.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [May 6, 2021, 10:25am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/8 "2021-05-06T10:25:48Z")

</div>

Thanks!

I appreciate the complexity of these procedure. It’s pretty tricky! I guess that down the line it would be good to have some more documentation about these more complicated layouts.

---

<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:** [May 6, 2021, 1:42pm UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/9 "2021-05-06T13:42:08Z")

</div>

The problem here is again that the layout cannot use the information that objects want to have a certain aspect ratio. If it could then we would have an optimization problem, while the layout follows a deterministic algorithm. If you give an axis `aspect = DataAspect()` that means that it will reduce its frame from the available space so that the visual aspect ratio is the same as that of the data. This will leave gaps if the available space doesn’t perfectly fit the required size already.

You can either go all the way inside out and fix the axis sizes completely, then resize the figure to fit as in @piever’s snippet.

Or you can say, well at least if the axes shrink down, they should do so in a way that they end up with the same height. (If you could fix the height and enforce aspect of each axis, you would immediately have to have a certain fixed width per axis, so that would again break the layout if the widths didn’t add up perfectly by chance.)

So you can reach this goal by making the layout size all columns with correct relative ratios, given the xlimits of your axes. You do that by setting their width to `Auto(span)`, which will distribute the available space according to the size of each `span`. Then all axes have to reach the same height if they resize themselves using `DataAspect()`.

```julia
scene, layout = layoutscene(resolution = (1000, 400))
spans = range(0.2, 1, length = 5)
for (i, span) in enumerate(spans)
    ax = layout[1, i] = Axis(scene, aspect = DataAspect(),
        limits = (0, span, 0.0, 1.0))
    poly!(ax, Circle(Point2f0(span / 2, 0.5), 0.1))
    colsize!(layout, i, Auto(span))
end
scene

```

 ![grafik](https://global.discourse-cdn.com/julialang/original/3X/3/6/36315938740a5d729e77995b81deedccc5e06a02.png)

---

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [March 7, 2023, 5:33pm UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/10 "2023-03-07T17:33:47Z")

</div>

I thank @jules for providing this elegant solution. Using this method, I was able to create a figure with 2×2 panels with matched widths and heights while using `Axis(...; aspect=DataAspect())`.

What was not clear to me was the meaning of `colsize!()`. It is obvious that it means the column size, but again, what does the column size mean? Initially I thought it meant the height of the column, but it turned out to mean the width of the column. It took a couple of experiments to figure this out. Similarly, `rowsize!()` is not the width of the row, but the height of the row.

I think the documentation can be improved by explicitly mentioning whether the size in `rowsize!()` and `colsize!()` means width or height.

---

<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 8, 2023, 7:42am UTC](https://discourse.julialang.org/t/makie-plots-with-equal-height-unequal-width-data-aspect-ratio/60628/11 "2023-03-08T07:42:52Z")

</div>

In the `GridLayout`, column sizes are widths and row sizes are heights. The height of a column is simply computed as the sum of the row widths plus gaps, you can’t set it directly.
