Gadfly Layer Order (Geom.point and Geom.line)

In Gadfly, I have multiple layers (expensive, I know) - a combination of Geom.point and Geom.line (from function). I tried (https://gadflyjl.org/stable/man/compositing/#) to arrange/ order such that the line is on top, but unsuccessful. Any idea? Thanks.
Gadfly_layers_order

using Gadfly, RDatasets
iris = dataset("datasets", "iris")
fs = [x->4.5*(1.0.-exp.(-1.5*(x-4))), x->0.3x+1, x->0.3x+1.1 ]
cs = unique(iris.Species)

plot(iris, 
  layer(x=:SepalLength, y=:SepalWidth, color=:Species),
  layer(y=fs, xmin=[4.4], xmax=[8], Stat.func, Geom.line, color=cs, order=2)
    )

iris
There’s another example of Stat.func in the Gadfly docs.

Tested your code - it is working. When I modified your code to match mine, it doesn’t work. Do I have to follow exactly yours?

using Gadfly, RDatasets
iris = dataset("datasets", "iris")
ft(x) = 4.5*(1.0.-exp.(-1.5*(x-4)))
cs = unique(iris.Species)

plot( 
  layer(iris, x=:SepalLength, y=:SepalWidth, color=:Species, Geom.point),
  layer(ft, 4, 8, Geom.line(order=2),
  )

Gadfly_layers_order2

  1. This works:
plot( 
  layer(ft, 4, 8, Geom.line),
  layer(iris, x=:SepalLength, y=:SepalWidth, color=:Species)
  )
  1. This should work:
layer(ft, 4, 8, Geom.line, order=2)

but there is currently a bug, which I’ll put on the to do list.

  1. About this:
layer(ft, 4, 8, Geom.line(order=2))

Geoms are like sublayers, and a layer can contain several Geoms.
So Geom.line(order=2) controls the sublayer order, but not the layer order.

@Mattriks How to change each line color (your post #1)?

Confirmed my suspicion.

Do you mean line color separately from point color? And how many line color groups vs point color groups? An example would help.

My objective is change the default line color (not to follow Geom.point color), since I got to go with your method, until the bug is fixed. For example, assign red color for function1, orange color for function2 and so on.

Here’s line color different to point color:

using Colors
cs = ["fn1", "0.3x+1", "0.3x+1.1"]
dpalette(n::Int) = LCHuv.(65, 100, 15:(360/n):374)
palette2 = ["deepskyblue","yellow3", "hotpink", "blue", "orange", "orchid"]

p = plot(iris,
    layer(x=:SepalLength, y=:SepalWidth, color=:Species),
    layer(y=fs, xmin=[4.4], xmax=[8], Stat.func, Geom.line, color=cs, order=2),
#    Scale.color_discrete_manual(dpalette(6)...) 
   Scale.color_discrete_manual(palette2...), 
    Guide.colorkey(title="Iris")
    )

Tried your code. Removed dependency on Colors and simplified a bit - still works. Basically using Scale.color_discrete_manual to control the color. Excellent.

#using Colors
#cs = ["fn1", "0.3x+1", "0.3x+1.1"]
#dpalette(n::Int) = LCHuv.(65, 100, 15:(360/n):374)
palette2 = ["deepskyblue","yellow3", "hotpink", "blue", "orange", "orchid"]

p = plot(iris,
    layer(x=:SepalLength, y=:SepalWidth, color=:Species),
    #layer(y=fs, xmin=[4.4], xmax=[8], Stat.func, Geom.line, color=cs, order=2),
    layer(y=fs, xmin=[4.4], xmax=[8], Stat.func, Geom.line, order=2),
#    Scale.color_discrete_manual(dpalette(6)...) 
   Scale.color_discrete_manual(palette2...), 
    Guide.colorkey(title="Iris")
    )

In your example, it’s curious that the lines get color-mapped, because color is not specified in that layer. Consider this example (& try removing the color=cs):

fs = [ x->0.3x+1, x->0.3x+1.1 ]
cs = ["versicolor", "virginica"] # same os point color 
# cs = ["0.3x+1","0.3x+1.1"] # different to point color
p = plot(iris,
    layer(x=:SepalLength, y=:SepalWidth, color=:Species),
    layer(y=fs, xmin=[4.4], xmax=[8], Stat.func, Geom.line, color=cs, order=2),
    )

Sorry, I don’t think it work - after testing with various changes and restarted Julia. The color did not change, until color=cs present. Without this line, the color is auto-mapped to Goem.point. Just curious, what does this line cs = ["fn1", "0.3x+1", "0.3x+1.1"] mean, particularly fn1?

This doesn’t work for me. Error below.

ERROR: LoadError: MethodError: no method matching layer(::var"#fn_m#11"{Array{Any,1}}, ::Float64, ::Float64, ::Type{Gadfly.Geom.LineGeometry}, ::Theme; order=2)
Closest candidates are:
  layer(::Function, ::Number, ::Number, ::Union{Function, Gadfly.Element, Theme, Type}...) at

I’ve started a PR to fix that issue (https://github.com/GiovineItalia/Gadfly.jl/pull/1420).

cs = ["fn1", "0.3x+1", "0.3x+1.1"] is just a set of labels (you can change). If you want the line colors to match the point colors, than use matching point and line labels. If you want different colors, then use different labels.

OK. My plots are rather complicated, some up to 12 layers: 6 Geom.point and 6 Geom.line{ function}. As long as I can get the lines on top, that meet my purpose. Thanks for the PR. Hope it got fix and rollout soon.

It seems to work. Tried again with code below, after fresh Julia restart and clear Plot view.

using Gadfly, RDatasets
iris = dataset("datasets", "iris")

fs = [x->4.5*(1.0.-exp.(-1.5*(x-4))), x->0.3x+1, x->0.3x+1.1 ]
cs = ["a", "b", "c"]
dpalette(n::Int) = LCHuv.(65, 100, 15:(360/n):374)
#palette2 = ["deepskyblue","yellow3", "hotpink", "blue", "red", "green"]
palette2 = ["blue", "red", "green"]

plot(
    layer(iris, x=:SepalLength, y=:SepalWidth), #, color=:Species),
    layer(y=fs, xmin=[4.4], xmax=[8], Stat.func, Geom.line, order=2),
#    Scale.color_discrete_manual(dpalette(6)...)
    Scale.color_discrete_manual(palette2...),
    )


Gadfly_layers_order4

Solved. As the plots are created over loop, got to make conditional (if-else) palette based on color count. Sample below.

1 Like

Really nice figure! I like it. Can you also provide the code? Might be useful for people. Thanks!

@Balinus. Thanks. Actually, there is nothing fancy about the plot - just stack of plot layers. The one shown here comprises of 12 layers - six Geom.point and six Geom.line (function)). However, this is an expensive exercise for Gadfly. Luckily the data points are not that too many. The gist of this post is there is an issue with layer ordering for plot with mixed Geom.point and Geom.line, i.e. Geom.line got buried under Geom.point. @Mattriks showed a workaround, while waiting for the bug to be fixed.

The star2 are binning averages, with different color for different averaging method (Arithmetic, Geometric, Harmonic, etc.). The lines are curve fit bin averages.

1 Like

I merged the PR into master. You can use it now by doing

]add Gadfly#master

The plot from my first post above can be done as:

plot(iris,
    layer(x=:SepalLength, y=:SepalWidth, color=:Species),
    layer(fs, 4.4, 8, color=cs, order=2)
  )
1 Like