7

I would like to draw a rectangle (or more) which printed on paper shows the rectangle in units of cm. So

Graphics[{Rectangle[{0, 0}, {19, 28}], Orange, Rectangle[{0, 0}, {1, 1}]}]

will print out as two rectangles which can be measured as exactly 1cm x 1cm (orange one) and the black one as 19x28 cm.

It seems that some variables are important: The ImageSize and of course the AspectRatio.

I used AspectRatio->19/28 and for the ImageSize various settings like ImageSize->{19*27,28*27} but it keeps being not very accurate.

I export the graphics to TIFF and then print out with windows photo gallery to a full page photo. Does anyone have experience with this? There must be a formula instead of trial and error.

UPDATE: I tried the suggestion of @Szabolcs and I used the following code:

   g = Graphics[{White, EdgeForm[Directive[Thick, Black]], 
   Rectangle[{0, 0}, {18, 28}], Orange, Rectangle[{0, 0}, {10, 10}]}]

   final = Show[g, AspectRatio -> Automatic, 
   PlotRange -> {{-0.5, 18.5}, {-0.5, 28.5}}]

   cm = 72/2.54

   Export["final.pdf", Show[final, ImageSize -> {19 cm, 29 cm}]]

This works great. The orange rectangle of 10x10cm is when measured exactly 10x10cm

the cm 72/2.54 value was not what I expected since I though Windows uses 96dpi and Mac 72dpi (reading from the www). However 72 is the value that works. I've also beenn playing with the frames but then it gets ugly. Haven't found a way to get the right results dispite playing with all possible settings. What should work is create the frames/ticks etc myself inside the selected boundaries but that's not the path I would like to pursue..

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
Lou
  • 322
  • 4
  • 12
  • I think the conversion to TIFF and printing as a bitmap is not so good. Try exporting it to PDF, that preserves the dimensions much better. – Norbert P. Jun 01 '11 at 15:39
  • Printing to scale, as done with the 72 points per inch scaling as stated in the answers below (and in MMA's docs) actually never worked for me. I find that I need an extra scaling factor that I determine in a few iterative passes (printing, measuring with ruler, adjusting scale, printing etc.). If I recall correctly the printing environment also reduces size to 80% of the working environment. – Sjoerd C. de Vries Jun 01 '11 at 16:47
  • @Sjoerd, have you tried my method, with raster export? – Mr.Wizard Jun 01 '11 at 22:22
  • @Mr.wizard I have negative feelings about doing raster dumps on a vector based laser printer; that's not the way it should be done. But I've tried several formats in the past and they all needed adjustments. – Sjoerd C. de Vries Jun 01 '11 at 22:43
  • @Sjoerd, I appreciate the desire to keep things in the vector format, but I ask because from what I can tell the size is correct with that method, and I would like confirmation. – Mr.Wizard Jun 02 '11 at 00:26
  • How to print and export to PDF with `Magnification->1` and original on-screen appearance: see my answer ["General PDF/EMF export problems and solutons"](http://stackoverflow.com/questions/4198961/what-is-in-your-mathematica-tool-bag/6124065#6124065) and also this question: ["Font sizes print smaller than indicated"](http://stackoverflow.com/questions/6091553/font-sizes-print-smaller-than-indicated). – Alexey Popkov Jun 02 '11 at 03:59

2 Answers2

9
g = Graphics[{Rectangle[{0, 0}, {19, 28}], Orange, Rectangle[{0, 0}, {1, 1}]}]

Okay, first thing you need to do is set the x and y directions to use the same units, which means

Show[g, AspectRatio -> Automatic]

But this is already the default.

Second thing you need to do is choose a size and range for your plot area. Let's make it 21 by 30 with your rectangles centred:

plotArea = {{0, 21}, {0, 30}} - {1, 1}
Show[g, AspectRatio -> Automatic, PlotRange -> plotArea]

Third thing you need to do is turning off adding any padding/margins that make the actual size of your figure larger than your plot range:

final = Show[g, AspectRatio -> Automatic, PlotRange -> plotArea, PlotRangePadding -> 0, ImagePadding -> 0]

I believe ImageMargins does not make a difference, but if it does, set that to 0 as well.

The final thing you need to do is export this to a printable format that preserves the image dimensions, and set the size of the image so that 1 cm will be 1 unit on your plot. Mathematica accepts image sizes in printer's points, so let's define:

cm = 72/2.54
Export["final.pdf", Show[final, ImageSize -> 21 cm]]

We want the plot to be 21 cm wide because it's 21 units wide. Use PDF as export format, not TIFF. The ImageSize needs to be used inside Show to work around some problems with Export ...

Now open your PDF in Adobe Reader, open the print dialogue, and make sure that Page Scaling is set to None! I don't know how to do this in other readers ... Also make sure your figure fits the paper (21 by 30 cm is too large for A4 ...)

I'm not going to do a test print, so let me know if this works for you :-) The size of the PDF generated this way is exactly 21 by 30 cm, so if something goes wrong, it must happen at the printing stage.

Szabolcs
  • 24,728
  • 9
  • 85
  • 174
  • 1
    Believe it or not I did not copy your message in my update, I was working on it while you posted. – Mr.Wizard Jun 01 '11 at 16:01
  • Now the final question is, how to do it while still showing a visible Frame on the plot!! It's probably a lot of messing with paddings ... BTW I think both ImagePadding and PlotRangePadding only become relevant if a Frame/Axes are present. – Szabolcs Jun 01 '11 at 16:06
  • It seems PlotRangePadding leaves a white border on the sample graphic, and is therefore required. I shall think about the Frame issue. – Mr.Wizard Jun 01 '11 at 16:14
  • @Szabolcs I'll experiment some more at work (don't want to print to much at home ;)) I'll keep you posted with my findings! – Lou Jun 01 '11 at 16:15
  • It would be nice if there was a way to directly specify the unit scale of the Graphics objects. I wonder if LevelScheme provides for that. – Mr.Wizard Jun 01 '11 at 16:19
  • @Lou you can check the size of the PDF (e.g. with Adobe Reader move the mouse to the bottom left corner). Then all is reduced to printing the PDF at actual size. – Szabolcs Jun 01 '11 at 16:22
  • 1
    @Mr.Wizard: LevelScheme uses PrintersPoints (`pt`). Nearly all serious typesetting stuff is done in `pt`. – abcd Jun 02 '11 at 00:07
  • @Mr.Wizard: PostScript points. So what you and Szabolcs have is correct. I was merely pointing out that LS doesn't have the flexibility of directly entering units in `cm` or `in` – abcd Jun 02 '11 at 01:02
  • @Szabolcs You should realize that by default *Mathematica* exports graphics in PDF with `Magnification->.8`. See this question on how to solve it: ["How to export graphics in “Working” style environment rather than “Printout”?"](http://stackoverflow.com/questions/6093559). – Alexey Popkov Jun 02 '11 at 04:02
4

I believe you need to add PlotRangePadding -> None and set image dimensions appropriately.

In this case, the "bounding box" size is the same as your larger rectangle: {19, 28}

The robust way to do this is to set ImageSize to the actual required dimensions, and make use of ImageResolution, which will embed this value into the TIFF file for proper printing:

cm = 72 / 2.54;

g = Graphics[{Rectangle[{0, 0}, {19, 28}], Orange, 
      Rectangle[{0, 0}, {1, 1}]}, PlotRangePadding -> None, 
      ImageSize -> {19, 28}*cm];

Export["print.tif", g, ImageResolution -> 300]

This assumes that you want to print from a raster format (TIFF) but you can also export to other formats such as PDF with the same method.

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125