This is a follow up to this discussion.
Is there, or perhaps should there be, a proper way to apply a bokeh theme to a plot in a pane? For the sake of clarity, I am working in a jupyterlab notebook.
I can get bokeh to show a themed object as follows:
from bokeh.io import curdoc, output_notebook, show from bokeh.plotting import figure from bokeh.themes import built_in_themes output_notebook() theme = built_in_themes["dark_minimal"] doc = curdoc() doc.theme = theme fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'] counts = [5, 3, 4, 2, 4, 6] p = figure(x_range=fruits, plot_height=250, title="Fruit counts", toolbar_location=None, tools="", align="center") p.vbar(x=fruits, top=counts, width=0.9) p.xgrid.grid_line_color = None p.y_range.start = 0 show(p)
Similarly for holoviews:
import holoviews as hv from holoviews import opts hv.extension("bokeh") hv.renderer('bokeh').theme = theme plot = hv.Bars((fruits, counts)) plot
But panel does not respect the bokeh theme:
import panel as pn pn.extension() pn.pane.Bokeh(p)
I also tried this unsuccessfully:
Although, the previously set holoviews theme is respected by panel:
A work around was provided in the same discussion mentioned above:
pn.viewable._Document.theme = theme pn.pane.Bokeh(p)
However, to quote the concerns mentioned in the discussion:
It works, but is ugly and involves accessing “private” attribute and making module-wide change
Digging around, I also noticed that
pn.io.save.file_html accepts a theme. And as a quick side note, while this renders fine:
from IPython.display import display, HTML from bokeh.resources import CDN html = pn.io.save.file_html(p, resources=CDN, theme=theme) HTML(html)
It does not render well with panel unless the height is manually specified:
In my imagination allowing
pn.pane.Bokeh to accept a theme parameter would make sense.
In short, is there a better way to apply a bokeh theme to a bokeh object in a panel bokeh pane?
Update while still typing this post… I tried this, and it worked:
import param from bokeh.themes import Theme from panel.pane.plot import Bokeh class ThemedBokeh(Bokeh): theme = param.ClassSelector(default=None, class_=(Theme, str), allow_None=True, doc=""" Bokeh theme to apply to the plot.""") def _get_model(self, doc, root=None, parent=None, comm=None): model = super()._get_model(doc, root=root, parent=parent, comm=comm) if self.theme: model._document.theme = self.theme return model
I think that really is a testament to how well structured this stack of technology is.
I don’t know if there are negative repercussions or potential side effects to this approach. If this is an appropriate approach, I’d be happy to submit a PR that either adds the theme parameter to the Bokeh pane class, or implements a ThemedBokeh class.
Any suggestions or feedback would be appreciated.