5
$\begingroup$

The built-in function PairwiseScatterPlot has been discussed for example here: Scatterplots for subsets of multivariate data [Updated]. However, I find it not very informative to plot the identity function along the diagonal of the matrix of plots: do you guys know how to plot a more informative histogram instead? Also, it is superfluous to plot the entries above the diagonal.

Here is an example:

Needs["StatisticalPlots`"]
Needs["MultivariateStatistics`"]
data = RandomReal[MultinormalDistribution[{0, 0, 0}, {{1, 1/2, -2/3}, {1/2, 5, 2}, {-2/3, 2, 20}}], 10^3];
PairwiseScatterPlot[data, DataTicks -> Automatic, DataLabels -> {"var1", "var2", "var3"}]

enter image description here

UPDATE: I have improved the code a user wrote as a possible solution (unfortunately that user deleted that entry). Basically I have fixed a bug and the labels. Here is what it does:

pspF3 = With[{dt = #, ca = ConstantArray[Null, {#, #} &@Dimensions[#][[2]]],
opts = Sequence[AspectRatio -> 1, Frame -> True]}, 
GraphicsGrid[ReplacePart[ca, {{i_, i_} :> Histogram[dt[[All, i]], Automatic, "PDF", opts, 
     If[i == Dimensions[dt][[2]], FrameLabel -> {"var" <> ToString[i], None}, FrameLabel -> None],
PlotRange -> All, Ticks -> Automatic],
{i_, j_} /; i > j :> ListPlot[dt[[All, {j, i}]], opts,
Which[i == Dimensions[dt][[2]] && j > 1, FrameLabel -> {{None, None}, {"var" <> ToString[j], None}}, i == Dimensions[dt][[2]] && j == 1, FrameLabel -> {{"var" <> ToString[i], None}, {"var" <> ToString[j], None}}, i > 1 && j == 1, FrameLabel -> {{"var" <> ToString[i], None}, {None, None}}, i > j, FrameLabel -> {None, None}],
RotateLabel -> True,PlotRange -> All]}], ImageSize -> 600]] &;
pspF3@data

enter image description here

However, the ticks are not aligned and the labels of the ticks are repeated when not necessary (they should appear only at the very bottom and on the left). Also, the size of the various frames is not constant and ideally there should not be gaps. PairwiseScatterPlot does all this automatically. Can you improve on this solution?

$\endgroup$
1
  • $\begingroup$ One approach is to build your own grid of plots based on GraphicsGrid or Grid. Reproduce the six off-diagonal plots using ListPlot, and use Histogram or whatever else you like for the three diagonal plots. $\endgroup$
    – bbgodfrey
    Commented Dec 27, 2014 at 16:31

2 Answers 2

11
$\begingroup$

Update 3: Using the function pwScatterPlot from this answer

ClearAll[addHistograms, pwScatterPlot]       
addHistograms = Module[{diag = Diagonal[Partition[Cases[#, {dir_, ___Point} :> dir, All], 
    Round @ PlotRange[#][[1, 2]]]]}, 
 # /. {c : Alternatives @@ diag, p__Point} :> Module[{xy = Cases[{p}, Point[x_] :> x]}, 
   Inset[Histogram[xy[[All, 1]], ChartStyle->c, AspectRatio->1/GoldenRatio, Axes -> False], 
     Min /@ Transpose@xy, {Left, Bottom}, {.9, .9}]]] &; 

Needs["StatisticalPlots`"]
pwScatterPlot = addHistograms @* PairwiseScatterPlot;

To use this function on an input data with n series we need to use an n-by-n matrix of styles where the diagonal entries are different from off-diagonal entries.

data2 = RandomReal[MultinormalDistribution[{0, 1, 2}, 
    {{1, 1/2, 1/3}, {1/2, 2, 1/3}, {1/3, 1/3, 3}}], 10^3];
labels2 = "var" <> ToString[#] & /@ {1, 2, 3};
colors2 = {{Red, Blue, Green}, {Blue, Orange, Magenta}, {Green, Magenta, Purple}};

pwScatterPlot[data2, DataSpacing -> .1, DataTicks -> Automatic, 
   DataLabels -> labels2, ImageSize -> 500, PlotStyle -> colors2]

enter image description here

Original answer:

pspF = With[{dt=#,ca=ConstantArray[1,{#,#}&@Dimensions[#][[2]]],
             opts=Sequence[Axes->False,AspectRatio->1]},
           Grid[ReplacePart[ca, {{i_,i_}:>Histogram[dt[[All,i]],opts],
                {i_,j_}:>ListPlot[dt[[All,{i,j}]],opts]}],
               Dividers->All]]&;

 data1 = RandomReal[MultinormalDistribution[{0, 0}, {{1, 1/2}, {1/2, 1}}], 10^2];
 pspF@data1

enter image description here

data2 = RandomReal[MultinormalDistribution[{0, 0,0}, 
                   {{1, 1/2,1/3}, {1/2, 2,1/3},{1/3,1/3,3}}], 10^3];

pspF@data2

enter image description here

Update 1: Using DensityHistogram with the option Method -> {"DistributionAxes"->True}:

dhF=With[{dt=#,ca=ConstantArray[1,{#,#}&@Dimensions[#][[2]]],
          opts=Sequence[Axes->False,AspectRatio->1]},
       Grid[ReplacePart[ca, {{i_,i_}:>Histogram[dt[[All,i]],opts],
            {i_,j_}:>DensityHistogram[dt[[All,{i,j}]],opts,
                      Frame->False,Method->{"DistributionAxes"->True},
                      ChartElementFunction->"Point"]}],
            Dividers->All]]&; 

data2 = RandomReal[MultinormalDistribution[{0, 0,0},
                   {{1, 1/2,1/3}, {1/2, 2,1/3},{1/3,1/3,3}}], 10^3];

dhF@data2

enter image description here

Note: You can also use "BoxWhisker", "Histogram" or "SmoothHistogram" as the setting for the suboption "DistributionAxes".

Update 2: To include PlotLabels, FrameLabels, FrameTicks etc, add these options to Histogram and/or to ListPlot:

pspF2 = With[{dt = #, ca = ConstantArray[1, {#, #} &@Dimensions[#][[2]]], 
     pr = Through[{Min, Max}[#]], opts = Sequence[AspectRatio -> 1, Frame -> True]}, 
    Grid[ReplacePart[ca, 
        {{i_, i_} :> Histogram[dt[[All, i]], Automatic, "Count", opts, 
         PlotRange -> {pr, Automatic},
         FrameLabel -> {{"Count", None}, {"var" <> ToString[i], None}},
         PlotLabel -> ("var" <> ToString[i])], {i_, j_} :> 
        ListPlot[dt[[All, {i, j}]], opts, PlotRange -> {pr, pr}, 
         FrameLabel -> {{"var" <> ToString[i], None}, {"var" <> ToString[j], None}}, 
         PlotLabel -> ("var" <> ToString[i] <> "     versus   var" <> 
            ToString[j])]}], Dividers -> All]] &;

data2 = RandomReal[MultinormalDistribution[{0, 1, 2}, 
          {{1, 1/2, 1/3}, {1/2, 2, 1/3}, {1/3, 1/3, 3}}], 10^3];

pspF2@data2

enter image description here

$\endgroup$
5
  • $\begingroup$ thanks! Is it possible to also include DataLabels and DataTicks? $\endgroup$
    – Valerio
    Commented Dec 28, 2014 at 23:09
  • $\begingroup$ @Valerio, please see the update. $\endgroup$
    – kglr
    Commented Dec 28, 2014 at 23:46
  • $\begingroup$ thanks but the labels should appear only on the outer frames and so the numbers associated with the ticks (see my updated plot). Also, if I test pspF2 with data of my example (I've changed the covariance matrix to make obvious which is var1 and which is var2) I get the wrong ordering, that is the columns do not have the same variables for the various x-axes: to have the right ordering I have to transpose the matrix. $\endgroup$
    – Valerio
    Commented Dec 29, 2014 at 23:40
  • $\begingroup$ @Valerio, just saw your update with a specific example of what you need. I am afraid we need a more elaborate function than pspF to get a full-fledged trellis display like the example in the linked article. Deleting for now until I find a better approach. $\endgroup$
    – kglr
    Commented Dec 29, 2014 at 23:51
  • $\begingroup$ I have only recently begun to study this topic. Can you please tell me what these histograms show and how they are built from two data sets? $\endgroup$
    – ayr
    Commented Oct 16, 2022 at 12:03
2
$\begingroup$

Using the function VariableDependenceGrid from the package "MathematicaForPredictionUtilities.m":

data = RandomReal[MultinormalDistribution[{0, 0, 0}, {{1, 1/2, -2/3}, {1/2, 5, 2}, {-2/3, 2, 20}}], 10^3];
Import["https://raw.githubusercontent.com/antononcube/MathematicaForPrediction/master/MathematicaForPredictionUtilities.m"]
VariableDependenceGrid[data, "var" <> ToString[#] & /@ Range[3]]

enter image description here

(See also this answer.)

$\endgroup$
2
  • $\begingroup$ I have only recently begun to study this topic. Can you please tell me what these histograms show and how they are built from two data sets? $\endgroup$
    – ayr
    Commented Oct 16, 2022 at 12:03
  • 1
    $\begingroup$ @dtn Thank you for your interest! I will do that in the next few days… $\endgroup$ Commented Oct 17, 2022 at 1:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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