# Mesh Problems with MatrixPlot

Bug introduced in 10.1 or earlier and persisting through 11.3.0 or later

I've come across some weird behavior in 10.1 when trying to use Mesh with MatrixPlot. In the example below, when specifying Mesh, I only get one line along the X axis at 100 instead of lines at {100, 200, ..., 500}. I assume this is a bug, but does anyone know of a work around.

Thanks,

Mike

data = RandomReal[{0, 1}, {21, 500}];

MatrixPlot[data, AspectRatio -> Full,
FrameTicks -> Automatic,
ColorFunction -> (Hue[1 - #] &),
ColorFunctionScaling -> True,
MeshStyle -> Blue,
Mesh -> { Table[j, {j, 0, 25, 5}], Table[j, {j, 100, 500, 100}] }
]


The solution or rather "fix" to the problem seems to be to raise the MaxPlotPoints:

data = RandomReal[{0, 1}, {21, 500}];

MatrixPlot[
data,
AspectRatio -> Full,
FrameTicks -> Automatic,
ColorFunction -> (Hue[1 - #] &),
ColorFunctionScaling -> True,
MeshStyle -> Blue,
Mesh -> {Table[j, {j, 0, 25, 5}], Table[j, {j, 100, 500, 100}]},
MaxPlotPoints -> Infinity
]


This returns:

This started out as a long comment, but in the meantime I think I found the solution to this problem which is clearly a bug in MatrixPlot. My initial analysis follows and the conclusion and a solution are at the bottom.

First, this is not typical to 10.1. I see identical behavior in versions 8 and 9.

Second, your example can be simplified to reduce the phenomenon to its essentials:

data = ConstantArray[0, {20, 500}];
MatrixPlot[data, Mesh -> {{5, 10, 15}, {100, 200, 300}}]


The difference in data ranges plays a role. Increasing the vertical range of the matrix adds the missing grid lines:

data = ConstantArray[0, {200, 500}];
MatrixPlot[data, Mesh -> {{5, 10, 15}, {100, 200, 300}}]


Another problem when we let Mathematica choose the mesh locations:

data = ConstantArray[0, {20, 500}];
MatrixPlot[data, Mesh -> {4, 20}]


Again, with less of a difference in data ranges:

data = ConstantArray[0, {200, 500}];
MatrixPlot[data, Mesh -> {4, 20}]


Looks like a bug to me.

Note that ArrayPlot works correctly with the same options:

data = ConstantArray[0, {20, 500}];
ArrayPlot[data, Mesh -> {{5, 10, 15}, {100, 200, 300}}]


data = ConstantArray[0, {20, 500}];
ArrayPlot[data, Mesh -> {4, 20}]


## Drilling down further

Let's look at the underlying Graphics code of the resulting plot:

data = ConstantArray[0, {20, 300}];
mp = MatrixPlot[data, Mesh -> {Table[i, {i, 0, 20, 3}], Table[i, {i, 0, 300, 10}]}]


mp // InputForm


Ah! The array is changed into a SparseArray, but its horizontal dimension is incorrect. The vertical mesh lines, drawn with Line, seem to use coordinates that are derived from this incorrect SparseArray dimension.

Let's change the data array somewhat again:

data = ConstantArray[0, {50, 300}];
mp = MatrixPlot[data, Mesh -> {Table[i, {i, 0, 50, 3}], Table[i, {i, 0, 300, 10}]}]


mp // InputForm


The SparseArray is correct here, and the mesh lines are correct as well.

The same dimensional error is found when one replaces the ConstantArray with a random array. You don't get a SparseArray in the Graphics code, but a Raster instead. Again, with the incorrect dimensions:

## Cause and solution

I suspect the cause of this problem to be an incorrect handling of the downsampling of the input data.

The MatrixPlot documentation says:

With the default setting MaxPlotPoints->Automatic, sufficiently large or sparse matrices are downsampled so that their structure is visible in the plot generated by MatrixPlot.

So, prohibiting this downsampling could be a solution. Let's try this:

data = ConstantArray[0, {20, 500}];
MatrixPlot[data, Mesh -> {{5, 10, 15}, {100, 200, 300, 400, 500}},
MaxPlotPoints -> Infinity]


Seems to work. Graphics will be much more memory intensive though. I noted that this subsampling is doing pretty weird things. A 20 x 500 matrix will be subsampled, but a 50 x 500 won't.

• +1. That is of course a very concise explanation of what is going on behind the scenes. Great.
– gwr
Commented Jul 8, 2015 at 16:19