Changing orientation of plots in gadfly

Sorry to reopen this issue, but I am trying to recreate this same plotting style in Gadfly as this issue Plotting histogram on the y-axis at the end of a time series. I have these two plots and want to plot side by side with the second plot being horizontal, however, unlike the previous issue I cannot just change the orientation of the histogram because I have a layer on it, I think I can achieve this by changing the orientation of the layer but I’m not sure how to do that.


tsteps = range(tspan[1], tspan[2], length = datasize)
GBM_Means = S₀.*exp.(r.*tsteps)
tsteps1 = tsteps[:,1]*30
GBM_Means = convert(Vector{Float32}, GBM_Means)
layer1 = Gadfly.layer(x = tsteps1,y = GBM_Means, Geom.line,linestyle=[:dash],color=[colorant"black"])
pa = Gadfly.layer(y_sort, x=Row.index, y=Col.value, color=Col.index, Geom.line)
plt1 = Gadfly.plot(layer1,pa,Guide.xlabel("Time"),Guide.ylabel("Stock Price"),Guide.yticks(ticks = [50 75 100 125 150 175]), Scale.ContinuousColorScale(p -> get(ColorSchemes.:YlOrBr_6, p)),Theme(key_label_font_size=6pt,major_label_font_size=7pt,key_position = :none),Guide.manual_color_key("", ["Neural SDE Stock Price Path","Mean"],["#FFA500","#000000"],pos=[0.05w,-0.45h],shape=[Gadfly.Shape.hline,Gadfly.Shape.hline]),Coord.cartesian(xmin=0, xmax=30, ymin=50, ymax=182))

and

lambda = -(4*0.08*exp(0.08))/(4*(1-exp(0.08)))*100
#LN = LogNormal(0.08,0.2)
LN = NoncentralChisq(1,lambda)*(-4(1-exp(0.08))/(4*0.08))
s =  40:0.005:200
s = s[:,1]
LNPDF = pdf.(LN,s)
layer1 = Gadfly.layer(x= s,y= LNPDF, ymin= zeros(size(LNPDF)), Theme(alphas=[0.3],default_color=colorant"black") , ymax= LNPDF, Geom.line ,Geom.ribbon)
p = Gadfly.plot(layer1)
plt = Gadfly.plot(layer1,x = y1,Guide.xlabel("Frequency"),Guide.ylabel(nothing),Theme(key_label_font_size=6pt,major_label_font_size=7pt,key_position = :none,default_color=colorant"orange"),Guide.manual_color_key("", ["Neural SDE Terminal Stock Price","Non-central Chi-squared Density Function"],["#FFA500","#000000"],pos=[0.6w,-0.45h],shape=[Gadfly.Shape.hline,Gadfly.Shape.hline]),xintercept=[m], Geom.vline(color=["black"],style=[:dash]),Geom.histogram(density=:true, bincount=20),Guide.xticks(ticks = [40 50 75 100 125 150 175 200]), Guide.xlabel(nothing))

I would like to plot these as stated in the question. Essentially I want it to look like this:

Also as a side question, is it possible to change the x-axis of the first plot to not use Row.index?

For the side plot, does this work for you? (just an example):


layer1 = layer(y=s, x=LNPDF, xmin=zeros(size(LNPDF)), Theme(alphas=[0.3], default_color=colorant"black") , xmax= LNPDF, Geom.line ,Geom.ribbon)
layer2 = layer(yintercept=[m], Geom.hline(color=["black"],style=[:dash]))
plt = plot(layer2, layer1,
    y=y1, Geom.histogram(density=true, bincount=20, orientation=:horizontal), 
    Guide.xlabel("Frequency"), Guide.ylabel(nothing),
    Theme(key_label_font_size=6pt, major_label_font_size=7pt, key_position=:none, default_color=colorant"orange"))

NcChisq

For your Row.index question, see the last example on the Gadfly docs Plotting page

1 Like

I get the following error message:

Couldn't process recipe args: (Vector{Layer}, Vector{Layer}, Gadfly.Geom.BarGeometry, Gadfly.Guide.XLabel, Gadfly.Guide.YLabel, Theme)

Plots.jl uses recipes, not Gadfly. Have you accidentally imported Plots, or another package you’re using?

1 Like

you are correct, sorry I was using both packages. I did what you suggested by switching the x and y axis and get this:


I think the problem is that Geom.line is connecting the points on the same x values.

Did you change xmin and xmax? I can’t diagnose the issue without seeing code.

I coped and pasted this code.
Here’s the full code:

prob1 = result3.u
u2 = repeat(reshape(S₀, :, 1), 1, 1000)
y = predict_neuralsde(prob1, u2)[1,:,:]'
y1 = y[end,:]
m = S₀.*exp.(r.*1)
y_sort = y[:, sortperm(y[end,:])];
m = m[1]
lambda = -(4*0.08*exp(0.08))/(4*(1-exp(0.08)))*100
LN = NoncentralChisq(1,lambda)*(-4(1-exp(0.08))/(4*0.08))
s =  40:0.005:200
s = s[:,1]
LNPDF = pdf.(LN,s)

layer1 = layer(y=s, x=LNPDF, xmin=zeros(size(LNPDF)), Theme(alphas=[0.3], default_color=colorant"black") , xmax= LNPDF, Geom.line ,Geom.ribbon)
layer2 = layer(yintercept=[m], Geom.hline(color=["black"],style=[:dash]))
plt = Gadfly.plot(layer2, layer1,
    y=y1, Geom.histogram(density=true, bincount=20, orientation=:horizontal), 
    Guide.xlabel("Frequency"), Guide.ylabel(nothing),
    Theme(key_label_font_size=6pt, major_label_font_size=7pt, key_position=:none, default_color=colorant"orange"))

What happens if you take out Geom.line?

It just displays the ribbon, not the outline of the distribution.

Try Geom.path in layer1, rather than Geom.line. The reason I don’t see the solid black lines is because I’m on Gadfly#master branch, which now has alpha for Geom.line (add alpha aesthetic to Geom.line by bjarthur · Pull Request #1603 · GiovineItalia/Gadfly.jl · GitHub)

1 Like

Works perfectly, thank you.

Now just finally on how to hstack the two plots while making this 2nd plot smaller as you showed in the previous issue. I used your exact code and got this error:

MethodError: no method matching (Array{Context})(::Int64, ::Int64)

Yes the empty Array constructor has changed. Probably easier to do now:

Array{Compose.Context}(undef, 1, 2)

So the following:

M = Array{Compose.Context}[]
M[1] = compose(context(0,0,2/3,1), render(plt1))
M[2] = compose(context(0,0,1/3,1), render(plt))
draw(PNG(6.6inch, 3.3inch), hstack(M...))

?

Becuase this results in the following error:

MethodError: Cannot `convert` an object of type 
  Context to an object of type 
  Array{Context}

It now creates the array but:

BoundsError: attempt to access 0-element Vector{Context} at index [1]

Edited it again!

1 Like

Works! Thank you so much for all the help!