GiovineItalia / Gadfly.jl

Crafty statistical graphics for Julia.
http://gadflyjl.org/stable/
Other
1.9k stars 250 forks source link

Automatically plot different layers with different default colors? #1191

Open tlnagy opened 6 years ago

tlnagy commented 6 years ago

I just ran into this question: https://stackoverflow.com/questions/40563981/gadfly-new-color-layer

When I push new layer to an existing plot, it keeps the same color. Is there a way to change the color automatically when a new layer is pushed to a plot, or at least a way to set the color using a random number (I don't know in advance how many layers I will have) ?

Seems like a reasonable request to use the default color function to set default colors, i.e. using

julia> using Gadfly

julia> a = Scale.color_discrete_hue()
DiscreteColorScale((anonymous function),nothing,nothing,true)

julia> a.f(3)
3-element Array{ColorValue{T},1}:
 LCHab{Float64}(70.0,60.0,240.0)             
 LCHab{Float64}(80.0,70.0,100.43478260869566)
 LCHab{Float64}(65.0,70.0,0.0)    
Mattriks commented 4 years ago

Here's a solution (using the example from stackoverflow):

x, y = [1, 2, 3, 4], [3, 7, 5, 1]
xmin1, xmax1 = x.-0.1, x.+0.1
xmin2, xmax2 = x.-0.5, x.-0.3

p1 = plot(xmin=xmin1, xmax=xmax1, y=[3, 7, 5, 1], Geom.bar, color=[1], 
    Scale.color_continuous)
p2 = plot(xmin=xmin1, xmax=xmax1, y=[3, 7, 5, 1], Geom.bar, color=[1], 
    Scale.color_discrete)

lyr2 = layer(xmin=xmin2, xmax=xmax2, y=[3, 7, 5, 1], Geom.bar, color=[2])
push!(p1, lyr2); push!(p2, lyr2) 
hstack(p1, p2)

bar02

Could it be automated? I'm not sure that could be done in a way that's any more concise than simply adding push!(p, layer(..., color=[i])) in a loop. Would be good to add the above example to the docs layers section.

tlnagy commented 4 years ago

I think that's a good example, what I think could be automated is not having the color keyword at all, i.e. something like

p3 = plot(xmin=xmin1, xmax=xmax1, y=[3, 7, 5, 1], Geom.bar)
lyr3 = layer(xmin=xmin2, xmax=xmax2, y=[3, 7, 5, 1], Geom.bar)

push!(p3, lyr3) 

where p3 == p2. That is, we should assume Scale.color_discrete() and auto-assign a color from our default color scale unless the user provides a color keyword in any layer or a different scale. I feel that this is a saner default then what we currently do.

Mattriks commented 4 years ago

Currently, aesthetics override Themes (e.g. color= overrides Theme(default_color=). So there is a question here about what is the syntax for having some layers autocolored, and some layers set to a particular color?