JuliaPlots / PlotlyJS.jl

Julia library for plotting with plotly.js
Other
420 stars 78 forks source link

Layout images lost in subplots #114

Open WibbletheDuck opened 7 years ago

WibbletheDuck commented 7 years ago

Hi,

I've learned that the Python interface to Plotly has the ability to import outside images as backgrounds, logos, overlays to plots, etc. I could really use this ability with some Julia code I'm working on, so I'm wondering if there's any chance this could be made accessible from Julia as well, or if I'm missing where the way to do so is documented.

Thanks!

sglyon commented 7 years ago

This should work in the same way. Here's what that example should look like in julia:

julia> using PlotlyJS

julia> trace1 = scatter(x=[0,0.5,1,2,2.2],y=[1.23,2.5,0.42,3,1]);

julia> layout = Layout(
       images=[attr(
       source="https://images.plot.ly/language-icons/api-home/python-logo.png",
       xref="x", yref="y", x=0, y=3, sizex=2, sizey=2, sizing="stretch",
       opacity=0.5, layer="below"
       )]
       )
layout with fields images and margin

julia> plot(trace1, layout) 

which results in

newplot

WibbletheDuck commented 7 years ago

Hmm, okay, I see what the problem was: I was trying to use it in a subplot, and it just silently fails to work there. I figured out I can use it in the joined figure's layout, but that makes sizing a real pain. Any chance of use of images in subplots being made to work?

sglyon commented 7 years ago

I see. I would be glad to have this feature in the library, but won't be able to implement it myself any time soon.

If you are interested in trying to add this, you should check out the file src/subplots.jl. I think we will have to do some custom code like what I have there for handling subplot titles in the handle_titles! function.

ericmsmythe commented 5 years ago

Thank you Spender for PlotlyJS :-)

Sorry for barging into this thread as it might not be the correct place. I am running out of time, trying to implement something, and on the verge of falling back to a less elegant solution.

With the examples at http://spencerlyon.com/PlotlyJS.jl/manipulating_plots/, it seems clear that once you introduce square brackets in the args to plot(), then only the Title of the Layout shows (and not the annotations and shapes) I need the square brackets for subplotting. So right now I cannot have subplotting and annotations

julia> typeof(plot_graphs)
Plot{GenericTrace{Dict{Symbol,Any}}}
julia> plot(plot_graphs) # this displays all Layout features

julia> plot( [plot_graphs] ) # this displays only the "Title" - alas

I also edited the example above by adding a Title and a Shape to the Layout object.

Then ran the following:

julia> plot([Plot(trace1), Plot(trace2, layout)] ) # multiplot and only the `Title` from the Layout shows

julia> plot(Plot(trace2, layout) ) # shows _all_ the Layout fetures including the python image and the `Shape`

Would very much appreciate some help.

sglyon commented 5 years ago

hi @ericmsmythe

There is some tricky work to be done to know how to properly place annotations and shapes within a chart that has subplots. For that reason, we intentionally decided not to include them.

however, this is doable if you get a little lower level and construct things more by hand. There are two options:

  1. Use the [] for subplots. Then after you have a chart with subplots you can go in and add annotations and shapes. An example would be
    p = [p1, p2]
    relayout!(p, shapes=[my_list_of_shapes...], annotations=[my_list_of_annotations...])
  2. Construct the subplots by hand using syntax like any of the ones in the example in the official javascript docs. For example, this plot could be created in Julia as follows:
using PlotlyJS
trace1 = scatter(x=1:3, y=2:4)
trace2 = scatter(x=20:10:40, y=[5,5,5], xaxis="x2", yaxis="y")
trace3 = scatter(x=2:4, y=200:100:800, xaxis="x", yaxis="y3")
trace4 = scatter(x=4000:1000:6000, y=7000:1000:9000, xaxis="x4", yaxis="y4")
data = [trace1, trace2, trace3, trace4]
layout = Layout(
    grid=attr(
        rows=2, columns=2, subplots=[["xy", "x2y"], ["xy3", "x4y4"]],
        roworder="bottom to top"
    )
)
plot(data, layout)

Notice that in this example you pass a single list of traces and a single layout -- plot is only called once. Also note that you would add your annotations and shapes when you construct the layout

Good luck!