holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.62k stars 504 forks source link

Add (dark) theme support to HoloViews pane for Matplotlib and Plotly backends #6025

Open MarcSkovMadsen opened 9 months ago

MarcSkovMadsen commented 9 months ago

The HoloViews pane has a theme parameter. But this parameter only works for Bokeh plots.

Its just as natural to want other themes for Matplotlib and Plotly backends.

Personally I almost always use the Fast template. And many of my users prefer dark theme. Thus dark theme support would help me a lot.

The same when I demo the flexibility of hvPlot/ HoloViz ecosystem. then for me one of the main selling points is the many supported plotting backends. But its not really True if they are not well supported in Panel. For example in this example https://github.com/holoviz-topics/panel-chat-examples/pull/110 I would like to demonstrate the power of multiple backends. But since the HoloViews pane does not support dark theme, I abandoned that idea again.

Example

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"),
    pn.pane.HoloViews(plot, backend="matplotlib"),
)

pn.template.FastListTemplate(
    title="Paint It, Black",
    main=[component],
    theme="dark",
).servable()

I believe I should be able to use the named Matplotlib and Plotly themes like dark_background and plotly_dark. For example like pn.pane.HoloViews(plot, backend="plotly", theme='plotly_dark') or

pn.pane.HoloViews(plot, backend="plotly", theme={"plotly": "plotly_dark", "matplotlib": "dark_background"})

If that is too advanced then just a way to set some dark theme via for all backends via pn.pane.HoloViews(theme="dark", ...) would also be a big improvement.

Alternative Solutions

An alternative would be documenting how to change the default theme for Matplotlib or Plotly. That would also help a lot.

image

Plotly Workaround - Change the default theme

For Plotly you can change the default theme using

import plotly.io as pio
pio.templates.default = "plotly_dark"

image

There is a risk though that the dark theme will be used by a default/ light themed page. So this should probably be run just before setting or updating the object in the HoloViews pane. And the resetting to default right after.

Matplotlib Workaround - Change the default theme

You can change the default theme.

import matplotlib.pyplot as plt
plt.style.use('dark_background')

You will introduce some risk of another page renderering using dark_background when its a default/ light themed page.

MarcSkovMadsen commented 9 months ago

If someone can confirm that the workarounds are how we would like users to theme their matplotlib and plotly plots then I will add it to the documentation.

philippjfr commented 9 months ago

Seems like a great idea and doesn't sound super difficult to support.

philippjfr commented 9 months ago

I would not change the default though, ideally we'd use context managers like:

with plt.style.context('dark_background'):
    ... # HoloViews evaluation context
MarcSkovMadsen commented 9 months ago

It might be an idea to let the matplotlib renderer producere svgs. Insteads of png.

philippjfr commented 9 months ago

It might be an idea to let the matplotlib renderer producere svgs. Insteads of png.

It does already but I assume you mean changing the default? I'd agree with that.

philippjfr commented 9 months ago

There is some subtlety to that though, we should ensure that pcolormesh (and possibly imshow if that's not already true) are still rasterized so that we don't output gigantic SVG files for raster based plots.