I am trying to save a plot at a specific size (in physical length units, like inches) and have the correct font size. The idea is that then I could just insert it into my LaTeX document without scaling and have the same font and font size as the rest of my document. I can’t seem to get this right and am extremely confused by the behavior of size and dpi. Any help understanding what is going on is appreciated!

Example:

using Plots
x = 0:0.01:2π;
y = cos.(x);
p1 = plot(x,y;size=(600,600), dpi=600)
p2 = plot(x,y;size=(600,600), dpi=300)
savefig(p1, "test1.png")
savefig(p2, "test2.png")

I would expect the first image to be 1 inch by 1 inch, and the second to be 2 inches by 2 inches. But when I put them into my LaTeX document they are both larger than that, and even more confusing the second image is smaller than the first.

It seems like Makie can do this and is well documented: Figures | Makie. I will try this!

Matching figure and font sizes to documents

Academic journals usually demand that figures you submit adhere to specific physical dimensions. How can you render Makie figures at exactly the right sizes?

But if anyone knows how to do it in Plots let me know!

If you put \the\textwidth in somewhere in your latex source, you can see that your column is 345pt wide.

Then with Makie you can just match the width of the figure with your latex by setting size=(345,300) (only the width matters there), and you don’t have to worry about inches conversions etc

Use \includegraphics[width=\textwidth]{cosine.pdf}
edit: or set pt_per_unit = 1 in Makie so the pdf is the correct size

This matches fontsize perfectly with your latex document, confirmed by advanced inspection in paint:

Ah, my mistake was using pt_per_unit in the wrong place… it should be used when saving the PDF. So it was using the default value (0.75). I can also use one of the default themes instead of specifying the font myself. Here is the solution that works.

The trick is to realize that there is an internal dpi value in Plots.jl and the actual dpi value of the saved figure. The internal value is hardcoded as 100. The actual dpi value of the saved figure is set via plots(...; dpi=DPI). This can be reflected in your code snippet as

using Plots
x = 0:0.01:2π;
y = cos.(x);
DPI = 600
width_inches = 3.4
width_px = width_inches * 100 # internal dpi=100
p = plot(x,y;size=(width_px, width_px), dpi=DPI)
savefig(p, "test.png")