RE: plot of "marginal distributions" of scatter plot
- To: mathgroup at smc.vnet.net
- Subject: [mg74118] RE: [mg74112] plot of "marginal distributions" of scatter plot
- From: "David Annetts" <davidannetts at aapt.net.au>
- Date: Mon, 12 Mar 2007 04:30:52 -0500 (EST)
- References: <200703101156.GAA28443@smc.vnet.net>
Hi Claus, > I'd like to plot the "marginal distributions" of a > scatterplot just on the sides of the scatterplot. > I'd like to have something similar to this (the "Axis bar > plot"), but with mathematica: > http://www.cl.cam.ac.uk/~sjm217/projects/graphics/ > so far I've come up with this: > Show[GraphicsArray[{{Histgr1, ScatPlot1}, {, Histgr2}}]] > which admittedly is lame. However I am new to mathematica, > so I wonder if anybody has better suggestions. It _is_ a bit(!) of a kludge but ..... My idea is to use DisplayTogether[] rather than GraphicsArray[]. Although this introduces new problems, they can probably be overcome. Also note that I'm using Marc Caprio's CustomTicks package (on MathSource). Anyway .... First I'll generate some data using the statistics package and plot it. Needs["Statistics`"] x = RandomArray[LaplaceDistribution[0, 2], 256]; y = RandomArray[LaplaceDistribution[2, 1], 256]; data = Transpose[{x, y}]; ListPlot[data, PlotJoined -> False]; I'll define some limits using {nx, mx} = {Min@x, Max@x}; {ny, my} = {Min@y, Max@y}; Now, we need to draw some lines corresponding to each of the data points. Yes, they are called "dot" rather than "lin". Define the helper functions dotx[{x_, y_}] := Line[{{x, ny - 1}, {x, ny - .5}}]; doty[{x_, y_}] := Line[{{nx - 1, y}, {nx - .5, y}}]; And process our data dx = dotx[#] & /@ data; dy = doty[#] & /@ data; We can plot everything using DisplayTogether[{ ListPlot[data, PlotJoined -> False], Show[Graphics[{Red, dx}]], Show[Graphics[{Blue, dy}]] }, Frame -> False, Axes -> True, AxesOrigin -> {nx - 2, ny - 2}, Ticks -> { LinTicks[nx, mx], LinTicks[ny, my]} ]; This is very similar to the top plot at the URL you provided. We can use the same trick with the plots of the distribution. The key is the function BinCounts[] in Statistics. You'll probably want to play with the number of bins. We can get, normalise & plot the distribution in x using bx = BinCounts[x, {nx, mx, .5}] bx = bx/Max@bx; bx = Transpose[{Range[nx, mx, .5], bx}]; ListPlot[bx, PlotJoined -> False]; tpx = # - {0, -(ny - 1)} & /@ bx; px = Point[#] & /@ tpx; The last two lines convert our plot to a set of points and shift them below the rest of the data. Do the same for our y dataset, noting we need to rotate the plot. by = BinCounts[y, {ny, my, .5}] by = by/Max@by; by = Transpose[{by, Range[ny, my, .5]}]; ListPlot[by, PlotJoined -> False]; tpy = # - {-(nx - 1), 0} & /@ by; py = Point[#] & /@ tpy; Now we can combine the data and the two distributions using DisplayTogether[{ ListPlot[data, PlotJoined -> False], Show[Graphics[{Red, px}]], Show[Graphics[{Blue, py}]] }, Frame -> False, Axes -> True, AxesOrigin -> {nx - 2, ny - 2}, Ticks -> { LinTicks[nx, mx], LinTicks[ny, my]} ]; This plot is similar to the second plot on the URL you provided. Clearly, this solution has problems in that the axes extend further than I'd like. I believe from the CustomTicks documentation that this package can be used to fix the problem, but I'm not sure. You might also like to fine-tune the distribution plots so that they look more like histograms, but this should be straightforward. An alternative solution to my laborious effort above would be to convert everything to Graphics primitives and construct the axes & ticks by hand. This would be a whole lot quicker (I suspect) and be far less prone to error. Regards, Dave.
- References:
- plot of "marginal distributions" of scatter plot
- From: Claus <claus.haslauer@web.de>
- plot of "marginal distributions" of scatter plot