2

I'd like to export an output from MatrixPlot[], however, the output file size seems to depend on my specification of the ImageSize -> {..., ...}. How might I export a TIFF with all of the data in the $N \times M$ matrix being plotted? Presumably one could set the ImageSize to reflect the matrix dimensions, however, how would one appropriately pad for the axes and axes labels?

The command I'm using for MatrixPlot[] export is:

Export["MatrixExportFileExample.tiff",MatrixPlot[...]];
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
SqrtOfBlue
  • 55
  • 3

2 Answers2

6

I think what you are looking for is the PixelConstrained option of ArrayPlot, or understanding of its mechanism using Raster and Offset. With the default settings you will need Frame -> False to show all values (the frame overlaps the outer pixels).

data = CellularAutomaton[{1635, {3, 1}}, {{1}, 0}, 80];

ArrayPlot[data,
 ColorRules -> {0 -> Black, 1 -> Yellow, 2 -> Orange}, 
 PixelConstrained -> 2,
 Frame -> False
]

enter image description here

This makes every point on the plot a 2px by 2px square.
For full control this can be done manually with Raster and Offset:

data /. {0 -> {0, 0, 0}, 1 -> {1, 1, 0}, 2 -> {1, 0.5, 0}};
Graphics[Raster[Reverse @ %, {{0, 0}, Offset[{322, 162}, {0, 0}]}], 
 ImageSize -> {322, 162}, PlotRange -> {{0, 322}, {0, 162}}, Frame -> False, 
 FrameTicks -> None]

With either method you will find that adding frame ticks causes clipping as the ImageSize does not account for the label area. A solution is to specify the ImagePadding manually and include it in the ImageSize.

myPlot[data_, scale_Integer, pad_Integer:0, opts : OptionsPattern[]] :=
 With[{size = scale {#2, #} & @@ Dimensions@data},
  Graphics[Raster[Reverse @ data, {{0, 0}, Offset[size, {0, 0}]}], 
   ImageSize -> 2 + pad + size,
   PlotRange -> {{0, size[[1]]}, {0, size[[2]]}}, opts, 
   ImagePadding -> {{pad, 1}, {pad, 1}},
   PlotRangeClipping -> True, Frame -> True, 
   FrameTicks -> None
  ]
 ]

data /. {0 -> {0, 0, 0}, 1 -> {1, 1, 0}, 2 -> {1, 0.5, 0}};
myPlot[%, 2, 25, FrameTicks -> True]

enter image description here

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
5

The direct approach to the problem is to take the Raster expression directly from the generated Graphics object and then convert it to an Image object by applying Image to Raster (not to Graphics!).

As Documentation says, "Image[Raster[...]] converts a Raster object to an image."

The solution is as follows:

data = CellularAutomaton[{1635, {3, 1}}, {{1}, 0}, 80];
pl = ArrayPlot[data, ColorRules -> {0 -> Black, 1 -> Yellow, 2 -> Orange}];

Export["MatrixExportFileExample.tiff", Image@pl[[1]]];

The PixelConstrained option of ArrayPlot does not change the Image@pl[[1]]. You will get pixel-perfect image with guarantee. Note however that this approach imply that the Graphics object generated (pl) contains only one graphics primitive: Raster, as it is by default. If you wish to add other primitives (or wish to include ticks in the rasterized image), Mr.Wizard's solution is a way to go. Some additional explanations can be found here.

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
  • Thanks! This is exactly what I needed, and, I think, the simplest and the most direct answer to the OP's question. – Roman Kogan Oct 28 '16 at 09:06