Search code examples
pythonbokehholoviews

For looping overview with Holoview and Bokeh, theme is not taking effect


Trying to create multiple plots in a loop, using Holoview and Bokeh. The theme is taking effect in the first, single plot, case, yet being ignored in the second case. What is it that I am doing wrong?

import numpy as np
import pandas as pd
import holoviews as hv
from holoviews import dim, opts
from bokeh.palettes import Spectral6
import configparser
import hvplot.pandas
import json
from bokeh.plotting import figure, show
hv.extension('bokeh')

idx = pd.date_range("2021-01-01", periods=10, freq="H")
df = pd.DataFrame(np.random.randn(10, 4), columns=list('ABCD'), index=idx)

# First Case
dist_opts = opts.Curve(height=300, xrotation=45,  fontsize={'title': 10, 'labels': 10, 'xticks': 6, 'yticks': 8}, title = f"Title " )
hv.renderer('bokeh').theme = 'dark_minimal'
hline = hv.HLine(0)
hline_opts = opts.HLine(line_width=2, line_color='indianred', line_dash='dotted', line_alpha=0.9)
hdf = df.iloc[:,1].hvplot(legend=False,responsive=True)
overlay = hdf* hline
overlay.opts(dist_opts, hline_opts)
overlay

# Second Case
def set_plot(df):
    hline = hv.HLine(0)
    hline_opts = opts.HLine(line_width=2, line_color='indianred', line_dash='dotted', line_alpha=0.9)
    hdf = df.hvplot(legend=False,responsive=True)
    overlay = hdf* hline
    overlay.opts(dist_opts, hline_opts)
    return overlay

def show_plots(df):
    # hv.renderer('bokeh').theme = 'dark_minimal'
    plots_list = []
    for i in range(0,len(df.columns)):
        print(i)
        this_plot = set_plot(df.iloc[:,i])
        plots_list.append(this_plot)
    plot = hv.Layout(plots_list).cols(2)
    show(hv.render(plot))

show_plots(df)

Thanks


Solution

  • Holoviews automatically displays objects without the need to call show and it seems that has some bearing on things. The theme shows up if you code is changed to simply return the layout, rather than call show on it:

    def show_plots(df):
        hv.renderer('bokeh').theme = 'dark_minimal'
        plots_list = []
        for i in range(0,len(df.columns)):
            print(i)
            this_plot = set_plot(df.iloc[:,i])
            plots_list.append(this_plot)
        return hv.Layout(plots_list).cols(2)
    

    I'm not sure if this is intentional, or not. You might consider making an issue on the Holoviews issue tracker to clarify. It may be unavoidable, since show is a Bokeh function, and does not know anything about the theme that is set in Holoviews (which could explain why calling show does not take the HV setting into consideration).