PlotlyJS.jl icon indicating copy to clipboard operation
PlotlyJS.jl copied to clipboard

Shared axes?

Open jbrea opened this issue 7 years ago • 7 comments
trafficstars

Is it possible to generate subplots with shared axes like https://plot.ly/javascript/subplots/#subplots-with-shared-axes?

jbrea avatar Jan 10 '18 07:01 jbrea

Hi @jbrea it is definitely possible, though there isn't a "built in" way to do it yet.

The example you linked to would look like this in PlotlyJS.jl:

data =  [
    scatter(x=1:3, y=2:4),
    scatter(x=20:10:40, y=fill(5, 3), xaxis="x2", yaxis="y"),
    scatter(x=2:4, y=600:100:800, xaxis="x", yaxis="y3"),
    scatter(x=4000:1000:6000, y=7000:1000:9000, xaxis="x4", yaxis="y4")
]
layout = Layout(
    xaxis_domain=[0, 0.45],
    yaxis_domain=[0, 0.45],
    xaxis4=attr(domain=[0.55, 1.0], anchor="y4"),
    xaxis2_domain=[0.55, 1],
    yaxis3_domain=[0.55, 1],
    yaxis4=attr(domain=[0.55, 1], anchor="x4")    
)
plot(data, layout)

I think this would be a good addition to the library, the only question is what the API should look like.

One thing that could work would be to have a function

function share_axes!(l::Layout; rows::Vector{Int}=Int[], cols::Vector{Int}=Int[])
    # make sure `rows` and `cols` aren't both empty

    # for each row in rows, make all the subplots in that row share axes with left most subplot in that row

    # for each column in cols, make all subplots in that col share axes with bottom most subplot in that col

end

function share_axes!(p::Plot; rows::Vector{Int}=Int[], cols::Vector{Int}=Int[])
    share_axes!(p.layout, rows=rows, cols=cols)
end

function share_axes!(p::SyncPlot; rows::Vector{Int}=Int[], cols::Vector{Int}=Int[])
    share_axes!(p.plot, rows=rows, cols=cols)
end

Does that seem reasonable to you?

sglyon avatar Jan 10 '18 15:01 sglyon

Hi @sglyon

Thanks much for the quick response and the example!

I like your proposition for the extension of the API. However, I am not sure how to handle cases with multiple custom sized subplots, if you plan to also create an API for them. E.g. in https://plot.ly/javascript/subplots/#multiple-custom-sized-subplots it is not clear, if the bottom figure is in column 1 or 2.

As an alternative, what do you think about functions like

function share_xaxis!(plots::Vector{Plot})
# for each plot in plots share x-axis with plots[1]
end

jbrea avatar Jan 11 '18 14:01 jbrea

That's also a good idea. The one tricky thing is that a figure with multiple subplots will be just one Plot object... I need to think on that a bit more

sglyon avatar Jan 13 '18 03:01 sglyon

Ref. https://github.com/JuliaPlots/Plots.jl/issues/1371

cstjean avatar Feb 06 '18 11:02 cstjean

@sglyon any chance of an update? :) The example above is very helpful but my use-case is slightly different (I think?).

I am in a situation similar to subplots3(), in that I am generating many other plots, each with multiple traces. I'd like to be able to generate those plots, then combine any subset of them, then link all their x-axes. For example, in the subplots3() example, I sometimes might want only to plot 2 or 3 of the subplots, rather than all 4. But in all situations, I would like to be able to link the x-axis across all plots. Maybe this is already possible but I'm just having trouble with the syntax?

Either way, enjoying PlotlyJS so far! :)

kylecarbon avatar Sep 29 '18 19:09 kylecarbon

Hey @kylecarbon I haven't put more thought into this since the discussion fizzled out early this year.

Would the proposed API I had in the comment above with the share_axis! functions help in your case?

It is totally possible to do right now, but you would have to build the Layout object that does it by hand

sglyon avatar Sep 29 '18 21:09 sglyon

I think the share_axis! function would work just fine, as long as it handles all nested subplots (like you already mentioned above). That way, I can share the x-axis for all subplots, as well as plots in other windows.

I tried building the Layout object by hand but had trouble with it :/

kylecarbon avatar Sep 30 '18 04:09 kylecarbon