Is it possible to add space between rows and/or columns in ArrayPlot?

From this

 ArrayPlot[Table[x*y, {x, 4}, {y, 20}], Mesh -> True, ImageSize -> 1 -> 25]

enter image description here

i would like to get something like this

enter image description here

I tried the following code but obviously it is not work as desired

  (ArrayPlot[{#}, Mesh -> True, ImageSize -> 1 -> 25]) & /@ Table[x*y, {x, 4}, {y, 20}] // TableForm

enter image description here

  • $\begingroup$ "add space between rows and/or columns in ArrayPlot" - with ArrayPlot itself, no; you may need to fall back with using Raster[]. $\endgroup$ – J. M.'s ennui Feb 1 '17 at 21:30
  • $\begingroup$ related: How to partition MatrixPlot graphics? $\endgroup$ – kglr Dec 30 '17 at 12:31

ArrayPlot may not be the best tool for this kind of thing. Here is a way using GraphicsGrid that allows quite flexible control over the appearance.

tab = Table[x*y, {x, 4}, {y, 20}]; 
GraphicsGrid[Table[g = (Max[tab] - tab[[i, j]])/Max[tab];
    Graphics[{RGBColor[g, g, g], EdgeForm[Directive[Black]], Rectangle[]}],
        {i, 1, 4}, {j, 1, 20}], Spacings -> {20, 200}, ImageSize -> 600]

enter image description here

You can control the overall size with ImageSize. Control the vertical and horizontal spaces with the two Spacings parameters. Control the color with the RGBColor parameter. The EdgeForm directives control the appearance of the edges.

  • $\begingroup$ Nice! But how I can make spacing in row really equal to zero? Since if I put Spacings -> {0, 200} there are still gaps between cells $\endgroup$ – Филипп Цветков Feb 2 '17 at 21:13
  • 1
    $\begingroup$ Use negative numbers. Spacings -> {-20, 200} seems about right. $\endgroup$ – bill s Feb 2 '17 at 21:38
ArrayPlot[Table[x y, {x, 4}, {y, 20}], 
  Mesh -> True,
  ImageSize -> 1 -> 25,
  MeshStyle -> {{White, Thickness[0.02]}, {White, Thickness[0.02]}}]
  • $\begingroup$ almost, but I would like to keep the borders around the cells $\endgroup$ – Филипп Цветков Feb 1 '17 at 21:42
  • $\begingroup$ also it reduce the size of the cells ArrayPlot[Table[x y, {x, 4}, {y, 20}], Mesh -> True, ImageSize -> 1 -> 35, MeshStyle -> {{White, Thickness[0.02]}, {White, Thickness[0.00]}}] $\endgroup$ – Филипп Цветков Feb 1 '17 at 21:48
  • $\begingroup$ I can't seem to find that ImageSize specification. Where is it in the docs? $\endgroup$ – Edmund Dec 16 '17 at 0:02
table = Table[x*y, {x, 4}, {y, 20}];    

Using ArrayPlot with PlotRange -> {0, Max[table]}:

ArrayPlot >> Details and Options:

With the default setting for ColorFunction, PlotRange->{$a_{min}$, $a_{max}$} specifies that values from $a_{min}$ to $a_{max}$ should be shown with gray scales varying from white to black.

Column[ArrayPlot[{#}, Mesh -> All, ImageSize -> 1 -> 40, PlotRange -> {0, Max[table]}, 
 PlotRangePadding -> .1, ImagePadding -> .1] & /@ table, Spacings -> .5]

enter image description here

Using ListDensityPlot:

data = 1 - table/Max[table]; 

Column[ListDensityPlot[{#, #}, InterpolationOrder -> {0, 0}, 
  ColorFunctionScaling -> False, ColorFunction -> GrayLevel, 
  AspectRatio -> 1/20, Mesh -> All, 
  MeshStyle -> Directive[Antialiasing -> False, GrayLevel[-1 + GoldenRatio]], 
  Frame -> False, ImageSize -> 1 -> 40] & /@ data, Spacings -> 1]

enter image description here


The following approach relies on ArrayPlot to generate an appropriately colored and scaled Raster object. I then extract the data and specifications from this object (size, scale), and split the data up into rows, each one of which is used to generate a new Raster object with the specifications obtained above, but appropriately resized. The objects obtained, i.e. the "rows" of the original ArrayPlot are then re-combined using Column to introduce spacing. The process is wrapped in a custom function called spacedArray:

spacedArray[data_?MatrixQ] := Block[
  {values, rectangle, range},
  {values, rectangle, range} = First@Cases[
     ArrayPlot[data, Mesh -> True],
     Raster[values_, rectangle_, range_] :> {values, rectangle, range},
  rectangle[[2, 2]] = rectangle[[2, 2]]/First@Dimensions[values];
   Graphics[Raster[{#}, rectangle, range], ImageSize -> 1 -> 25] & /@ values

Here is the result on the original toy data:

spacedArray[Table[x*y, {x, 4}, {y, 20}]]

Mathematica graphics

... and on a different data set:

spacedArray[Table[x*y, {x, 5}, {y, 10}]]

Mathematica graphics

Notice that in the latter case the size of the cells is retained, although the overall size and aspect ratio of the plot changes substantially.

Vertical spacing can be controlled with appropriate options to Column. Obviously, this solution is still missing the mesh lines: those could be extracted from ArrayPlot as well as Line objects (two sets of lines, for the horizontal and vertical mesh respectively), but that seems tedious. Perhaps direct construction from Graphics primitives would be best at that point.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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