Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Responsive sizing_mode does not work for plotly backend in HoloViews pane #6026

Open
MarcSkovMadsen opened this issue Dec 10, 2023 · 21 comments
Labels
type: discussion Requiring community discussion type: enhancement Minor feature or improvement to an existing feature
Milestone

Comments

@MarcSkovMadsen
Copy link
Collaborator

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()

image

Additional Information

The matplotlib and bokeh backends works.

@MarcSkovMadsen
Copy link
Collaborator Author

If there is a workaround I would really like to know it. Then I could get the chat app fully working.

@philippjfr
Copy link
Member

philippjfr commented Dec 14, 2023

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()

@philippjfr
Copy link
Member

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.

@philippjfr philippjfr added type: enhancement Minor feature or improvement to an existing feature type: discussion Requiring community discussion and removed type: bug labels Dec 14, 2023
@MarcSkovMadsen
Copy link
Collaborator Author

If you try the example, then something is wrong; The position of the tool icons

image

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

@philippjfr
Copy link
Member

Yep was looking at that this morning. It's missing our patched plotly.css file for some reason.

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 14, 2023

Does that also solve the fast "dark" mode issue. In dark mode the tool icons are also dark and cannot be seen.

@MarcSkovMadsen
Copy link
Collaborator Author

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()
not-working.mp4

@philippjfr
Copy link
Member

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.

@MarcSkovMadsen
Copy link
Collaborator Author

Workaround

If you use the below

hvplot.extension("plotly")
pn.extension('plotly')

Then it works

it-works.mp4

@MarcSkovMadsen
Copy link
Collaborator Author

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.

Hmmm. So user should combine hvplot and panel extension?

hvplot.extension("plotly")
pn.extension('plotly')

@philippjfr
Copy link
Member

philippjfr commented Dec 14, 2023

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.

@MarcSkovMadsen
Copy link
Collaborator Author

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')

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 14, 2023

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.

@philippjfr
Copy link
Member

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.

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 14, 2023

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.

@philippjfr
Copy link
Member

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.

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 14, 2023

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.

image

@philippjfr
Copy link
Member

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.

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 14, 2023

And setting plotly first and then bokeh is not a workaround.

does-not-work.mp4

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 14, 2023

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.

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 16, 2023

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.

@philippjfr philippjfr modified the milestones: next, v1.6.0 Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: discussion Requiring community discussion type: enhancement Minor feature or improvement to an existing feature
Projects
None yet
Development

No branches or pull requests

2 participants