Is there a way to make on_change callback receive arbitrary references

I was trying to implement a python module that would add a Datashading callback inspired on the DataShader Case Study in Python.

The callback function update_ds_image calls gen_ds_image which accesses iris_target_df. No issues with this as iris_target_df is in the notebooks scope.

My issue is if I have a class that has a data frame as an attribute (self._df). Iā€™m not able to use that data frame inside the callback function because it needs to have the callback signature similar to update_ds_image(layout, x_range, y_range, plot_width, plot_height).
I need to pass layout and Iā€™m not able to pass self and access the data frame.

Is there any way I can access objects out of the layout scope (and not in the global scope) from an on_change callback?

The only way I can make this work is adding the data frame reference to the module scope with globals()['df'] = self._df

Hi @neuronist,

If Iā€™m following you correctly, I think you could do this using functools.partial. This allows you to write the callback function with the extra dataframe argument, and then supply just that argument before providing the function to the on_callback method.

Something like

from functools import partial
...
def update_ds_image(df, layout, x_range, y_range, plot_width, plot_height):
    ...

f.layout.on_change(partial(update_ds_image, self._df), 'xaxis.range', 'yaxis.range', 'width', 'height')

Does that approach work for you?

-Jon

Hi @jmmease thank you very much it worked!

Note to self functools.partial is awesome and jmmease aswell! :slight_smile:

1 Like