9
$\begingroup$

Mathematica uses a screen resolution of 72 dpi. For post-processing figures I use Corel, which conveniently allows me to use metric units (mm) for positioning and resizing figures. Say, I want to export a figure exactly 80mm wide. I would use a snippet of code like this:

mm=72/25.4;
myplot=Plot[Sin[x],{x,0,10},BaseStyle->{6},ImageSize->{80mm,40mm},
ImagePadding->{{8mm,2mm},{6mm,2mm}},AspectRatio->32/70,Frame->True];
Export["myplot.pdf",myplot]

The problem is that 80mm is 226.772 points. So Mathematica exports a PDF with a rounded width of 227 points i.e. 80.081mm. Tweaking options such as "ScreenResolution" or passing options to Export such as ImageResolution does not seem to change anything, as Mathematica invariably behaves such, that one pixel at 100% magnification is 1/72 of an inch. This can become a problem when, for example, I have to arrange several such figures into a grid in Corel and lead to minor misalignments.

So is 1/72 of an inch the one and only resolution that Mathematica can use for these purposes or is there a way to work accurately in metric units?

Edit to follow up links given in comments:

How to set image DPI shows a neat example when exporting to a raster format. Some investigation shows that

Export["figure.tiff", Show[g, ImageSize -> 720.25],ImageResolution -> 72]

creates a tiff file 720 pixels wide (obviously, there must be an integer number of pixels). Increasing the image resolution four-fold helps:

Export["figure.tiff", Show[g, ImageSize -> 720.25],ImageResolution -> 288]

This results in a tiff file 2881 pixels wide (not 2880 or 2884). 2881/288*25.4=254.089mm. However (and sorry for not mentioning this explicitly before), I would like to export to a vector format, such as PDF. So I try the following code:

Export["figure.pdf", Show[g, ImageSize -> 720.25]]

As usual, Mathematica does the export to the precision of a printer point, equal to 1/72 of an inch, but this time gives a PDF not 720 "pixels" wide (254mm), like it was for the TIFF file, but rounds up. The PDF is 254.353mm, or 10+1/72 of an inch - 721 printer points. If I increase the resolution:

Export["figure.pdf", Show[g, ImageSize -> 720.25],ImageResolution -> 288]

the width of the exported file is still 254.353mm, not the desired/expected 254.089mm, as was with the TIFF image. This little inacurracy is not adressed in the linked questions, I'm afraid.

Further investigation: Specifically for my problem there is a workaround I have found:

g=Plot[Sin[x],{x,0,10},Background->None,ImageSize->720.25,Epilog->{Directive[Green,Opacity[.2]],Rectangle[ImageScaled[{0,0},ImageScaled[{1,1}]]]}]
Export["myplot.pdf",g,Background->None]

This kind of code still yields a PDF which is 721/72 inches wide (rather than the desired 720.25), however the semi-transparent green rectangle overlaying the graph will be exactly 720.25/72 inches wide. Upon importing such a PDF into Corel it will ignore the absent background and claim to observe an image with the desired width of 254.089mm. This works well for the purposes of aligning figures, as Corel now sees the correct size, but is still somewhat unsatisfactory, as now I have to manually delete the background of every figure I export if I actually want the figure to have a transparent background. Also this highlights the problem if the figure is opened in a PDF viewer - around the edges of the otherwise green image there will be small white margins visible. I would be grateful, if someone can confirm, that there is no better way, or better yet, suggest a way to override Mathematica's default assumption that the value passed to ImageSize is the width of the image in units of 1/72 of an inch (why can't I change this arbitrary number to 1/100 or 1/254 or 1mm).

$\endgroup$
10
  • $\begingroup$ Have you seen How to set image DPI?? $\endgroup$
    – user9660
    Mar 12, 2015 at 15:28
  • $\begingroup$ possible duplicate of Real Size Image Printing $\endgroup$
    – Yves Klett
    Mar 12, 2015 at 15:46
  • $\begingroup$ The example in your link seems to work nicely with raster graphics: Export["Z:\\Temp\\figure.tiff", Show[g, ImageSize -> 720.25], ImageResolution -> 72] generates a tiff file 720 pixels wide, but Export["Z:\\Temp\\figure.tiff", Show[g, ImageSize -> 720.25], ImageResolution -> 288] gives a tiff file not 2880, but 2881 pixels wide, as would be expected for that extra quarter in ImageSize. When recalculating the print size from pixels (2881) and resolution (288), I then correctly get 254.089mm or 10+1/288 of an inch. If I change the filename to figure.pdf, I get an image 254.359mm wide. $\endgroup$
    – LLlAMnYP
    Mar 12, 2015 at 15:55
  • $\begingroup$ I have added a more detailed explanation/follow-up in the OP. $\endgroup$
    – LLlAMnYP
    Mar 12, 2015 at 16:24
  • 2
    $\begingroup$ I suspect PDF out from mathematica is just a wrapper around EPS. EPS in turn fundamentally has its size defined by a whole-point BoundingBox. (you might try exporting eps, manually tweaking the boundingbox with decimal values and see if corel recognizes it ) $\endgroup$
    – george2079
    Mar 12, 2015 at 16:37

1 Answer 1

3
$\begingroup$

As there has not been any further input so far, I shall try to expand my latest edits into a complete answer. As mentioned before, Mathematica's apparent behavior is that ImageSize is given in units equal to 1/72 of an inch. The default resolution when outputting to a raster format is also 72dpi. So it should come as no surprise, that

g=Plot[Sin[x],{x,0,10},ImageSize->720.25]
Export["myplot.tiff",g]

exports a TIFF file 720 pixels wide. It is quite clear, however, that Mathematica itself has no problems working with a fractional ImageSize, because increasing the resolution 4 times

g=Plot[Sin[x],{x,0,10},ImageSize->720.25]
Export["myplot.tiff",g,ImageResolution->288]

gives a TIFF file which correctly accounts for the fractional part of the value of ImageSize. If you open this file and check its properties, you will find it to be 2881 pixels wide with a printing resolution of 288dpi. This behavior is desirable, although it is not the only outcome one could expect. I would not be surprised if Mathematica had exported a TIFF file still 720 pixels wide, but with a resolution set to 288dpi.

Problems are encountered, when I try exporting to PDF.

g=Plot[Sin[x],{x,0,10},ImageSize->720.25]
Export["myplot.pdf",g]

Some inspection shows, that the exported PDF is actually 721 units wide. Why 721 and not 720, like with the TIFF file? It seems, because Mathematica honestly tries to fit this 720.25 wide image into the PDF and, as george2079 suggests, needs to create a BoundingBox 721 units wide. This time, however, increasing the ImageResolution does not help.

g=Plot[Sin[x],{x,0,10},ImageSize->720.25]
Export["myplot.pdf",g,ImageResolution->288]

The bounding box width is still 721 points, specifically points of the 72dpi kind. I'm not sure, if there's some easy way to turn these points into the 288dpi kind, but if possible, that would be the perfect solution. But while the bounding box may be an integer number of points wide, the contents of the vector graphic are defined with higher precision (had that not been so, it would defeat the point of vector graphics in the first place). To illustrate this I can do the following:

g=Plot[Sin[x],{x,0,10},ImageSize->720.25,Prolog->{Directive[Green],Rectangle[ImageScaled[{0,0}],ImageScaled[{1,1}]]}]
Export["myplot.pdf",g]

Now the PDF is still 721/72 inches wide, but Mathematica (having no problem working with fractional image sizes) will place the left edge of the green rectangle at x=0 and the right edge at x=720.25 (x being given in absolute coordinates). If we zoom all the way into the edges of the PDF we will see tiny white margins next to the green rectangle less than half a printer point wide.

The next step illustrates a little hack one can do with Corel.

g=Plot[Sin[x],{x,0,10},ImageSize->720.25,Background->None]
Export["myplot.pdf",g,Background->None]

Now, when I import the PDF into Corel, it doesn't care about the actual dimensions of the page. It will enclose the imported graphics into quite a tight box, ignoring any whitespace (actually, transparent space, as we have specified Background->None everywhere), which will be quite a bit smaller than 720 printer points (10 inches). So if I do the same trick as with the green rectangle:

g=Plot[Sin[x],{x,0,10},ImageSize->720.25,Background->None,Prolog->{Directive[Green],Rectangle[ImageScaled[{0,0}],ImageScaled[{1,1}]]}]
Export["myplot.pdf",g,Background->None]

Corel will disregard the aforementioned margins and will see an image exactly as wide, as the rectangle is. From here there are two and a half ways one can go about to solve my problem. The first is:

  • Position the image in Corel as desired.
  • Ungroup the image.
  • Select the green rectangle and delete it.

The alternative:

  • Instead of Directive[Green] use Directive[White] or whatever the background color is.

If there is no need for transparency in the plot's background, this is perfect. But what if transparency is desired? A naive option would be to use Directive[White,Opacity[0]], but then Corel disregards the transparent background rectangle just like it disregards the transparent margins. Moreover, probably because the alpha channel has a size of 8 bits, Corel also does not respond to Directive[White,Opacity[0.001]]. However, something like Directive[White,Opacity[0.005]] does work.

To summarize:

  • For an arbitrary non-integer ImageSize instead of Export["myplot.pdf",g] use Export["myplot.pdf",Show[g,Background->None,Prolog->{Directive[White,Opacity[0.005]],Rectangle[ImageScaled[{0,0}], ImageScaled[{1,1}]]}],Background->None].
  • If transparency is not a key issue, omit the Opacity[0.005] directive.

Pros:

  • Corel sees an image of the desired size.
  • No need to further manipulate the image (manual deletion of background, etc.) within Corel.

Cons:

  • The dimensions of the PDF are still the wrong size.
  • The transparency is not perfect. In the (unlikely) case, that several (more than 5-10) figures will need to be stacked, the not fully transparent backgrounds will show themselves.

To-do/workarounds:

  • Best option: find a way to increase the resolution of the bounding box size.
  • If many transparent-background images need to be stacked, stack them as much as possible within Mathematica, then export at the last step.

And as a final remark. Thankfully, while the overall image dimensions in the exported file may be slightly off (to the precision of a printer point), the actual contents of the graphic are not distorted, and this is why the related questions and answers in How to set image DPI> and Real Size Image Printing succeded in getting graphics of exactly the correct size. The questions therein were mainly concerned with getting the contents correctly sized, not the bounding boxes.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.