share
MathematicaVisualization of Bivariate Distributions
[+24] [4] Alex
[2013-06-16 05:43:43]
[ plotting graphics3d distributions ]
[ https://mathematica.stackexchange.com/questions/27083/visualization-of-bivariate-distributions ]

I know it is perfectly possible to show the bivariate probability distributions in MMA. But my question is can we show each dimension of distribution in 2D dimension while we are showing the 3D plot? The same as here:

enter image description here

How we can have the 2D histograms in the sides and 3D histogram in between?

Look up MarginalDistribution[], among other things... - J. M.'s missing motivation
@0x4A4D with 2D histograms on the sides and 3D histogram in the middle? - Alex
(2) Well, you can use RandomVariate[] to generate random variates from your bivariate distribution, yes, then use Histogram[] on each component of the variates. I'm seeing no 3D histogram, tho; just a point cloud, an enclosing ellipse, and nothing more. - J. M.'s missing motivation
(2) The more I stare at this plot, the more unstable it becomes -- it keeps flipping in 3D perspective like a Necker cube en.wikipedia.org/wiki/Necker_cube - bill s
(1) In case of 3D histogram important question is: what do You want z-scale to show. Maybe You want different scales for marginal distributions and main 2D distribution, that could be reasonable for clarity of plot. - Kuba
@Kuba definitely you can read my mind!!Thanks for saying that. - Alex
[+23] [2013-06-16 11:47:41] Rod [ACCEPTED]

You can also try this:

Generate yor data:

data = RandomVariate[\[ScriptD] = 
  MultinormalDistribution[{0, 0}, {{1, 0.9}, {0.9, 2}}], 10^4];

To improve a little bit the final image, you might want to introduce lighting vectors:

lightSources = {
 {"Directional", White,Scaled[{1, 0, 1}]}, 
 {"Directional", White,Scaled[{1, .5, 1}]}, 
 {"Directional", White, Scaled[{.5, 0, 1}]}
};

Create the 3D histogram

G1 = Histogram3D[data, {0.25}, "PDF", ColorFunction -> "Rainbow", 
  PlotRange -> {{-4, 4}, {-4, 4}, All}, ImageSize -> Medium, 
  Boxed -> False, Lighting -> lightSources]

Create the individual histograms

G3 = Histogram[Transpose[data][[1]], {-4, 4, .25}, "Probability", 
  ColorFunction -> Function[{height}, ColorData["Rainbow"][height]], 
  Axes -> False]
G4 = Histogram[Transpose[data][[2]], {-4, 4, .25}, "Probability", 
  ColorFunction -> Function[{height}, ColorData["Rainbow"][height]], 
  Axes -> False]

Show them all together:

G5 = Graphics3D[{EdgeForm[], Texture[G3], 
 Polygon[{{4, 4, 0}, {-4, 4, 0}, {-4, 4, 0.2}, {4, 4, 0.2}},  
   VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}, 
 Axes -> False, Boxed -> False];
G6 = Graphics3D[{EdgeForm[], Texture[G4], 
 Polygon[{{-4, 4, 0}, {-4, -4, 0}, {-4, -4, 0.2}, {-4, 4, 0.2}}, 
   VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}, 
 Axes -> False, Boxed -> False];
Show[G1, G5, G6]

enter image description here

EDITED

If you want a strict 2D representation of the data you can try this:

DH = DensityHistogram[data, {-4, 4, .25}, ColorFunction -> "Rainbow", Frame -> False];
GraphicsGrid[{{G3,}, {DH, Rotate[G4, -.5 Pi]}}]

enter image description here


1
[+17] [2013-06-16 15:16:03] xan

Don't do it!

3D plots on a 2D surface are an anti-pattern for data visualization. The perspective mapping taints the free perceptual processing you get from your visual cortex. Angles are no longer what they seem. The 3D histogram makes things even worse by the way foreground bars obscure other bars -- not only is the data poorly represented: some of it is invisible!

For example, @RodLm's answer shows exactly what you asked for, but can you tell the 3D histogram distribution represents an ellipse?

A couple links on 3D chart junk angle, infovis-wiki [1] peltiertech [2], and a 2D pic (not from Mathematica).

bivariate normal

[1] http://www.infovis-wiki.net/index.php/Chart_Junk#3D_Bar_Chart
[2] http://peltiertech.com/WordPress/the-perils-of-being-in-3d/

...and now, an answer I can get behind with... - J. M.'s missing motivation
Good point. But who said it is going to be printed. It could be part of interactive cdf. Then there will be no doubts. - Kuba
Yes and No!Thanks, you are right if we are going to print it and read the data out of it; but as Kuba said it is just to show interactive PDF or CDF.The main problem is about scaling that Kuba mentioned before as well. - Alex
(1) @xan You can easily show the elliptical relation between the variables by using the CountourPlot[] of your data... You could also use Plot3D[PDF[\[ScriptD], {x, y}], {x, -4, 4}, {y, -4, 4}] to see the continuous version of the plot... - Rod
(2) @Kuba, The question didn't mention interactive use either. I assume you are referring to how through interaction one can tilt and rotate a 3D view to see hidden elements and how movement helps reduce the mental translation of 2D to 3D. Even so, there is some cost to requiring the viewer to interrogate the graphic instead of having a graphic that can speak for itself. - xan
@RodLm, From that Plot3D view, I can see the top is elliptical because of the truncated probability dimension (how do I change the scale?), but I can't tell what's obscured without interacting with the plot, which was my main point on the 3D histogram. - xan
(1) I do agree with You. I just wanted to show it isn't so bad as one could think. - Kuba
@xan as you can easily find from the title, it is about bivariates distributions and the resut has to be in 3D plots.It shows from stochastic point how probability of two random variables could effect each other.The points that you mentioned in the linkes that you refereeing , are easily can be shown in 2D but here the story is different. We have no other way just 3D. Sometimes we have to look at the cases from uncertainties point of view!!!! - Alex
(2) Surely there are many other ways besides 3D to view the interaction. A blended point cloud, a heat map (as shown in RodLm's updated answer), a 2D contour plot, a non-parametric density plot, ... - xan
2
[+15] [2013-06-16 10:24:35] Kuba

I'm going to show method of displaying marginal distributions based on Histogram3D, it has disadvantages, but also a couple of advantages (concise code, tooltip preserved, etc.)

hist[data_, rx_, ry_] :=Show[{
   ListPointPlot3D[{##, 0} & @@@ data],
   Histogram3D[{#1, ry} & @@@ data, {.2}],
   Histogram3D[{-rx, #2} & @@@ data, {.2}, ChartStyle -> Red]},
PlotRange -> {{-rx, rx}, {-7, 7}, All}, AxesEdge -> {{-1, -1}, {1, -1}, {-1, 1}}, 
FaceGrids -> {{-1, 0, 0}, {0, 0, -1}, {0, 1, 0}},Boxed -> False]

data = RandomVariate[BinormalDistribution[{1, 2}, .8], 10^3];
hist[data, 4, 7]

enter image description here

Update after comments and answers:

The most important thing is xan's answer. I agree with that point but I do not consider Alex's question useless.

The issue discussed in comments was about z-scale. Marginal distributions are 1D while real data distribution is 2D. Integrals/bin counting/counts per bin differ for them. So the question is, what do we want to show.

I could set "Count" for each, z-scale tells the truth but Histogram3D looks a little bit flat:

enter image description here

Histogram/Histogram3D gives us ability to manage bins/values through PureFunctions in place of 2nd and 3rd argument of them (details in Help). We can rescale number of counts:

Histogram3D[data, {.2}, Function[{x, y, z}, t z] (*t is scale factor*)

Caution: z axis now is related to marginal distributions only! What I wanted to show is this functionality.

enter image description here

At the end I decided that if we want to focus on shapes of distributions the best solution is to normalize each distribution at bin with maximum value of counts. It can be easily applied with previous functionality with function:

Function[{x, y, z}, z/Max@z]

enter image description here

One should keep in mind that normalization factor is different for each distribution.


nice job with less code.Thank you all cause I am learning a lot. - Alex
About Z scale if we are going to have the "Probability" then it would be alright?Right? - Alex
@Alex No I don't think so. Take a look at simpler case of uniform distrubution. If we divide it on 10x10 bins then each bin will have value 1/100 for "Probability" while marginal distributions would have 1x10 bins -> 1/10 for each, so the scale is different. - Kuba
Yes.but look at the Rod Lm response.It shows the probability on the axes.Yours code shows the number of data in histogram not "Probability".Then your case from scale point of view is more complicated.Am I right? - Alex
@Alex z-axis on his plot is related to Histogram3D. Marginal distributions fit to it because texture which they are is rescaled to fit the box. Try , Axes -> True in G3 and G4 and see the real values. So the plot looks good at the end but it would be hard to name z-axis related to those histograms. - Kuba
@Alex I think the last solution is what You need. - Kuba
3
[+13] [2013-06-16 09:32:06] shrx

First you determine the binormal distribution of the data:

data = RandomVariate[BinormalDistribution[{1, 0}, {2.5, 5}, 0], 10^4];
dataX = data[[All, 1]];
dataY = data[[All, 2]];
dist = EstimatedDistribution[data, 
BinormalDistribution[{Subscript[μ, 1], Subscript[μ, 
2]}, {Subscript[σ, 1], Subscript[σ, 2]}, ρ]]
distX = EstimatedDistribution[dataX, 
NormalDistribution[μ, σ]]
distY = EstimatedDistribution[dataY, 
NormalDistribution[μ, σ]]

Then you draw the plots for $x$ and $y$ distribution and the contour plot:

x = Show[
Histogram[dataX, 20, "PDF", PlotRange -> {{-20, 20}, {-.005, .25}}, 
Axes -> False, PlotRangePadding -> 0, AspectRatio -> 1/2],
Plot[PDF[distX, x], {x, -20, 20}, 
PlotStyle -> Directive[{Thick, Blue}]]]
y = Show[
Histogram[dataY, 20, "PDF", PlotRange -> {{-20, 20}, {-.005, .25}}, 
Axes -> False, PlotRangePadding -> 0, AspectRatio -> 1/2],
Plot[PDF[distY, x], {x, -20, 20}, 
PlotStyle -> Directive[{Thick, Red}]]]
c = ContourPlot[
PDF[dist, {x, y}] == .00001, {x, -20, 20}, {y, -20, 20}, 
Epilog -> {PointSize[Small], Point /@ data}, PlotPoints -> 50, 
Frame -> False, ContourStyle -> Directive[{Thick, Green}]]

Finally, combine it all together:

pp1 = Graphics3D[{EdgeForm[], Texture[x], 
Polygon[{{-20, 20, 0}, {20, 20, 0}, {20, 20, .25}, {-20, 
   20, .25}}, 
 VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}];
pp2 = Graphics3D[{EdgeForm[], Texture[y], 
Polygon[{{-20, -20, 0}, {-20, 20, 0}, {-20, 
   20, .25}, {-20, -20, .25}}, 
 VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}];
pp3 = Graphics3D[{EdgeForm[], Texture[c], 
Polygon[{{-20, -20, 0}, {20, -20, 0}, {20, 20, 0}, {-20, 20, 0}}, 
 VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}];

Graphics3D[{pp1[[1]], pp2[[1]], pp3[[1]]}, 
Lighting -> {{"Ambient", White}}, BoxRatios -> {1, 1, 1/2}, 
Boxed -> False, Axes -> True, PlotRangePadding -> 0, 
ViewPoint -> {2, -2, 1}, ImageSize -> 600]

The result: 3d plot

I'm not sure if MMA can do isometric projections.


4