I thought MatrixPlot can differentiate different expressions in color until I found this:

SparseArray[Band[{1, 1}] -> {E^-I, E^I, E^I, E^-I, E^-I, E^I}] // MatrixPlot

my MatrixPlot

MatrixPlot can't differentiate E^-I from E^I!!!!

But I use MatrixPlot to get a first impression of how many different expressions are there and how they are located in a newly generated matrix?

So here is the question:

How to force MatrixPlot to differentiate every distinct expression?

  • 2
    $\begingroup$ SparseArray[Band[{1, 1}] -> {E^-I, E^I, E^I, E^-I, E^-I, E^I}] // Im // MatrixPlot $\endgroup$ – eldo Nov 7 '15 at 11:06
  • 1
    $\begingroup$ "MatrixPlot can't differentiate E^-I from E^I!!!!". It can, but only if it gets input it can work with, i.e. real numbers. $\endgroup$ – Graumagier Nov 7 '15 at 11:06
  • $\begingroup$ @Graumagier well, so what I am asking is to find a way to let MatrixPlot differentiate every distinct expr without supplying it with numbers $\endgroup$ – matheorem Nov 7 '15 at 11:09
  • $\begingroup$ @matheorem – eldo's comment should help you with that. $\endgroup$ – Graumagier Nov 7 '15 at 11:10
  • $\begingroup$ @eldo This is to specific, what if there are other kind of expr that MatrixPlot can't differentiate, we don't know $\endgroup$ – matheorem Nov 7 '15 at 11:10

got an idea, use Hash function. Hash function will generate very different hash code for different expr

mat=SparseArray[Band[{1, 1}] -> {E^-I, E^I, E^I, E^-I, E^-I, E^I}]


enter image description here

I wrote a function colormat to color matrix with any expressions and to make it as colorful as possible

colormat[mat_] := Module[{},
  tmpmat = Map[Hash[#] &, Normal@mat, {2}] /. Hash[0] -> 0;
  tallyelement = Tally@Flatten@tmpmat;
  fcol = Hue;(*ColorData["CMYKColors"]*)
  customhuelist[n_] := 
   fcol[#[[1]], #[[2]], 1] & /@ 
    Transpose@{Subdivide[0, 0.9, n - 1], 
      Take[Flatten@Table[{0.35, 0.55, 1}, 30], n]};
  If[MemberQ[tallyelement, 0, -1], 
   customcolorrule = 
    Thread[Sort@tallyelement[[;; , 1]] -> 
      Prepend[customhuelist[Length[tallyelement] - 1], White]], 
   customcolorrule = 
    Thread[tallyelement[[;; , 1]] -> 
  MatrixPlot[#[[1]], ColorRules -> customcolorrule, 
     PlotLabel -> #[[2]]] & /@ {{tmpmat, "mat"}, {Re@mat, 
     "Re@mat"}, {Im@mat, "Im@mat"}}]

Now for matrix like following

colormat[{{a, b, d}, {e, f, g}, {h, i, j}}]

will give

enter image description here

I keep the last two plot as default MatrixPlot of Re and Im for possible reference.

If we directly use Hash or bill s ToCharacterCode will give

enter image description here

So you can see how colorful colormat can give :)


Another way to approach this is to turn each item in the list into a string, then transform the string to charactercodes, which are numbers that can be plotted by MatrixPlot.

mat = SparseArray[Band[{1, 1}] -> {E^-I, E^I, E^I, E^-I, E^-I, E^I}];
MatrixPlot[Map[Total, ToCharacterCode /@ Map[ToString, Normal[mat], {2}], {2}],
           ColorFunction -> Hue]

enter image description here

  • $\begingroup$ The interesting thing is why we got the same color? $\endgroup$ – matheorem Nov 8 '15 at 1:46
  • $\begingroup$ I think it's coincidence because the numbers in the matrices are very different. $\endgroup$ – bill s Nov 8 '15 at 4:00
  • $\begingroup$ Modified to match purpose of question...Im seems the most natural choice $\endgroup$ – ubpdqn Nov 8 '15 at 8:31


mat = SparseArray[Band[{1, 1}] -> {E^-I, E^I, E^I, E^-I, E^-I, E^I}];

Auxiliary. Nonzero values:

nzv[mat_] := Sort@DeleteDuplicates@SparseArray[mat]["NonzeroValues"];

Index function. Assign a positive integer index to each nonzero expression in the matrix mat.

idxFN[mat_] := With[{a = AssociationThread[# -> Range@Length@# &@nzv[mat]]},
   Lookup[a, #, 0] &];

MatrixPlot[Map[idxFN[mat], mat, {2}]]

Mathematica graphics

A ColorFunction that assigns a different color to each expression in mat. Adding the default color function made it look at little complicated, but it's basically the same idea as the indexing function.

        cf_:  (* default color function with default rescaling *)
            "DefaultColorFunction" /.
              (Method /. Charting`ResolvePlotTheme["Default", MatrixPlot]), 
            0.5 + 0.5 # &],
        default_: White] :=
  With[{a = AssociationThread[# -> cf /@ (N@Range@Length@#/Length[#]) &@ nzv[mat]],
        d = default /. Automatic -> cf[0]}},
   Lookup[a, #, d] &];

The usual use should use ColorFunctionScaling -> False:

MatrixPlot[mat, ColorFunction -> colorFN[mat], 
 ColorFunctionScaling -> False]

Mathematica graphics

Other styling options:

 ColorFunction -> colorFN[mat, ColorData@"Rainbow", Blue],
 ColorFunctionScaling -> False]

Mathematica graphics

 ColorFunction -> colorFN[mat, ColorData@"LakeColors", Automatic],
 ColorFunctionScaling -> False]

Mathematica graphics

  • $\begingroup$ Upvoted, what I want to do in colormat has the same effect as indexing different expr. But I done it stupidly. Very clever method! $\endgroup$ – matheorem Nov 8 '15 at 15:20
  • $\begingroup$ BTW, what does Composition[ "DefaultColorFunction" /. (Method /. ChartingResolvePlotTheme["Default", MatrixPlot]), 0.5 + 0.5 # &]` mean? ChartingResolvePlotTheme` ? $\endgroup$ – matheorem Nov 8 '15 at 15:24
  • 1
    $\begingroup$ @matheorem Thanks. ResolvePlotTheme is a way to look up some default settings for various plotting functions. Search for it on this site, and you'll find some other uses. The default behavior of MatrixPlot seems to scale the input to the default color function so that the matrix value 0 corresponds to the color function value 0.5. Therefore I composed with 0.5 + 0.5 # &. $\endgroup$ – Michael E2 Nov 8 '15 at 15:34

You can simply colorize by the complex phase

mat = SparseArray[Band[{1, 1}] -> {E^-I, E^I, E^I, E^-I, E^-I, E^I}];
MatrixPlot[mat, ColorFunction -> (Hue[Arg@#/2/π, Abs@#] &), 
 ColorFunctionScaling -> False]

enter image description here


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.