6
$\begingroup$

I have two distance matrices. Both are comparing two entities in the same way. I create each matrix using

generateDistanceMatrix[centroids_] :=
  Module[{matrix},
   matrix = 
    DistanceMatrix[centroids, DistanceFunction -> EuclideanDistance];
   Times[matrix, 0.01]];

and then I visualize them using

visualizeDistanceMatrix[matrix_] :=
  Module[{range},
   range = Range[0, Length[matrix], 20];
   ArrayPlot[matrix,
    Frame -> True,
    ColorFunction -> isoHcf,
    ImageSize -> Full,
    FrameTicksStyle -> Directive[FontSize -> 12],
    FrameTicks -> {{range, None}, {None, range}},
    FrameLabel -> {{None, Style["Residue Sequence", 12]},
      {Style["Residue Sequence", 12], None}},
    PlotLegends ->
     {Placed[BarLegend[{isoHcf[#] &, {0, Max[matrix]}},
        LabelStyle -> Directive[Black, FontSize -> 12],
        LegendLabel -> "Distance (Angstroms)",
        LegendMarkerSize -> 400,
        LegendLayout -> "Column"], {{1, 1}, {0, 1}}]}]];

I would like to use Grid or something similar to show both distance matrices in the same figure, with a common legend. How can I change this function to force each distance matrix to use a common legend instead of their own?

$\endgroup$
3
  • 1
    $\begingroup$ Just a side note: Why don't you use just generateDistanceMatrix[centroids_] := 0.01 DistanceMatrix[centroids, DistanceFunction -> EuclideanDistance]? $\endgroup$ Mar 22 '20 at 8:21
  • $\begingroup$ That would simplify it, thank you @HenrikSchumacher $\endgroup$
    – brienna
    Mar 22 '20 at 15:30
  • 1
    $\begingroup$ You're welcome. (Btw. DistanceFunction -> EuclideanDistance is the default, so it can also be omitted.) $\endgroup$ Mar 22 '20 at 15:32
5
$\begingroup$
ClearAll[visualizeDM, barLegend]
isoHcf = ColorData["TemperatureMap"];
visualizeDM[minmax_, is_: 80] := ArrayPlot[#, 
   ColorFunction -> Function[x, isoHcf[Rescale[x, minmax, MinMax@#]]], 
   Epilog -> MapIndexed[Text[#, #2 - .5] &, Reverse /@ Transpose[#], {2}], 
   FrameTicksStyle -> Directive[FontSize -> 12], 
   FrameTicks -> Automatic, 
   FrameLabel -> {{None, Style["Residue Sequence", 12]},
     {Style["Residue Sequence", 12], None}}, 
   ImageSize -> 1 -> is] &

barLegend[minmax_] := BarLegend[{isoHcf[Rescale[#, minmax]] &, minmax}, Automatic,  
  LabelStyle -> Directive[Black, FontSize -> 12], 
  LegendLabel -> "Distance (Angstroms)", LegendMarkerSize -> 400, 
  LegendLayout -> "Column"]

Example:

SeedRandom[1]
centroidlists = RandomReal[100, {2, 5}];
dms = Round[generateDistanceMatrix /@ centroidlists, .01];
dms[[1, 1, 2]] = dms[[1, 2, 1]] = dms[[2, 1, 2]] = dms[[2, 2, 1]] = .55;

minmax = MinMax[dms];

Legended[Row[visualizeDM[minmax] /@ dms, Spacer[5]], Placed[barLegend[minmax], Right]]

enter image description here

Note: I added text labels to check that the a given value is mapped to the same color in both plots. Remove the part Epilog -> ... to get rid of the labels.

$\endgroup$
2
  • $\begingroup$ This works great! I wonder though about the legend. My color function yielded a continuous color scale, whereas this rescaled legend gives discrete colors. Is there a way to rescale continuously? (Let me know if any additional code would be helpful ) $\endgroup$
    – brienna
    Mar 22 '20 at 5:57
  • 1
    $\begingroup$ @briennakh, remove Automatic from BarLegend to get a continuous gradient. $\endgroup$
    – kglr
    Mar 22 '20 at 6:33

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.