# Scatterplot with marginal histograms

**URL:** <https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619>\
**Category:** Visualization\
**Tags:** plotting\
**Created:** [April 15, 2020, 6:56am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619 "2020-04-15T06:56:36Z")\
**Posts on this page:** 16\
**Page:** 2

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [April 16, 2020, 12:19pm UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/21 "2020-04-16T12:19:38Z")

</div>

@Humphrey_Lee I started a [github gist](https://gist.github.com/Mattriks/eee7469a10443f4291358dbb22d2cab7), which is a quick implementation of marginal histograms in Gadfly. Plenty of room for improvement, please make comments there.

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [April 16, 2020, 12:43pm UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/22 "2020-04-16T12:43:34Z")

</div>

This one will go into the Gallery… It seems to be useful for a lot of people.

---

<div class="post-metadata">

**Author:** ![Humphrey\_Lee](https://avatars.discourse-cdn.com/v4/letter/h/a88e4f/32.png) [@Humphrey\_Lee](https://discourse.julialang.org/u/Humphrey_Lee)\
**Post date:** [April 16, 2020, 11:18pm UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/23 "2020-04-16T23:18:33Z")

</div>

> [@Mattriks](#):
>
> @Humphrey_Lee I started a [github gist](https://gist.github.com/Mattriks/eee7469a10443f4291358dbb22d2cab7), which is a quick implementation of marginal histograms in Gadfly. Plenty of room for improvement, please make comments there.

@Mattriks. Saw your first plot. Nice! My 2cents comments:-

- Add axis into both histograms [can be frequency (normalized) or counts (un-normalized)];
- Add cumulative line into both histograms; &
- If the plot data is of multiple groups, e.g. by colors, the histogram should reflect that as well, by showing stacked histogram.

---

<div class="post-metadata">

**Author:** ![Humphrey\_Lee](https://avatars.discourse-cdn.com/v4/letter/h/a88e4f/32.png) [@Humphrey\_Lee](https://discourse.julialang.org/u/Humphrey_Lee)\
**Post date:** [April 21, 2020, 12:14am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/24 "2020-04-21T00:14:11Z")

</div>

Can you share how can I use this module `gg.jl`?

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [April 21, 2020, 12:25am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/25 "2020-04-21T00:25:16Z")

</div>

`gg.jl` is a file, so `include("gg.jl")`.

---

<div class="post-metadata">

**Author:** ![Humphrey\_Lee](https://avatars.discourse-cdn.com/v4/letter/h/a88e4f/32.png) [@Humphrey\_Lee](https://discourse.julialang.org/u/Humphrey_Lee)\
**Post date:** [April 21, 2020, 12:43am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/26 "2020-04-21T00:43:08Z")

</div>

Thanks. Successfully replicated your example. Will do more tests to incorporate my 3 suggestions.

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [April 21, 2020, 12:58am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/27 "2020-04-21T00:58:01Z")

</div>

Custom guides could be developed in a separate package (e.g. ggplot has ggExtra). Note the coding of aesthetic guides (e.g. color, shape etc) is under 🚧 in Gadfly (e.g. [Stacked guides by Mattriks · Pull Request #1423 · GiovineItalia/Gadfly.jl · GitHub](https://github.com/GiovineItalia/Gadfly.jl/pull/1423)), so structural changes may occur that affect external development.

---

<div class="post-metadata">

**Author:** ![Humphrey\_Lee](https://avatars.discourse-cdn.com/v4/letter/h/a88e4f/32.png) [@Humphrey\_Lee](https://discourse.julialang.org/u/Humphrey_Lee)\
**Post date:** [May 2, 2020, 1:43am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/28 "2020-05-02T01:43:55Z")

</div>

Saw some commits in git repository for PR#1423. Not sure how much this has matured. Last test (~10 days ago), it did not allow additional layer. Please let me know I can help to test.

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [May 2, 2020, 2:39am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/29 "2020-05-02T02:39:17Z")

</div>

PR #1423 was merged, so it’s available on master (in julia, `]add Gadfly#master`).  
You’ll have to explain what you mean by “it did not allow an additional layer” (please provide example code).

---

<div class="post-metadata">

**Author:** ![Humphrey\_Lee](https://avatars.discourse-cdn.com/v4/letter/h/a88e4f/32.png) [@Humphrey\_Lee](https://discourse.julialang.org/u/Humphrey_Lee)\
**Post date:** [May 2, 2020, 2:48am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/30 "2020-05-02T02:48:26Z")

</div>

I probably did it the wrong way. Don’t know how to use/ call the merged features. I’ve pulled in latest Gadfly. My code is below.

```julia
using Gadfly, Cairo
include(raw"D:\codes\Git\gg.jl")

X = randn(1000, 2)
X1 = randn(1000, 2)

p = Gadfly.plot(x=X[:,1], y=X[:,2], Geom.point, gg.margins(),
    layer(x=X1[:,1], y=X1[:,2], Geom.path, order=3, Gadfly.Theme(default_color=colorant"red")),
    color=[colorant"deepskyblue"],
    Gadfly.Theme(panel_stroke="gray", default_color="gray80")
)

draw(PDF("marginalhistogram.pdf", 5inch, 5inch), p)

l1 = layer(x=X[:,1], y=X[:,2], Geom.point, gg.margins())
l2 = layer(x=X1[:,1], y=X1[:,2], Geom.path, order=3, Gadfly.Theme(default_color=colorant"red"))

p1 = plot(x=X[:,1], y=X[:,2], Geom.point, gg.margins(), l2)

draw(PDF("marginalhistogram1.pdf", 5inch, 5inch), p1)

```

The error messages.

```julia
WARNING: replacing module gg.
LoadError: Layers can't be used with elements of type Main.gg.Marginal
Stacktrace:
 [1] error(::String) at .\error.jl:33
 [2] add_plot_element!(::Array{Layer,1}, ::Main.gg.Marginal) at ...

```

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [May 2, 2020, 3:33am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/31 "2020-05-02T03:33:26Z")

</div>

The error happens in this line: `l1 = layer(x=X[:,1], y=X[:,2], Geom.point, gg.margins())`. The output of `gg.margins()` is a Guide, and you can’t put guides in layers (see the [Layers section](http://gadflyjl.org/dev/man/compositing/#Layers-1) in the Gadfly docs). You can put Guides directly in the plot statement, as you have already done in your plot `p` and plot `p1`.  
`

---

<div class="post-metadata">

**Author:** ![Humphrey\_Lee](https://avatars.discourse-cdn.com/v4/letter/h/a88e4f/32.png) [@Humphrey\_Lee](https://discourse.julialang.org/u/Humphrey_Lee)\
**Post date:** [May 2, 2020, 4:11am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/32 "2020-05-02T04:11:24Z")

</div>

If this is implemented as Guide, I’m not sure how extensible it will be. I also noticed the marginal\_histogram in R’s [ggExtra](https://deanattali.com/2015/03/29/ggExtra-r-package/) is also pretty primitive. See code sample below to demo my enhancement proposal. In scenario #1, I might want to do histogram for the Geom.point only, excluding Geom.line. In scenario #2, the histogram is not detail enough. Stacked histogram would be helpful.

```julia
using Gadfly, Cairo
include(raw"D:\codes\Git\gg.jl")

X = randn(10, 2)
X1 = randn(10, 2) .- 10

l1 = layer(x=X[:,1], y=X[:,2], Geom.point)
l2 = layer(x=X1[:,1], y=X1[:,2], Geom.line, order=3, Gadfly.Theme(default_color=colorant"red"))

p1 = plot(l1, l2, gg.margins())

draw(PDF("marginalhistogram1.pdf", 5inch, 5inch), p1)

using RDatasets
D = dataset("datasets", "iris")
p3 = plot(D, x="SepalLength", y="SepalWidth", color="Species", Geom.point, gg.margins())

draw(PDF("marginalhistogram2.pdf", 5inch, 5inch), p3)

```

marginalhistogram1

 ![marginalhistogram1](https://global.discourse-cdn.com/julialang/original/3X/f/8/f8cedc3d9935c682f502c8eeb1a87d98b5cc55f1.png)

marginalhistogram2

 ![marginalhistogram2](https://global.discourse-cdn.com/julialang/original/3X/2/6/26968f38a2f7e897f15e2c1b7d74b99cb16fc389.png)

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [May 2, 2020, 4:40am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/33 "2020-05-02T04:40:04Z")

</div>

Both these enhancements can be developed, but at the moment I’m busy with [Roadmap · Issue #1385 · GiovineItalia/Gadfly.jl · GitHub](https://github.com/GiovineItalia/Gadfly.jl/issues/1385) and other issues.

---

<div class="post-metadata">

**Author:** ![Humphrey\_Lee](https://avatars.discourse-cdn.com/v4/letter/h/a88e4f/32.png) [@Humphrey\_Lee](https://discourse.julialang.org/u/Humphrey_Lee)\
**Post date:** [May 5, 2020, 12:19am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/34 "2020-05-05T00:19:35Z")

</div>

Tried running your code, but encountered error. I’ve updated to latest Gnuplot (1.3.0) and even tried #master branch. Error below.

```julia
LoadError: type NamedTuple has no field TERM_XMIN
in expression starting at untitled-e7bdc683e45977abea23bd6e2e41964d:17
getproperty at Base.jl:33 [inlined]
gpmargins(::Symbol) at Gnuplot.jl:2281
gpmargins() at Gnuplot.jl:2278
top-level scope at untitled-e7bdc683e45977abea23bd6e2e41964d:17

```

Second question is how customizable are the histograms? For example, if the plot are multi-layers/ stacked plots, can the histogram applies to certain layers (or combination)? If the scatter consists of multi-color/ shape, can the histogram turn into stacked histogram, representing/ mimicking the shape/ color distribution? Thanks.

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [May 5, 2020, 12:44am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/35 "2020-05-05T00:44:02Z")

</div>

I guess it’s because you’re running in Jupyter or Juno, while `gpmargins()` and `gpranges()` requires an actual gnuplot terminal.

Try run the above code in a simple Julia REPL. Or try the following in Jupyter:

```julia
using Gnuplot

x = randn(1000);
y = randn(1000);

# Overall plot margins (normalized in the range 0:1)
margins = (l=0.08, r=0.98, b=0.13, t=0.98)

# Right and top margins of main plot
right, top = 0.8, 0.75

# Gap between main plot and histograms
gap = 0.015

# Axis range
xr = [-3,3]
yr = [-3,3]

# Main plot
@gp "set multiplot"
@gp :- 1 ma=margins rma=right tma=top xr=xr yr=yr :-
@gp :- x y "w p notit" xlab="X" ylab="Y"

# Histogram on X
h = hist(x, nbins=10)
@gp :- 2 ma=margins bma=top+gap rma=right xr=xr yr=[NaN,NaN] :-
@gp :- "set xtics format ''" "set ytics format ''" xlab="" ylab="" :-
bs = fill(h.binsize, length(h.bins));
@gp :- h.bins h.counts./2 bs./2 h.counts./2 "w boxxy notit fs solid 0.4" :-

# Histogram on Y
h = hist(y, nbins=10)
@gp :- 3 ma=margins lma=right+gap tma=top xr=[NaN,NaN] yr=yr :-
@gp :- "unset xrange" :-
bs = fill(h.binsize, length(h.bins));
@gp :- h.counts./2 h.bins h.counts./2 bs./2 "w boxxy notit fs solid 0.4" :-
@gp

```

Concerning your second question: you have complete flexibility for the horizontal histogram on the top (see `set style histogram` in the gnuplot manual), while for the vertical histogram on the right you need to calculate the bounding coordinates of each histogram "bar, and use the color/filling properties of the `boxxyerror` style.

---

<div class="post-metadata">

**Author:** ![Humphrey\_Lee](https://avatars.discourse-cdn.com/v4/letter/h/a88e4f/32.png) [@Humphrey\_Lee](https://discourse.julialang.org/u/Humphrey_Lee)\
**Post date:** [May 5, 2020, 12:53am UTC](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619/36 "2020-05-05T00:53:36Z")

</div>

Tried the original code in REPL, still error → `ERROR: LoadError: type NamedTuple has no field TERM_XMIN Stacktrace: [1] getproperty at .\Base.jl:33 [inlined]`

Run the new code above in REPL, it works.

[Previous page](https://discourse.julialang.org/t/scatterplot-with-marginal-histograms/37619.md?page=1)
