plotjuliagadfly

Adding multiple layers in Julia Gadfly plot with loops


I'm trying to plot multiple layers in Gadfly plot with a pattern as following:

p=plot(yintercept=[0,1,2,3],Geom.hline(color=colorant"darkgray", size=0pt),

 [ layer( x=locs, y=BS[:,i]+1-1, Geom.line,Theme(default_color=colorant"red") ) for i in ind[1] ] ... ,

 [ layer( x=locs, y=BS[:,i]+2-1, Geom.line,Theme(default_color=colorant"red") ) for i in ind[2] ] ... ,

 [ layer( x=locs, y=BS[:,i]+3-1, Geom.line,Theme(default_color=colorant"red") ) for i in ind[3] ] ... ,

 [ layer( x=locs, y=BS[:,i]+4-1, Geom.line,Theme(default_color=colorant"red") ) for i in ind[4] ] ...

) 

It's quite annoying to add layers manually when m getting large(currently m is up to 4). So I want to write a loop to add layers to current plot p.

p=plot(yintercept=[0,1,2,3],Geom.hline(color=colorant"darkgray", size=0pt) )

for m=0:M
  q = append!(p.layers, [ layer( x=locs, y=BS[:,i]+m, Geom.line,Theme(default_color=colorant"red") ) for i in ind[m+1] ] ... )
end

The loop doesn't work now. Any ideas on how to easily get the layers added?


Solution

  • Since Gadfly is inspired by ggplot2, then we can use the DataFrames library and apply the stack function. Consider the following:

    using DataFrames: DataFrame, head, stack
    
    my_df = DataFrame(x = collect(1:100));
    

    Now suppose we add columns for different slope values of the slope-intercept equation. That is,

    for i in .1:.1:1.
        my_df[Symbol("line_" * string(i))] = 100 + my_df[:x] * i
    end
    

    So that the head of our dataset is given below:

    julia> print(head(my_df))
    
    │ Row │ x │ line_0.1 │ line_0.2 │ line_0.3 │ line_0.4 │ line_0.5 │ line_0.6 │
    ├─────┼───┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
    │ 1   │ 1 │ 100.1    │ 100.2    │ 100.3    │ 100.4    │ 100.5    │ 100.6    │
    │ 2   │ 2 │ 100.2    │ 100.4    │ 100.6    │ 100.8    │ 101.0    │ 101.2    │
    │ 3   │ 3 │ 100.3    │ 100.6    │ 100.9    │ 101.2    │ 101.5    │ 101.8    │
    │ 4   │ 4 │ 100.4    │ 100.8    │ 101.2    │ 101.6    │ 102.0    │ 102.4    │
    │ 5   │ 5 │ 100.5    │ 101.0    │ 101.5    │ 102.0    │ 102.5    │ 103.0    │
    │ 6   │ 6 │ 100.6    │ 101.2    │ 101.8    │ 102.4    │ 103.0    │ 103.6    │
    
    │ Row │ line_0.7 │ line_0.8 │ line_0.9 │ line_1.0 │
    ├─────┼──────────┼──────────┼──────────┼──────────┤
    │ 1   │ 100.7    │ 100.8    │ 100.9    │ 101.0    │
    │ 2   │ 101.4    │ 101.6    │ 101.8    │ 102.0    │
    │ 3   │ 102.1    │ 102.4    │ 102.7    │ 103.0    │
    │ 4   │ 102.8    │ 103.2    │ 103.6    │ 104.0    │
    │ 5   │ 103.5    │ 104.0    │ 104.5    │ 105.0    │
    │ 6   │ 104.2    │ 104.8    │ 105.4    │ 106.0    │
    

    Now we then plot x and the 10 lines. To do so, we need to stack the columns of these lines. That is,

    my_df_stack = DataFrame(x = repeat(my_df[:x], outer = [length(collect(.1:.1:1.))]), 
                            var = stack(my_df[2:end])[1],
                            val = stack(my_df[2:end])[2]);
    

    So that,

    julia> print(head(my_df_stack))
    
    6×3 DataFrames.DataFrame
    │ Row │ x │ var      │ val   │
    ├─────┼───┼──────────┼───────┤
    │ 1   │ 1 │ line_0.1 │ 100.1 │
    │ 2   │ 2 │ line_0.1 │ 100.2 │
    │ 3   │ 3 │ line_0.1 │ 100.3 │
    │ 4   │ 4 │ line_0.1 │ 100.4 │
    │ 5   │ 5 │ line_0.1 │ 100.5 │
    │ 6   │ 6 │ line_0.1 │ 100.6 │
    

    Finally, the plot is done as follows:

    using Gadfly
    Gadfly.push_theme(:dark)
    
    plot(my_df_stack, x = :x, y = :val, group = :var, Geom.line)
    

    enter image description here or

    plot(my_df_stack, x = :x, y = :val, color = :var, Geom.line)
    

    enter image description here