Dynamic update of pn.Param object

I am streaming random data into a plotly bar plot. The stream is switched through a Toggle widget, defined through the params of a Parametrized class. Here the code:

import param

import numpy as np
import pandas as pd
import panel as pn
import plotly.graph_objects as go
import plotly.express as px
import seaborn as sns

from dataclasses import dataclass, field
from datetime import datetime

pn.extension("plotly", sizing_mode="stretch_width")

param_wdgt_dct = {"update_data": pn.widgets.Button, "toggle_stream":{"widget_type": pn.widgets.Toggle, "button_style": "outline", "button_type": "primary"}}

class PanelClass(param.Parameterized):
    num = param.Integer(default=1)
    df = param.DataFrame(precedence=-1, default=pd.DataFrame(np.zeros((7,4)), columns=list('ABCD')))

    update_data = param.Action(default=lambda x: x.param.trigger('update_data'))

    toggle_stream = param.Boolean(default=False)

    plot_output:pn.pane.Plotly

    stream_callback:pn.io.PeriodicCallback

    def __init__(self, **params):
        super().__init__(**params)

        self.update_df()
        fig, fig_patch = self.generate_figure()
        self.plot_output = pn.pane.Plotly(fig_patch)

        self.stream_callback = pn.state.add_periodic_callback(self.update_df, period= self.num * 1000, start=self.toggle_stream)

    def generate_figure(self):

        indo = self.df.index.to_series().apply(str).tolist()
        palette = sns.color_palette("hls", n_colors=len(indo)).as_hex()
        pal_dct = {kkk:vvv for kkk, vvv in enumerate(palette)}

        traccio = go.Bar(
                    x=self.df.A,
                    y=indo,
                    orientation='h',
                    marker_color=[pal_dct[int(eee)] for eee in indo],
                )

        fig = None
        # fig = go.Figure()
        # fig.add_trace(traccio)

        fig_patch = dict(data=[traccio], layout=go.Layout())

        return fig, fig_patch

    @param.depends("toggle_stream", watch=True)
    def start_streamo(self):
        self.stream_callback.running = self.toggle_stream

    @param.depends("update_data", watch=True)
    def update_df(self):
        self.df += pd.DataFrame(np.random.randint(0,10,size=(7, 4)), columns=list('ABCD'))
        self.df.sort_values("A", inplace=True)

    @param.depends("num", watch=True)
    def change_stream_pace(self):
        self.stream_callback.period = self.num * 1000

    @param.depends("df", watch=False)
    def view(self):

        tmp_arro = []

        tmp_arro.append(pn.pane.HTML(f"<h2>Last update:{datetime.now()}</h2>"))
        tmp_arro.append(self.df)

        fig, fig_patch = self.generate_figure()
        self.plot_output.object = fig_patch

        return pn.Column(*tmp_arro)


tmplt = pn.template.BootstrapTemplate()

insto = PanelClass(num=1)
insto_1 = PanelClass(num=5)

tmplt.sidebar.append(pn.Param(insto.param, widgets=param_wdgt_dct))
tmplt.sidebar.append(pn.Param(insto_1.param, widgets=param_wdgt_dct))

tmplt.main.append(pn.Row(insto.plot_output, insto_1.plot_output))
tmplt.main.append(pn.Row(insto.view, insto_1.view))

tmplt.servable()

It works already rather well, what I wanted to reach is about changing the Toggle button_type depending on its value, e.g. success if True and danger if False. What I tried is to define an instance element of the class called toggle_view, initialise it in the init method as a pn.Param from self.toggle_stream, and then display into an according layout. This way the Toggle widget is still related to the events of each self.toggle_stream. Then I tried to change its properties in the start_streamo method, but I have no idea how to access the widget properties, since it is somewhere into the pn.Param object.

Any suggestion how to do that?

in the end I solved defining the toggle_view directly from pn.widgets.Toggle.from_param:

import param

import numpy as np
import pandas as pd
import panel as pn
import plotly.graph_objects as go
import plotly.express as px
import seaborn as sns

from dataclasses import dataclass, field
from datetime import datetime

pn.extension("plotly", sizing_mode="stretch_width")

param_wdgt_dct = {"update_data": pn.widgets.Button, "toggle_stream":{"widget_type": pn.widgets.Toggle, "button_style": "outline", "button_type": "primary"}}

class PanelClass(param.Parameterized):
    num = param.Integer(default=1)
    df = param.DataFrame(precedence=-1, default=pd.DataFrame(np.zeros((7,4)), columns=list('ABCD')))

    update_data = param.Action(default=lambda x: x.param.trigger('update_data'))

    toggle_stream = param.Boolean(default=False)

    plot_output:pn.pane.Plotly

    stream_callback:pn.io.PeriodicCallback

    toggle_view:pn.widgets.Toggle

    def __init__(self, **params):
        super().__init__(**params)

        self.update_df()
        fig, fig_patch = self.generate_figure()
        self.plot_output = pn.pane.Plotly(fig_patch)

        self.stream_callback = pn.state.add_periodic_callback(self.update_df, period= self.num * 1000, start=self.toggle_stream)

        self.toggle_view = pn.widgets.Toggle.from_param(self.param.toggle_stream, button_style="outline", button_type=PanelClass.get_toggle_button_type(self.toggle_stream))

    def generate_figure(self):

        indo = self.df.index.to_series().apply(str).tolist()
        palette = sns.color_palette("hls", n_colors=len(indo)).as_hex()
        pal_dct = {kkk:vvv for kkk, vvv in enumerate(palette)}

        traccio = go.Bar(
                    x=self.df.A,
                    y=indo,
                    orientation='h',
                    marker_color=[pal_dct[int(eee)] for eee in indo],
                )

        fig = None
        # fig = go.Figure()
        # fig.add_trace(traccio)

        fig_patch = dict(data=[traccio], layout=go.Layout())

        return fig, fig_patch

    @staticmethod
    def get_toggle_button_type(inp_bool:bool):
        if inp_bool:
            return "success"
        else:
            return "danger"

    @param.depends("toggle_stream", watch=True)
    def start_streamo(self):
        self.stream_callback.running = self.toggle_stream
        self.toggle_view.button_type = PanelClass.get_toggle_button_type(self.toggle_stream)

    @param.depends("update_data", watch=True)
    def update_df(self):
        self.df += pd.DataFrame(np.random.randint(0,10,size=(7, 4)), columns=list('ABCD'))
        self.df.sort_values("A", inplace=True)

    @param.depends("num", watch=True)
    def change_stream_pace(self):
        self.stream_callback.period = self.num * 1000

    @param.depends("df", watch=False)
    def view(self):

        tmp_arro = []

        tmp_arro.append(pn.pane.HTML(f"<h2>Last update:{datetime.now()}</h2>"))
        tmp_arro.append(self.df)

        fig, fig_patch = self.generate_figure()
        self.plot_output.object = fig_patch

        return pn.Column(*tmp_arro)


tmplt = pn.template.BootstrapTemplate()

insto = PanelClass(num=1)
insto_1 = PanelClass(num=5)

tmplt.sidebar.append(pn.Param(insto.param, parameters=["num", "update_data"], widgets=param_wdgt_dct))
tmplt.sidebar.append(insto.toggle_view)
tmplt.sidebar.append(pn.Param(insto_1.param, parameters=["num", "update_data"], widgets=param_wdgt_dct))
tmplt.sidebar.append(insto_1.toggle_view)

tmplt.main.append(pn.Row(insto.plot_output, insto_1.plot_output))
tmplt.main.append(pn.Row(insto.view, insto_1.view))

tmplt.servable()

I have the desired result, but I still find interesting to know if there is a way to access what I wanted from a pn.Param .