Gadfly: transparent histogram layers

All I want to do is plot two histograms on the same plot in layers and make them both transparent so I can see both at the same time. I can’t for the life of me figure out how to do this, I’ve tried many of the different Theme parameters. Anyone know? Thanks.

I believe Gadfly accepts RGBA style colors, so you could pass something like Color.RGBA(255, 255, 255, 0.1), where the last parameter control opacity

Feeding tuples to color arguments cause exceptions.

Sorry, wasn’t at computer. Meant something like this:

plot(layer(x=rand(10), y=rand(10), Geom.bar, Theme(default_color=Colors.RGBA(0,0,0, 0.4))),
     layer(x=rand(10), y=rand(10), Geom.bar, Theme(default_color=Colors.RGBA(255,0,255, 0.2))))

This is just a comment. It would be nice in Gadfly if one could use transparent colors with the color aesthetic. The following example would benefit if transparent colors could be used:

D1 = vcat([DataFrame(x=i+randn(200), g="μ=$i") for i in [0,2] ]...)  

coord = Coord.cartesian(xmin=-6, xmax=6)
p = plot(D1, x=:x, color=:g, coord,
    Stat.density(bandwidth=0.5), 
    Geom.polygon(fill=true, preserve_order=true),
)

fig3

Others will possibly think the same about my alternative but I find that Gadfly syntax awfully complicated and impossible to remember. With GMT you would do

x=collect(linspace(-3,3,50));
y=1/sqrt(2pi)*exp.(-x.^2);
plot(x,y,fmt="png",fill="red",alpha=50,limits=[-3 5 0 0.4])
plot!(x+2,y,fmt="png",fill="blue",alpha=50,show=1)

I am not saying this is superior to GMT or Gadfly (that Gadfly plot is really pretty AND the original question was about Gadfly) but if we are documenting how to do this in different plotting packages it could be instructive to show how to do it in StatPlots (currently only works on master). Plots is based on plotting user-defined objects, so you would load the distributions package and plot the Distributions.Normal object:

using StatPlots, Distributions 
plot([Normal() Normal(2)], fill = 0, alpha = 0.5)


I guess it would be easy to add transparency to the Gadfly call, the best option is probably to open a feature request issue on the repo.

4 Likes

This is possible in Gadfly, though it’s more unwieldy that perhaps it should be: some Gadfly methods (e.g. Scale.color_discrete_manual) take Colors rather than Colorants, which is a problem because

julia> typeof(RGB(0,0,1)) <: ColorTypes.Color
true
julia> typeof(RGBA(0,0,1,.5)) <: ColorTypes.Color
false

Anyway, the code snippet from Mattriks can be modified to produce transparent histograms:

mu_vals = [0,2]
D1 = vcat([DataFrame(x=i+randn(200), g="μ=$i") for i in mu_vals ]...)  

colors = [RGBA(0, .75, 1, .5), # gadfly default_color
	RGBA(.63, 0, .37, .5)]
coord = Coord.cartesian(xmin=-6, xmax=6)
p = plot(
	[layer(
		x = D1[:x][D1[:g] .== "μ=$(mu_vals[i])"],
		Stat.density(bandwidth=0.5), 
		Geom.polygon(fill=true, preserve_order=true),
		style(default_color = colors[i])
	)
	for i in [1,2]
	]...,
	coord
)


Notice that each layer is constructed separately, and for that layer we specify a default color with transparency.

Edit: the same works with Geom.histogram

Edit 2: that line where the histograms cross can be eliminated by adding line_width = 0mm to the style call.

Frankly my only complaint about Gadfly at the moment is that it seems really hard to do things like compose plots (one needs to add both layers, set colors and transparency, set a color key somehow). The other thing I like about Gadfly is that it is really easy to set the size (in pixels) of the output. The plots I make with Plots.jl always come out too small, and I find it hard to get them to look really nice (by the way @mkborregaard, which back-end was that done with? that looks better than mine usually do).

I’ve also found Plots.jl to be a bit buggy; I’ll post the crashes I have in their issues when I get around to doing MWE.

Yeah, complex Gadfly plots can get a bit verbose, which is a bit of a bummer. It doesn’t bother me too much since simple plots are simple and complex plots are rare, but some more concise syntax might be nice. I really like what you get in return though: the plot is exactly as you specify. (And outputs to beautiful .pdf or .svg).

I tried Plots.jl and really couldn’t get into it. I know it’s become something of the de facto standard, but the design philosophy just isn’t for me. As the Plots.jl readme says: Smart. Attempts to figure out what you want it to do... not just what you tell it. I don’t want my plotting package trying to outsmart me; I much prefer the ggplot/gadfly model of cleanly specifying how everything fits together.

2 Likes

Yeah, in practice 99% of all plots are histograms and scatter plots. To me the absolutely vital functionality is to have these with options for log scales, and the ability to easily compose them. The log scale functionality in Gadfly seems extremely robust (always seems to crash in Plots), but, as I’ve said, composing plots still seems like a huge chore.

I also really love UnicodePlots.jl and I have found it surprising how often these simple unicode plots are completely adequate, however, as far as I can tell that package does not allow for log scales, so I don’t use it much.

I use Gadly a lot and I found that using a lot of layers is the solution to most problems, it’s seem to be pretty fast too, you can have hundreds of layers without issues.

For me its worse limitation is plotting images, which is very slow. It might be possible to do some sort of hack via cairo though.

A few answers:

  1. Different plotting packages have different interfaces, and I think it’s clear that there isn’t a one interface that will make everybody happy. Ideally the interface should be decoupled from the engine, IMHO. Plots doesn’t try to outsmart you, though - you have control with everything if you specify it.
  2. The plot was made with the GR backend, which I believe is the most widely used one.
  3. I’ve not really experienced issues with log scales, but if you get them please do open an issue - I agree this should be robust and will receive high priority.
  4. Complex plots are uncommon in some fields but common in others.
  5. You set the plot size in pixels with the size keyword, e.g. size = (600,800)- but if it’s for resolution you should do savefig("myplot.svg") or savefig("myplot.pdf") to get the plot as a vector graphic.
  6. We much prefer specific issues to blanket statements “Plots is a bit buggy” :slight_smile: Though I will agree there could be improvements - we have 219 open issues, all of which are relevant.

Oh and by the way I definitely didn’t want to start a plotting-package-flame-war :slight_smile:

2 Likes

This is now easier in Gadfly 0.8.0, see this example.

2 Likes