Skip to content

ReactiveHTML: Enable me to provide bound functions to parameters #5476

Open
@MarcSkovMadsen

Description

@MarcSkovMadsen

I'm on the current main branch of Panel.

I'm trying to help in #5475 by creating a ReactiveHTML pane to wrap the lets-plot package.

I've now made a simple component that accepts a lets-plot PlotSpec. But now I want to give it a bound function that returns the PlotSpec.

I don't know how to do this as I've never seen an example. I think it should either be automatic or well documented.

import panel as pn
import param
from panel.reactive import ReactiveHTML

from lets_plot import __version__ as _lets_plot_version
from lets_plot.plot.core import PlotSpec

class LetsPlotPane(ReactiveHTML):
    object = param.ClassSelector(class_=PlotSpec, precedence=-1)

    _plot_spec_as_dict = param.Dict()


    _template = '<div id="pn-container" style="height:100%;width:100%"></div>'

    __javascript__ = [f"https://cdn.jsdelivr.net/gh/JetBrains/lets-plot@v{_lets_plot_version}/js-package/distr/lets-plot.min.js"]

    @pn.depends("object", watch=True, on_init=True)
    def _update_config(self):
        if not self.object:
            self._plot_spec_as_dict={}
        else:
            spec =self.object.as_dict()
            if "data" in spec and isinstance(spec["data"], pd.DataFrame):
                spec["data"]=spec["data"].to_dict(orient="list")

            self._plot_spec_as_dict=spec

    _scripts = {
        "render": "self._plot_spec_as_dict()",
        "_plot_spec_as_dict": """
LetsPlot.buildPlotFromProcessedSpecs(data._plot_spec_as_dict, -1, -1, pn_container);
"""
    }
    


from lets_plot import ggplot, geom_line, aes
import pandas as pd

pn.extension()

df = pd.DataFrame({
    'x': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'y': [2, 4, 1, 8, 5, 7, 6, 3, 9, 10],
})


def create_lets_plot(rng):
    p = (ggplot(df[:rng]) + geom_line(aes(x='x', y='y')))
    return p


plot = create_lets_plot(6)
plot._repr_html_()


slider = pn.widgets.IntSlider(name="range", value=5, start=0, end=len(df))
bound_plot = pn.bind(create_lets_plot, slider)
# bound_plot=LetsPlotPane(object=create_lets_plot(6), width=500, height=200)
pn.Column(slider, bound_plot).servable()

image

You make the bound_plot static by removing the # it displayes - but there is of course no interactivity.

image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions