How do I pass arguments to methods wrapped in panel.param.ParamMethod

I’d like to make an element (or multiple elements) of a dashboard by wrapping a parametrized method with arguments in panel.param.ParamMethod, but can’t figure out how to pass the arguments.
This snippet might get across what I am up to:

plot_settings = {"line": {"x": "x", "y": ["y"]}, "hist": {"kind": "hist", "y": ["y"]}}
# really to be loaded from json

class Foo(param.Parameterized):
    mean_y = param.Number(default=0)
    _df = param.Parameter(
        default=pd.DataFrame({"x": np.arange(10), "y": np.arange(10)})
    )

    @param.depends("mean_y", watch=True)
    def make_df(self):
        x = np.arange(10)
        y = np.random.rand(*x.shape) - 0.5 + self.mean_y
        self._df = pd.DataFrame({"x": x, "y": y})

    @param.depends("_df")
    def make_hvplot(self, settings={}):
        return self._df.hvplot(**settings)


foo = Foo()

myplots = [pn.param.ParamMethod(foo.make_hvplot, method_args=plot_settings[k]) for k in plot_settings]

row = pn.Column(
    pn.Param(foo, parameters=["mean_y"]),
    **myplots,
)
row

except, of course, ParamMethod doesn’t have the method_args argument that I’m looking for.
Any suggestions?

Could you move your plot_settings into your class?

Then it’s calling hvplot(self.settings)?

If I did that, how would I make the different elements in the dashboard that should be made by calling the method with different settings values simultaneously?

class Foo(param.Parameterized):
    mean_y = param.Number(default=0)
    settings = param.Dict()
    _df = param.Parameter(
        default=pd.DataFrame({"x": np.arange(10), "y": np.arange(10)})
    )

    @param.depends("mean_y", watch=True)
    def make_df(self):
        x = np.arange(10)
        y = np.random.rand(*x.shape) - 0.5 + self.mean_y
        self._df = pd.DataFrame({"x": x, "y": y})

    @param.depends("_df")
    def make_hvplot(self, settings={}):
        return self._df.hvplot(**settings)

foo1 = Foo(settings=plot_settings)
foo2 = Foo(settings=other_plot_settings)

Hmm, so then I’d need to make the method in foo2 depend on the _df parameter of foo1, because I need all plots to update when the data changes. This might be doable, but I’ll need to figure out how.

If it gets too complicated, perhaps this is not the right way forward. Instead, there might be a simpler approach like using hv.DynamicMap with a layout of your plots, but I don’t know the whole context.

Some examples:
https://pydeas.readthedocs.io/en/latest/holoviz_interactions/tips_and_tricks.html#Wrap-DynamicMap-around-Panel-methods-to-maintain-extents-and-improve-runtime

1 Like