Responsive sizing_mode does not work for plotly backend in HoloViews pane
I'm on the main branch of Panel. I was trying to create a Chat with hvPlot application where users can specify the plotting backend they prefer in natural language. Unfortunately the plotly plot does not resize to the width and height of its container.
Its also an issue for me at work as many developers and users prefer the Plotly output. And they also prefer responsive sizing modes such that their apps works on big screens, laptop screens and when doing presentations.
import panel as pn
import hvplot.pandas
from bokeh.sampledata.penguins import data as df
pn.extension("plotly")
plot = df.hvplot.scatter(x='bill_length_mm', y='bill_depth_mm', by='species')
component = pn.Column(
pn.pane.HoloViews(plot, backend="plotly", sizing_mode="stretch_both"),
sizing_mode="stretch_both", styles={"background": "salmon"}
)
pn.template.FastListTemplate(
title="Paint It, Black",
main=[component],
).servable()
Additional Information
The matplotlib and bokeh backends works.
If there is a workaround I would really like to know it. Then I could get the chat app fully working.
You need to actually activate the plotly backend in hvPlot and use the responsive option:
import hvplot
import panel as pn
import hvplot.pandas
from bokeh.sampledata.penguins import data as df
hvplot.extension('plotly')
plot = df.hvplot.scatter(x='bill_length_mm', y='bill_depth_mm', by='species', responsive=True)
component = pn.Column(
pn.pane.HoloViews(plot, backend="plotly"), styles={"background": "salmon"}
)
pn.template.FastListTemplate(
title="Paint It, Black",
main=[component],
).servable()
Over all it is very hard for Panel to try to override settings applied to a plot that the user might have created. While it would be nice for pn.pane.HoloViews(..., sizing_mode='stretch_both') to override what the user specified when creating the plot it's not straightforward and it would be quite difficult to support robustly.
If you try the example, then something is wrong; The position of the tool icons
I don't see any errors in the browser console.
I'm on the current main branch of Panel using
plotly==5.18.0 bokeh==3.3.2 holoviews==1.18.1 hvplot==0.9.0
Yep was looking at that this morning. It's missing our patched plotly.css file for some reason.
Does that also solve the fast "dark" mode issue. In dark mode the tool icons are also dark and cannot be seen.
You need to actually activate the plotly backend in hvPlot and use the responsive option:
import hvplot import panel as pn import hvplot.pandas from bokeh.sampledata.penguins import data as df hvplot.extension('plotly') plot = df.hvplot.scatter(x='bill_length_mm', y='bill_depth_mm', by='species', responsive=True) component = pn.Column( pn.pane.HoloViews(plot, backend="plotly"), styles={"background": "salmon"} ) pn.template.FastListTemplate( title="Paint It, Black", main=[component], ).servable()
In this example you are cheating :-). You are using hvplot.extension("plotly"). If you are using pn.extension("plotly") then its not working.
import hvplot
import panel as pn
import hvplot.pandas
from bokeh.sampledata.penguins import data as df
pn.extension('plotly')
plot = df.hvplot.scatter(x='bill_length_mm', y='bill_depth_mm', responsive=True)
pane = pn.pane.HoloViews(plot, backend="bokeh", sizing_mode="stretch_both")
component = pn.Tabs(
pane, ("Hello", "Hello"), styles={"background": "salmon"}, sizing_mode="stretch_both"
)
def handle(_=None):
component[0]=pn.pane.HoloViews(plot, backend="plotly", sizing_mode="stretch_both")
update = pn.widgets.Button(name="Update", on_click=handle)
pn.template.FastListTemplate(
title="Paint It, Black",
sidebar=[update],
main=[component],
).servable()
https://github.com/holoviz/panel/assets/42288570/74d2aa23-3e9f-44fb-b1cd-bd936128fdd4
That is in no way cheating, it's following what the hvPlot docs tell you to do to use the Plotly backend: https://hvplot.holoviz.org/user_guide/Plotting_with_Plotly.html
Callingpn.extension('plotly') has no effect on what hvPlot does and should have no effect on what hvPlot does.
Workaround
If you use the below
hvplot.extension("plotly")
pn.extension('plotly')
Then it works
https://github.com/holoviz/panel/assets/42288570/52ed0099-2774-4e31-a5e0-c63851f7ccdf
That is in no way cheating, it's following what the hvPlot docs tell you to do to use the Plotly backend: https://hvplot.holoviz.org/user_guide/Plotting_with_Plotly.html
Calling
pn.extension('plotly')has no effect on what hvPlot does and should have no effect on what hvPlot does.
Hmmm. So user should combine hvplot and panel extension?
hvplot.extension("plotly")
pn.extension('plotly')
They certainly should not have to call the panel extension. What definitely has to happen is that hvPlot has to be told to render using plotly instead of the default which is bokeh, ideally that could be done without calling hvplot.extension, i.e. if that's not already possible you should be able to do something like df.hvplot.scatter(..., backend='plotly') or similar.
I do need to call pn.extension("plotly"). Otherwise I get
2023-12-14 13:00:45,048 PlotlyPlot was not imported on instantiation may not render in the served application. Ensure you add the following to the top of your application:
pn.extension('plotly')
Is the solution to document in the HoloViews reference guide that when using hvPlot and the plotly backend you will need to add both hvplot.extension("plotly") and pn.extension("plotly")?
It is not obvious. If you come from Streamlit, Gradio etc. backgrounds you don't have to do this kind of thing. Its done for you.
I do need to call pn.extension("plotly"). Otherwise I get
Cannot reproduce this.
It is not obvious. If you come from Streamlit, Gradio etc. backgrounds you don't have to do this kind of thing
I would argue this isn't true at all. hvPlot has an API and you have to correctly use that API to tell it to render with a backend other than the default (i.e. bokeh). The fact that hvplot.extension happens to share a name with pn.extension does not mean they do the same thing, perhaps for clarity it should be hvplot.set_backend('plotly') instead.
But I tell it (dynamically) in the HoloViews pane to use the plotly backend. I expected it to be controlled there. I would expect the HoloViews pane to tell hvPlot/ HoloViews everything it needs to render with the backend I specify. But it seems I need to control it twice.
But I tell it (dynamically) in the HoloViews pane to use the plotly backend. I expected it to be controlled there. I would expect the HoloViews pane to tell hvPlot/ HoloViews everything it needs to render with the backend I specify.
Unfortunately by that point it's too late, the problem is that hvPlot sets options only for the currently selected backend, which means that if you tell the plot to be responsive=True then that only applies to the Bokeh backend by default. This is a limitation of HoloViews and/or hvPlot, and could maybe be addressed there, e.g. we could decide to simply apply options for any plotting library that is loaded at execution time.
This is also demonstrates the problem I have. I would like to enable bokeh as my default renderer. But support dynamically changing to plotly and having stretch_width working.
But instead the hvplot renderer takes precedence to the backend of the HoloViews pane.
I thought we had an issue about this in hvPlot but it was probably closed when we implemented the backend support. I agree this is a significant point of friction and would help sell one of the core features of hvPlot.
And setting plotly first and then bokeh is not a workaround.
https://github.com/holoviz/panel/assets/42288570/ba34500d-419f-44e1-9954-e0620398aee2
Ok. I've added an issue to PANEL-CHAT-EXAMPLES that plotly plots don't stretch and I don't know how to solve the problem.
I can't see how to use hvplot.extension("plotly") solution because then that takes precedence over HoloViews pane backend setting.
The reference documentation for the HoloViews pane is also much more aligned with what I was trying to do
https://panel.holoviz.org/reference/panes/HoloViews.html#switching-backends
There is an example where its shown (indicated?) you can dynamically switch backends, but the example would never work as it does not add plotly neither to the pn.extension or some hvplot/ holoviews extension. And then there is the problem of responsive resizing too.
I believe this documentation should be fixed too. In general I would say the HoloViews reference notebook has not had the love it deserves. Everything about using hvPlot/ HoloViews plots with Panel should be clearly explained. Its the most expected use case.