GiovineItalia / Gadfly.jl

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

Stack plots and align axes #1455

Open CiaranOMara opened 4 years ago

CiaranOMara commented 4 years ago

Is there a way to stack different types of plots and align their axes?

I'm trying to construct one column from something like the following.

Related: https://github.com/GiovineItalia/Gadfly.jl/issues/619, https://github.com/GiovineItalia/Gadfly.jl/issues/1169

Mattriks commented 4 years ago

Currently here's no automated way to do this. The easiest workaround would be to use Theme(plot_padding=[l, r, t, b]). See ?Theme

The main development of this feature would be done in Compose. E.g.

using Compose
ct1 = compose(context(0,0,1,1), fillopacity(0.0), 
#    (context(), rectangle(), stroke("silver")),
    (context(0,0, 0.9,0.2), rectangle(), stroke("orange")),
    (context(0,0.2, 1.0,0.8), rectangle(), stroke("blue"))
)

The design idea is to extract the layout from ct1, and apply the same layout (horizontally or vertically) to someother compose tree ct2.

CiaranOMara commented 4 years ago

In a vstack, it seems that the plot_padding would need to be adjusted for bottom halves with different heights.

I'm keen to try the compose route. In terms of laying out the receiving tree, is there a way to pin the width of a context and let its height be relative or does an aspect ratio need to be calculated in advance?

# Core plots.
M = rand(200, 100)
p1 = plot(Geom.line, x = collect(axes(M,2)), y = sum.(eachcol(M)))
p2 = spy(M, Guide.yticks(ticks=[], label=false))
# Context splicing.
r1  = render(p1)
r2  = render(p2)

table1 = r1.container_children.head.container_children.head.children
table2 = r2.container_children.head.container_children.head.children

ctx = compose(context(0,0,1,1), fillopacity(0.0),
    (context(0, 0,    1.0, 0.2), Compose.rectangle(), Compose.stroke("orange"), table1[7]), # WIP
    (context(0, 0.2, 1.0, 0.8), Compose.rectangle(), Compose.stroke("blue"), table2[1], table2[2]) # WIP
)
Mattriks commented 4 years ago

In the case of your plot above, yes I should have said use Theme(plot_padding= ) with vstack2 in #1169.

Same for my design idea, you would need to combine: extracting the layout, applying it to the other plot, and stacking the 2 plots, all in one function. The function should also allow you to manually adjust the layout in the non-aligned direction. Currently Gadfly plots don't store information about their absolute size (#1299), but adding knowledge of plot size to an individual plot also might be useful here.