How to precisely control Plot size in mm?

How do I precisely control the size of the plot in mm?

using Plots
gr()
p = scatter(rand(100),randn(100), size = (1000,1000), dpi = 300, title = "rand", titlefontsize = 9)
savefig(p, "p.png")

Here I’m expecting the final size to be 8.47 cm, but it turns out to be ~46.8 cm on my computer. Is my estimation (1000/300*2.54 cm) wrong?

Moreover, what happens when I save it as pdf, which doesn’t care about the dpi? savefig(p, "p.pdf") produced a file the size of which is 41.6 cm.

What about fontsize? The font in the pdf file looks like 15 pt rather than 9 pt.

Also, different backend gives completely different final size. That’s very confusing…

I think the size is measured internally in points. If you want some specific mm size, you need to convert mm to pt and then specify this number.

The default unit is pixel, which means that the physical dimensions of the figure displayed on the screen depend on your screen and your resolution.
Whereas the default unit for fontsizes is indeed pt.
IIRC the GR backend does some upscaling using the dpi parameter to mimick an increase in resolution, which explains the bigger fontsize e.g. 9pt * sqrt(3) ≈ 15pt.

Where is this sqrt(3) coming from? And shouldn’t the saved file be independent of screen resolution? More specifically, where do I get the information of how the conversion works exactly? I can’t find it online.

This is strange. I have created a figure using Plots.jl with GR backend and saved it to a pdf.
Then, when I checked the properties of the pdf and converted the size to pt, it was equal to the figure size that I specified in plots. So, it looks like figures sizes are also measured in points.