Using uniform coloring in MatrixPlot
Seems that the automatic setting of MaxPlotPoints
is too low. You can set it to something high (or even Infinity
) to get around this.
m = 200;
list = Table[Table[RandomInteger[], {j, 1, 10}], {i, 1, m}];
Tally[Flatten[list]]
MatrixPlot[list, FrameTicks -> None, ImageSize -> {300, 300},
ColorRules -> {0 -> White, 1 -> Red}, MaxPlotPoints -> ∞]
Update: How is the default setting for MaxPlotPoints
determined?
The function Graphics`ArrayPlotDump`Private`checkMaxpoint
is called to get the value of MaxPlotPoints
. It takes three arguments. The first argument is the data
array. The third argument is True
if the calling function is MatrixPlot
, False
if it is ArrayPlot.
The default value of MaxPlotPoints
is obtained using Automatic
as the second argument.
To illustrate on an example from the original answer below:
SeedRandom[1]
data = RandomInteger[1, {20, 300}];
For this data
{m, n} = Dimensions[data]
{20, 300}
and the default value of MaxPlotPoints
for MatrixPlot
is
maxpoint = Graphics`ArrayPlotDump`Private`checkMaxpoint[data, Automatic, True]
{200, 200}
For ArrayPlot
it is always {∞, ∞}
regardless of data
(ArrayPlot
plots everything):
Graphics`ArrayPlotDump`Private`checkMaxpoint[data, Automatic, False]
{∞, ∞}
The function Graphics`ArrayPlotDump`Private`checkMaxpoint
turns the number x
returned by the function Graphics`ArrayPlotDump`Private`MatrixPlotMaxPlotPoints
into {x, x}
.
Graphics`ArrayPlotDump`Private`MatrixPlotMaxPlotPoints[data]
200
The core of this function is just
Min[1000, Max[100, 10 Min[Dimensions[data]]]]
200
So, for MatrixPlot
, {1000, 1000}
is the maximum possible value for maxpoint
regardless of data dimensions.
How is maxpoint
used to downsample data
?
The function call Graphics`ArrayPlotDump`Private`getCompressedMatrix[data, maxpoint, averaging]
uses maxpoint
to get the block sizes in vertical and horizontal directions:
{iblksize = Ceiling[m/Min[m, maxpoint[[1]]]],
jblksize = Ceiling[n/Min[n, maxpoint[[2]]]]}
{1, 2}
and calls the function Graphics`ArrayPlotDump`Private`downsampleArray
with two arguments, data
and {iblksize, jblksize}
which, in turn, partitions data into iblksize *jblksize
blocks and replaces each block with its total value and returns an array with dimensions Dimensions[data]/{iblksize, jblksize} = {20,150}
. If averaging
is True
the calling function Graphics`ArrayPlotDump`Private`getCompressedMatrix
process the matrix to replace each array entry by the mean of associated block.
downsampleddata = Graphics`ArrayPlotDump`Private`downsampleArray[data, {1, 2}];
Dimensions[downsampleddata]
{20, 150}
The array downsampleddata
is, effectively, the one plotted by MatrixPlot
:
ImageData[MatrixPlot[downsampleddata, Frame -> False]] ===
ImageData[MatrixPlot[data, Frame -> False]]
True
Original answer
Documentation >> MatrixPlot:
- With the default setting
MaxPlotPoints -> Automatic
, sufficiently large or sparse matrices are downsampled so that their structure is visible in the plot generated byMatrixPlot
.
And Documentation >> MatrixPlot >> Options >> MaxPlotPoints:
- By default, automatic methods are used to downsample large and/or sparse matrices
Setting the option value for MaxPlotPoints
to Infinity
or to Dimensions[data]
prevents downsampling.
Example:
SeedRandom[1]
data = RandomInteger[1, {20, 300}];
For a small subset of data
we see only two colors:
Column[{MatrixPlot[data[[All, ;; 200]], Frame -> False, ImageSize -> 600],
MatrixPlot[data[[All, ;; 200]], Frame -> False, ColorFunction -> Hue, ImageSize -> 600]}]
For full data
we see the effect of downsampling:
Column[{MatrixPlot[data, Frame -> False, ImageSize -> 600],
MatrixPlot[data, Frame -> False, ColorFunction -> Hue, ImageSize -> 600]}]
Setting the option value for MaxPlotPoints
to Infinity
or to Dimensions[data]
prevents downsampling:
Column[{MatrixPlot[data, Frame -> False,
MaxPlotPoints -> Dimensions[data], ImageSize -> 600],
MatrixPlot[data, Frame -> False, ColorFunction -> Hue,
MaxPlotPoints -> Dimensions[data], ImageSize -> 600]}]
As belisarius commented you can use ArrayPlot
, which does not compress the range of the data.
list = RandomInteger[1, {10, 300}];
ArrayPlot[list, ColorRules -> {0 -> White, 1 -> Red},
PlotRangePadding -> 0, ImageSize -> 600]
Perhaps better in this case you can also build the image raster directly:
Image[ list /. {0 -> {1, 1, 1}, 1 -> {1, 0, 0}} ]