How to create a semi-pie chart with percentage?

I noticed a glitch when the semi-pie chart updates. Its because you put fip in as a function. It’s “slow” as it needs to determine the type of object and transfer a Plotly pane to the browser for each update. If you define a Plotly pane instead and just update the .object it works better.

I’ve created a parametrized example below. I just love the Parameterized api :slight_smile:

I tried to optimize for efficiency as described here https://panel.holoviz.org/reference/panes/Plotly.html but it is not totally clear to me if I did the “perfect” thing.

import time
import panel as pn
import param

pn.extension("plotly")

import plotly.graph_objects as go


class App(param.Parameterized):
    silu = param.Integer(default=0, bounds=(0, 1000))
    click_me = param.Action()
    view = param.Parameter()

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

        self.settings_pane = pn.Param(
            self,
            parameters=["silu", "click_me"],
            sizing_mode="fixed",
            height=400,
            width=300,
            background="lightgrey",
        )
        self.fig = self._get_figure()
        self.figure_pane = pn.pane.Plotly(self.fig, sizing_mode="stretch_width")
        self.view = pn.Column(
            pn.Row(self.settings_pane, self.figure_pane, sizing_mode="stretch_both"),
            sizing_mode="stretch_both",
        )

        self.click_me = self._click_me
        self._update_figure()

    def _get_figure(self):
        fig = go.Figure()
        fig.update_layout(
            grid={"rows": 1, "columns": 1, "pattern": "independent"},
            template={
                "data": {
                    "indicator": [
                        {
                            "title": {"text": "Speed"},
                            "mode": "number+delta+gauge",
                            "delta": {"reference": 90},
                        }
                    ]
                }
            },
        )
        return fig

    @param.depends("silu", watch=True)
    def _update_figure(self):
        self.fig.data=[]
        self.fig.add_trace(
            go.Indicator(
                value=20 * self.silu,
                delta={"reference": 160},
                gauge={"axis": {"visible": False}},
                domain={"row": 0, "column": 0},
            )
        )
        self.figure_pane.object = self.fig.to_dict()

    def _click_me(self, events):
        for i in range(10):
            if self.silu + 10 < 1000:
                self.silu += 10
            else:
                self.silu = 0
            print("value changed")
            time.sleep(0.33)


App().view.servable()

figure (1)