JuliaPlots / Plots.jl

Powerful convenience for Julia visualizations and data analysis
https://docs.juliaplots.org
Other
1.83k stars 354 forks source link

[FR] Allow setting width of plotly output in terms of percentages #4775

Open schlichtanders opened 1 year ago

schlichtanders commented 1 year ago

When using python, plotly defaults to setting width to 100% and height to 450px. This is very handy when using Pluto, so that the output of a cell is automatically mobile friendly.

When using Julia with plotly() backend there seems to be no way at all to specify the width in terms of percentages. For using Julia plotly backend on mobile it would be very beneficial if there is at least one way to make the width responsible.

EDIT: Here the link to the current code which hardcodes that the width is always in terms of px https://github.com/JuliaPlots/Plots.jl/blob/master/src/plot.jl#LL235C18-L235C18

plt.layout.bbox = BoundingBox(0mm, 0mm, w * px, h * px)
schlichtanders commented 1 year ago

I just found that plotsmeasures has a pct unit. So it is already kind of there.

EDIT: While layout bounding box can be set with the pct unit, it seems that plotly backend just uses the size attribute directly https://github.com/JuliaPlots/Plots.jl/blob/7a06de623b81ecde5f94e5e72d430cd9389ac96e/src/backends/plotly.jl#LL198C5-L198C5

and setting the size like size=(0.8pct, 450) does not work - the final html shows width=0.8pctpx which obviously just means that using pct in size is not supported

schlichtanders commented 1 year ago

Looking further into it, I cannot even construct a simple workaround, as plotly hardcodes the use of px at several places

schlichtanders commented 1 year ago

Found another level of complication:

EDIT: it seems the javascript has an undocumented option responsize (quite a magic name) which will automatically set the width to fit the maximum available width - like widht=100%, but using javscript internally. See https://github.com/plotly/plotly.js/issues/106#issuecomment-481400492

EDIT2: the reason why this option is not documented may be that the official documentions mentions an extra config for setting responsiveness: https://plotly.com/javascript/responsive-fluid-layout/

schlichtanders commented 1 year ago

Finally I came up with a hacky workaround function which I now use in Pluto notebooks

function plotly_responsive(plt)
    HTML(replace(
        Plots.embeddable_html(plt), 
        # delete extra outer style attribute - not needed at all
        r"style=\".*\"" => "",
        # delete layout width as this interfers with responsiveness 
        r"\"width\":[^,}]*" => "",
        # add extra config json at the end of the call to Plotly.newPlot
        ");" => ", {\"responsive\": true});"
    ))
end

It would be great if something less hacky with same functionality could be supported by Plots.jl

BeastyBlacksmith commented 1 year ago

loosely related to #1775

schlichtanders commented 1 year ago

Just experimented a bit further and realized that the margins and axis labels interfere badly with the responsiveness...