# Plotting histogram on the y-axis at the end of a time series

**URL:** <https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381>\
**Category:** Visualization\
**Tags:** question, plotting\
**Created:** [August 14, 2017, 8:02pm UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381 "2017-08-14T20:02:37Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![chase](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chase/32/7146_2.png) [@chase](https://discourse.julialang.org/u/chase)\
**Post date:** [August 14, 2017, 8:02pm UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/1 "2017-08-14T20:02:37Z")

</div>

I came across a figure which had a visualization I really liked. It shows the time series of some simulations and then has the histogram of the end state of the system plotted on a new, rotated axis. I know this plot was done in Python, but don’t know how to approach it in either Python or Julia.

Is there any mechanic which could be used to generate such a plot? The trick it seems is that the two plots are sharing the y-axis of the time-series plot, but then the histogram is plotted as a seemingly separate subplot. I could not find any feature for which this is possible.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/2/12bd295abb5b810e06c85f3be76c61219cac84c7.png)

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 14, 2017, 8:08pm UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/2 "2017-08-14T20:08:00Z")

</div>

Check out [GitHub - JuliaPlots/StatsPlots.jl: Statistical plotting recipes for Plots.jl](https://github.com/JuliaPlots/StatPlots.jl) for some inspiration from similar plots produced using `Plots.jl`

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [August 14, 2017, 9:39pm UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/3 "2017-08-14T21:39:44Z")

</div>

Yeah you can write a Plots recipe for this, i’ll update tomorrrow unless someone beats me to it. But most Julia plotting packages should be able to do this.

---

<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:** [August 15, 2017, 1:44am UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/4 "2017-08-15T01:44:42Z")

</div>

Here is my quick attempt to produce a “similar” plot in [Gadfly](http://gadflyjl.org/stable/).

```plaintext
x = 1.0:5:500.0
D = DataFrame(x=x, y=x/250+randn(100))
pa = plot(D, layer(x=:x, y=:y, Geom.point, Geom.smooth),
    layer(x=[0], y=[4], label=["x10⁴"], Geom.label(position=:right)),
    Guide.xlabel("Time<sub> </sub>(yr)"), Guide.ylabel("Volume (km³)"), 
    Guide.title("Grounded Volume") )
pb = plot(D, y=:y, Geom.histogram(orientation=:horizontal, bincount=10, density=true), 
    Guide.xlabel("π(<i>V̂<sub>g</sub></i>)<sup>x10⁻⁵</sup>"), Guide.ylabel(""),
    Guide.title(" "))

M = Array{Compose.Context}(1,2)
M[1] = compose(context(0,0,2/3,1), render(pa))
M[2] = compose(context(0,0,1/3,1), render(pb))

draw(PNG(6.6inch, 3.3inch), hstack(M...))

```

![fig1](https://global.discourse-cdn.com/julialang/original/3X/9/4/943e71dceb149d1591b571242a9f623134a40f54.png)

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [August 15, 2017, 8:33am UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/5 "2017-08-15T08:33:27Z")

</div>

Very nice. The Plots code is very similar, in fact:

```julia
sims = hcat((x->cumsum(randn(200))).(1:100)...) # produce 100 random walks with 200 steps

using Plots, LaTeXStrings
pyplot(grid = false, legend = false, color = :grey, 
          guidefont = font("serif", 18), titlefont = font("serif", 18)) 
# or plotlyjs(), gr(), pgfplots()... sessionwide defaults to plot can go here
# these defaults try to mimic the grey color and large font of the example

# produce the subplots
p1 = plot(sims, alpha = 0.3, lw = 2, 
              title = L"Grounded\;volume", xlabel = L"Time\;(yr)", 
              ylabel = L"Volume\;(km^3)");
p2 = histogram(sims[end,:], lw = 0, orientation = :horizontal, 
               bin = 10, xlim = (0,30), 
               xlabel = L"π(\hat{V}_g)^{x10^{-5}}");

plot(p1, p2, link = :y, layout = grid(1,2,widths = [0.7,0.3]))

```

![example](https://global.discourse-cdn.com/julialang/original/3X/0/e/0e6c1a4ec3cbc7cf26ec411de105ebc4d0454d30.png)

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [August 15, 2017, 11:44am UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/6 "2017-08-15T11:44:29Z")

</div>

I also promised a “recipe”. So, Plots is not really a plotting package, in that it does not do any plotting itself. It is a package that allows a user to specify a plot to many different plotting packages in a uniform syntax.  
One smart aspect of that is “recipes” that allow a user to define a plot _without depending on Plots or any other plotting package_ . Thus a package can define plots without causing conflicts among plotting packages, and without enforcing any plotting package on the user (though (s)he needs to use Plots to use the recipe).

Here’s how the above plot type could be used to generate a recipe:

```julia
using RecipesBase # a tiny package defining the @recipe macro
@userplot SimPlot # defines a plotting function called "simplot"

@recipe function f(h::SimPlot; xlabel1 = "", xlabel2 = "") # define extra keywords to use in the plotting
    mat = h.args[1] # the x, y, z data to be plotted are stored in the args array

    legend := false # specify the plot attributes
    link := :y
    grid := false
    layout := grid(1, 2, widths = [0.7, 0.3])

    @series begin # send the different data to the different subplots
        subplot := 2
        seriestype := :histogram
        orientation := :h
        xlabel := xlabel2
        title := ""
        ylabel := ""
        mat[end,:]
    end

    linealpha --> 0.4 # this (specifying the opacity of the line) can be overridden by the user
    seriestype := :path
    subplot := 1
    xlabel := xlabel1
    mat # the recipe returns the data to be plotted
end

```

You can call this generic plotting function simply

```julia
using Plots; gr()
simplot(sims)

```

![34](https://global.discourse-cdn.com/julialang/original/3X/8/4/845e718a87c5698aa52078b0aa4bf8434722ae80.png)

But you still have access to the full Plots machinery and can change settings etc to get the same plot as above.

---

<div class="post-metadata">

**Author:** ![chase](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chase/32/7146_2.png) [@chase](https://discourse.julialang.org/u/chase)\
**Post date:** [August 15, 2017, 1:52pm UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/7 "2017-08-15T13:52:38Z")

</div>

Great, thanks all. This is really helpful and I like the idea of the recipe  
since it’s something I’m going to be using in a large post-processing  
workflow.

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [October 20, 2017, 9:14am UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/8 "2017-10-20T09:14:01Z")

</div>

I get an error when I try exactly this example, and I wonder if you have any clues as to why, or what I should vary to narrow this down.

I pasted the above inside a module, with `using RecipesBase` and without `using Plots`. In the REPL I load Plots and then my module, then define the fake data as above. And I get an error like so:

```julia
julia> simplot(sims)
ERROR: UndefVarError: grid not defined
Stacktrace:
 [1] macro expansion at /Users/me/.julia/v0.6/RI/src/plotrecipes.jl:378 [inlined]
 [2] apply_recipe(::Dict{Symbol,Any}, ::RI.SimPlot) at /Users/me/.julia/v0.6/RecipesBase/src/RecipesBase.jl:265
 [3] _process_userrecipes(::Plots.Plot{Plots.GRBackend}, ::Dict{Symbol,Any}, ::Tuple{RI.SimPlot}) at /Users/me/.julia/v0.6/Plots/src/pipeline.jl:81
 [4] _plot!(::Plots.Plot{Plots.GRBackend}, ::Dict{Symbol,Any}, ::Tuple{RI.SimPlot}) at /Users/me/.julia/v0.6/Plots/src/plot.jl:175
 [5] #simplot#101(::Array{Any,1}, ::Function, ::Array{Float64,2}, ::Vararg{Array{Float64,2},N} where N) at /Users/me/.julia/v0.6/RecipesBase/src/RecipesBase.jl:341
 [6] simplot(::Array{Float64,2}, ::Vararg{Array{Float64,2},N} where N) at /Users/me/.julia/v0.6/RecipesBase/src/RecipesBase.jl:341

```

If I add `using Plots` to the module then it works as expected, but if I understand right the point of this is to avoid that.

I was trying with `layout := @layout [left right{0.6w}]` before, and there too got errors unless I had `using Plots` in the module.

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [October 21, 2017, 6:03am UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/9 "2017-10-21T06:03:10Z")

</div>

You’re right - we were going to move layouts to RecipesBase at the time, but didn’t. This means that RecipesBase does not ATM support complex layouts. So in this case you’ve got to replace `layout := grid(1, 2, widths = [0.7, 0.3])` with `layout := 2`, which means you cannot control the sizes of individual subplots.

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [October 21, 2017, 9:52pm UTC](https://discourse.julialang.org/t/plotting-histogram-on-the-y-axis-at-the-end-of-a-time-series/5381/10 "2017-10-21T21:52:31Z")

</div>

OK, glad I’m not going mad!

Any thoughts on whether this is a great or a terrible idea? It does appear to work:

```julia
@require Plots begin

@userplot SimPlot  
@recipe function f(h::SimPlot; ...
  ...
  grid(1, 2, widths = [0.7, 0.3])
  ... 
end

end

```
