Skip to content

State embedding not working depending on widget order in pn.Column #8368

@bertcoerver

Description

@bertcoerver

ALL software version info

(this library, plus any other relevant software, e.g. bokeh, python, notebook, OS, browser, etc should be added within the dropdown below.)

Software Version Info
holoviews==1.22.1
panel==1.8.4
param==2.3.1
python==3.14.2

Description of expected behavior and the observed behavior

I'm exporting a pn.Column to html and embedding the different states using .save(..., embed=True). When I put one of the widgets (called model) at the end of my pn.Column, half of the saved states are "empty" (I can also see that by setting embed_json=True), while if I put the same widget at the top of my pn.Column everything works as expected.

Complete, minimal, self-contained example code that reproduces the issue

import holoviews as hv
import panel as pn
import numpy as np
import pandas as pd
import param
hv.extension("bokeh")

dfs = list()
for model in ["etlook","tsebtp"]:
    for class_ in [1,2,3,4,5]:
        values = np.random.randn(np.random.randint(40, 80))
        dfs.append(pd.DataFrame({
            "idx": np.arange(values.size),
            "count": values,
            "model": model,
            "class": class_
        }))
df = pd.concat(dfs).set_index("idx")

class Test(param.Parameterized):

    #####
    ## DATA
    #####
    df: pd.DataFrame = param.DataFrame(
    )

    #####
    ## WIDGETS
    #####
    a: int = param.Integer(
        default=0, 
        softbounds=(0,10), 
        metadata={"widget_type": pn.widgets.IntSlider},
    )
    fn: str = param.Selector(
        default="sin", 
        objects=["sin", "cos", "tan"],
        metadata={"widget_type": pn.widgets.RadioButtonGroup},
    )
    model: str = param.Selector(
        default="model1", 
        objects=["model1", "model2"],
        metadata={"widget_type": pn.widgets.RadioButtonGroup},
    )
    
    #####
    ## PANES
    #####
    curves: hv.DynamicMap = param.ClassSelector(
        class_=hv.DynamicMap, 
    )

    def __init__(self, **params):

        super().__init__(**params)

        self.curves = hv.DynamicMap(
            self.make_curve,
            streams={
                "a": self.param["a"],
                "fn": self.param["fn"],
            },
        ).opts(
            hv.opts.Curve(framewise=True, responsive=True),
        )

        self.view: pn.Column = self.make_view()

    def add_section(self, hv_name):
        out = list()
        if hv_name in self.param:
            out.append(pn.pane.HoloViews(getattr(self, hv_name)))
        else:
            raise ValueError
        return out
    
    def add_widget(self, param_name):
        return pn.Param(
                self.param[param_name], 
                     widgets = {param_name: self.param[param_name].metadata
                     }
                    )

    def make_curve(self, a, fn):
        x = np.linspace(0, 10, 100)
        fn_ = getattr(np, fn)
        y = fn_(x*a)
        return hv.Curve((x,y)).redim(x="the bins")
    
    def make_view(self):

        # NOTE this works.
        # view: pn.layout = pn.Column(
        #     self.add_widget("model"),
        #     *self.add_section("curves"),
        #     self.add_widget("a"),
        #     self.add_widget("fn"),
        # )

        # NOTE this does not work.
        view: pn.layout = pn.Column(
            *self.add_section("curves"),
            self.add_widget("a"),
            self.add_widget("fn"),
            self.add_widget("model"),
        )

        return view

if __name__ == "__main__":

    self = Test(
        df=df
    )

    print(self.view)

    if False:
        pn.serve(self.view)
    else:
        self.view.save(
            "only_works_when_model_is_model2.html", 
            embed=True, 
            max_opts=50, 
            embed_json=False
        )

Stack traceback and/or browser JavaScript console output

Screenshots or screencasts of the bug in action

Screen.Recording.2026-01-08.at.10.48.12.mov

only_works_when_model_is_model2.html
this_works.html

  • I may be interested in making a pull request to address this

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions