# Adjusting scales for size automatically in GLMakie

**URL:** <https://discourse.julialang.org/t/adjusting-scales-for-size-automatically-in-glmakie/94997>\
**Category:** Visualization\
**Created:** [February 22, 2023, 4:16am UTC](https://discourse.julialang.org/t/adjusting-scales-for-size-automatically-in-glmakie/94997 "2023-02-22T04:16:48Z")\
**Posts on this page:** 2\
**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:** [February 22, 2023, 4:16am UTC](https://discourse.julialang.org/t/adjusting-scales-for-size-automatically-in-glmakie/94997/1 "2023-02-22T04:16:48Z")

</div>

I have my own custom theme for figures used in publication, and usually I set all the default sizes (e.g. fontsize, linewidth, etc) assuming the figure has a specific figure width since that is usually the fixed by the journals. In `CairoMakie` I usually have something like this

```julia
using CairoMakie; CairoMakie.activate!()

fig_size = (6.5, 4.0) # figure size in inch

set_theme!()
update_theme!(
        fontsize = 9,
        figure_padding = (10f0,10f0,20f0,30f0)

        Lines = (
            linewidth = 1.5,
        )
    )

x1 = range(0, 1, 101)
y1 = sin.(2*pi*x1)

size_pt = 72 .* fig_size

fig = Figure(resolution=size_pt)

ax1 = Axis(fig[1,1], xlabel="x label", ylabel="y label")
lines!(ax1, x, y)
scatter!(ax1, x2, y2, markersize=10*scale)

Label(fig.layout[1,:,Top()], "this is the title", fontsize=12, tellwidth=false,
    tellheight=false, padding=scale.*(0f0,0f0,20f0,0f0))

save("fig_cairo.pdf", fig, pt_per_unit=1) # save figure as vector graphics
save("fig_cairo.png", fig, px_per_unit=4) # save figure as bitmap with size 1872 x 1152 px

```

If I want to save the figure as a bitmap instead (e.g. as .png or .jpg), then I can set `px_per_unit`, and the figure looks like same in terms of the relative size of different parts regradless of the value of `px_per_unit`.

Now suppose I want to use `GLMakie` for certain 3D plots or to make animations, and I need to provide the figure size in pixels from the beginning, and all the sizes in my custom theme no longer works for different figure size. For example, suppose I want to export the figure with pixel size `1872 x 1152`, if I keep the fontsize as 9, then it will appear too small in the generated figure. Instead, I need something like this

```julia
using GLMakie; GLMakie.activate!()

resolution_w_px = 1872 # desire width in pixel
scale = resolution_w_px/(72*fig_size[1]) # scale = 4 for this example

update_theme!(
        fontsize = 9*scale,
        figure_padding = (10f0,10f0,20f0,30f0) .* scale

        Lines = (
            linewidth = 1.5*scale,
        )
    )

```

Basically I find that I need to multiply every defined quantity related to fontsize, linewidth or padding space by `scale`. But in addition to the finite number of self-defined values in my custom theme, there are also many other settings which I keep at the default values (e.g. `xgridwidth`, `xminorgridwidth`, `xticklabelpad`, etc). Is there a way to automatically apply this `scale` to all the default values of various settings?

---

<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:** [February 22, 2023, 6:17am UTC](https://discourse.julialang.org/t/adjusting-scales-for-size-automatically-in-glmakie/94997/2 "2023-02-22T06:17:42Z")

</div>

> [@yhchang96](#):
>
> Is there a way to automatically apply this `scale` to all the default values of various settings?

No, what you need is a `px_per_unit` setting for GLMakie, luckily this should happen relatively soon via this PR. Could you try it out and report if it works for your purpose? We’re still testing it

> <https://github.com/MakieOrg/Makie.jl/pull/2544>
>
> \# Description
> 
> On my HiDPI monitors \[\*\], GLMakie's windows appear with a small… default size and very small font size compared to other UI elements. Overriding themes to enlarge font sizes, default window size, default line thicknesses, etc is possible, but that makes sharing plotting scripts across machines difficult.
> 
> The approach I've taken here is to distinguish between a logical pixel and physical pixel, based on the fact that GLFW can report the device scaling factor in use. Therefore, the default window size, font sizes, marker/line sizes, etc can all be left alone (i.e. 800x600 window with 16pt fonts), and all lengths are dynamically rescaled by the device scaling factor during rendering.
> 
> With what I've hacked together, I can view images in GLMakie that have similar scale to those I'd get from saving an image to disk and loading in Firefox (which does similar HiDPI scaling from nominal "1x" CSS pixels to actual screen pixels):
> 
> \`\`\`julia
> julia\> using CairoMakie; CairoMakie.activate!()
> 
> julia\> x = range(-2π, 2π, 5\_000); lines(x, sin.(2.1x))
> FigureAxisPlot()
> 
> julia\> save("/tmp/test.svg", current\_figure())
> CairoMakie.Screen{SVG}
> 
> 
> julia\> using GLMakie; GLMakie.activate!()
> 
> julia\> x = range(-2π, 2π, 5\_000); lines(x, sin.(2.1x))
> \`\`\`
> !\[image\](https://user-images.githubusercontent.com/2965436/210272454-a04ba7ca-f086-40c4-a7eb-ba056d26f227.png)
> 
> \*\*Important caveats\*\*
> \- I removed the retina-specific code paths, since they seemed to do something very similar but in a way that doesn't work for my Linux desktop where window and framebuffer sizes are always equal. I don't have a way to test on Mac, so it was easier for me to rip out and just ignore it, but someone else will need to test on OSX.
> \- I don't actually know GLSL, so the rendering modifications were a big exercise in pattern matching and guess-and-check. My stupidly-simple sample cases seem to now work, but I won't be surprised if there are still missing modifications for recipes I haven't tried.
> - I also don't really understand the SSAO, FXAA, etc, so I've probably not updated those rendering steps correctly either.
> \- I've only tested the "on content scale change" on Windows, where it seemed to work moving a window from the laptop builtin display at 125% to an external display at 200% and back. (I haven't been able to test on Linux since (AFAIU) that requires GLFW using the Wayland backend, but it seems like GLFW\_jll is going through XWayland instead.)
> 
> I've also discovered that #2529 now exists, which must have been created just after I'd starting working on this independently. I've borrowed the \`px\_per\_unit\` nomenclature and including that in the theme from that PR, but otherwise I think this has taken a different approach. That might be a clue as to differences between Linux and OSX...
> 
> \[\*\] Machine details:
> \- Arch Linux
> \- Gnome v43 DE on Wayland
> \- Dual 4K monitors (native resolution ~185dpi) with 200% scaling configured in Gnome's display settings
> 
> \## Type of change
> 
> Delete options that do not apply:
> 
> \- \[x\] New feature (non-breaking change which adds functionality)
> 
> \## Checklist
> 
> \- \[x\] Added an entry in NEWS.md (for new features and breaking changes)
> \- \[x\] Added or changed relevant sections in the documentation
> \- \[x\] Added unit tests for new algorithms, conversion methods, etc.
> \- \[\] Added reference image tests for new plotting functions, recipes, visual options, etc.
