Makie: save PNG with a particular num of pixels in x?

I’d like to get a “reasonably” high-resolution PNG image. My image is wider than it is tall (which seems to be the default with CairoMakie) and so I’d like to say that “There should be 1200 pixels in the horizontal direction”. How do you do that?

I’ve searching the net but all I’ve found has been resolution = (1200, ????) but to do that you need to know the current aspect ratio and calculate the number of pixels in the vertical. It would be nice if there were an option like xpixels = 1200, which would calculate ypixels automatically.

Alternatively, it would be nice if there were an option to specify “the resolution”, like pixels per centimeter. It seems to me that Makie’s images have physical dimensions because the documentations say that the basic units are “points”. And, if so, a pixels-per-centimeter specification would automatically determine the number of pixels in each direction. (Note that PNG can include a piece of metadata that specifies pixels-per-centimeter information. So, specifying it would make sense.)

I’ll link the preview page of the docs of the next Makie version for you because there I’ve rewritten the explanation how “units” work in Makie. For CairoMakie this hasn’t changed in the next version.

The short answer is that you can use px_per_unit to scale your output resolution up and down. If you want 1200 px width and your figure has 600 units width, set 2.

While png does in principle have a metadata field in which you can specify the intended real world width, this is not really used anywhere as far as I can tell. If you embed such an image in a latex document or word file or embed it in a website it will not be respected. So we assume the default convention of the web where 1px == 0.75pt unless overridden by the user.


At least, LaTeX respects the DPI metadata in PNG images. I’ve modified the DPI metadata of a PNG image using GIMP and embedded two versions of it in a LaTeX document, like so:


Although I didn’t measure the physical sizes of the images in the generated PDF file, they looked right.

If you don’t do so now, I recommend adding the correct DPI metadata to the PNG images Makie generates.

Thank you!!! That of course works:

# . . .
save("img.png", fig; px_per_unit=2.0)

If you export the same figure in 200 or 400 dpi but with the same measurements in inches, are they the same size in latex even though one has double the side lengths in pixels?

That wasn’t the test I carried out. The two are “identical” images; both are 800 x 600 pixels. The only difference is (or should be) the metadata. I opened the original image and set the DPI to 300 and saved the result without modifying the original. I opened the original image again and set the DPI to 600 and saved the result. The pixels were not touched. The pixels should remain identical to those in the original image.

Because the first one is 300 DPI with 800 x 600 pixels, its physical dimension should be 2.666 x 2 inches. That’s how LaTeX renders the image on the page of the PDF file. (A PDF file has a physical dimension, regardless of how it’s rendered on your computer screen, and when you print it out from a physical printer, the sizes will become physical sizes.)

The second one is 600 DPI with 800 x 600 pixels and its physical dimension should be 1.333 x 1 inch and that’s how LaTeX renders it on the page.

(Again, I haven’t exactly measured the images on the PDF file nor have I printed them out. I have just compared the two images in the LaTeX-generated PDF file and their sizes looked right compared to the size of the page, which was A4 paper.)

So, if you set the metadata correctly, somebody will be benefited.

By the way, I tried to paste the two images into this text box. The first one was pasted as a hyperlink, but the second one’s hyperlink became identical to the first one! That means, this textbox found the second image identical to the first one, ignoring the metadata! Yet, LaTeX differentiates them.

Interesting, I wasn’t aware LaTeX did that. Might have overextrapolated from other software. But most notably web browsers, I’m pretty sure those ignore the metadata. But maybe I’m wrong about that as well :smile:

Maybe we could look into setting that metadata on our png exports then, converted via the currently assumed device independent pixel / pt conversion ratio that the web uses

Thank you for your response!

I agree with your conjecture.

The big difference between PDF and webbrowser is that the coordinate system that PDF is based on uses physical dimensions. The papersize is 210 x 297 cm. Draw a black solid line from (345 pt, 29 pt) to (1234 pt, 522 pt). Etc. etc. In contrast, webbrowsers don’t care about physical dimensions. It’s the OS’s job to map pixels to the physical screen.

So, to use PNG images for PDF, it’s convenient if the images have physical dimensions. I actually have a concrete example. I generated two images from different programs. Those two images shared the same y axis and I wanted to place them side by side in my LaTeX document. Initially it was easy: I just scaled the two PDF images by the same percentage and then the physical lengths of the two y axes were naturally the same. But then, I realized that one of the PDF images was too large with so many objects. So, I needed to generate that image as a PNG file whereas I wanted to keep the other image in PDF because it was a line graph and the lines are smooth in vector graphics. But the software I used at the time didn’t add the correct DPI information to the PNG’s metadata. As a result, when I included the new PNG image into my LaTeX document, I needed to scale the new image by trial and error so that the two y axes match in their physical lengths.