1

I would like to create a stacked area chart, similar to this for example, in Julia using Plots.

I know / suppose that you can do this if you directly use the Gadfly or PyPlot backends in Julia, but I was wondering if there was a recipe for this. If not, how can you contribute to the Plots Recipes? Would be a useful addition.

Gobs
  • 47
  • 3

2 Answers2

3

There's a recipe for something similar in

https://docs.juliaplots.org/latest/examples/pgfplots/#portfolio-composition-maps

For some reason the thumbnail looks broken now though (but the code works).

The exact plot in the matlab example can be produced by

plot(cumsum(Y, dims = 2)[:,end:-1:1], fill = 0, lc = :black)

As a recipe that would look like

@userplot AreaChart
@recipe function f(a::AreaChart)
         fillto --> 0
         linecolor --> :black
         seriestype --> :path
         cumsum(a.args[1], dims = 2)[:,end:-1:1]
       end

If you want to contribute a recipe to Plots you can open a pull request on Plots, or, eg. on StatsPlots - there's a good description of contributing here: https://docs.juliaplots.org/latest/contributing/

It's a bit of reading, but very generally useful as an introduction to contributing to Julia packages.

Michael K. Borregaard
  • 7,864
  • 1
  • 28
  • 35
0

You can read this thread in the Julia discourse forum where the question is developed in deep.

One solution posted there using Plots is :

# a simple "recipe" for Plots.jl to get stacked area plots
# usage: stackedarea(xvector, datamatrix, plotsoptions)
@recipe function f(pc::StackedArea)
    x, y = pc.args
    n = length(x)
    y = cumsum(y, dims=2)
    seriestype := :shape

    # create a filled polygon for each item
    for c=1:size(y,2)
        sx = vcat(x, reverse(x))
        sy = vcat(y[:,c], c==1 ? zeros(n) : reverse(y[:,c-1]))
        @series (sx, sy)
    end
end

a = [1,1,1,1.5,2,3]
b = [0.5,0.6,0.4,0.3,0.3,0.2]
c = [2,1.8,2.2,3.3,2.5,1.8]
sNames = ["a","b","c"]
x = [2001,2002,2003,2004,2005,2006]

plotly()
stackedarea(x, [a b c], labels=reshape(sNames, (1,3)))

(by user NiclasMattsson)

Other ways presented there include using the VegaLite.jl package.

Antonello
  • 6,092
  • 3
  • 31
  • 56
  • A little curious why you'd answer two hours later with a significantly more verbose and unclear solution? That solution also prevents the user from setting the properties of the lines separating the slices. – Michael K. Borregaard Apr 12 '19 at 08:05
  • @MichaelK.Borregaard Well, that's subjective. I appreciate your answer, but I (subjectively) think the solution I posted (for which I take no credit) is more clear. Also posting to the link to the thread in discourse I show that there are other solutions that has been already posted to do that or similar things, like getting the area normalised. – Antonello Apr 13 '19 at 09:13