Receive an error when trying to select data with Plotly

Hello

This is my first post here, so my apologies if I’m not thorough enough in my explanation.
I’ve recently started using Panel for my company to create a webapp that works together with a framework that has been developed within our team. I wanted to create an interface for it and tried to use the interactive option that panel allows in conjunction with a Plotly plot. As an example, to see if I could get it to work, I tried to just plot a single point and tried to select it with the selection tool of the plot. However I continuously receive an error. I’ll post the code and the log in the following lines.

import os, sys
import io
import numpy as np
import pandas as pd
import panel as pn
from panel.io import location as locat
import hvplot.pandas
from holoviews import streams

from sklearn.cluster import KMeans
from bokeh.sampledata import iris

import plotly.graph_objects as go
import plotly.express as px

import plotly.offline

framework_dir = (
    "C:/Users/dupon40/OneDrive - imec/Documents/GitHub/pv_simulation_framework_py/"
)
sys.path.insert(0, framework_dir)


from utils.process_rad_files import (
    rad_polygons_pts_from_file,
    parse_polygon_pts,
)
import holoviews as hv

pn.extension("plotly")
# hv.extension("bokeh")

def callback_file(*events):
    print(events)
    print("type: ", type(rad_loader.value))
    polygon_str = "polygon"
    bytes_io = io.BytesIO(rad_loader.value)
    polygon_file = io.TextIOWrapper(bytes_io)
    lines = polygon_file.readlines()
    i = 0
    while i < len(lines):
        if polygon_str in lines[i]:
            split_line = lines[i].split(" ")
            material_id = split_line[0]
            polygon_id = split_line[-1][:-1]
            poly_pts_list = []
            i = parse_polygon_pts(i + 1, lines, poly_pts_list)
            poly_pts_array = np.array(poly_pts_list)
            if material_id not in rad_polygons:
                rad_polygons[material_id] = {}
            rad_polygons[material_id][polygon_id] = poly_pts_array

        i = i + 1
    # reader = io.BufferedReader(rad_loader.value)
    polygons = np.array(list(list(rad_polygons.values())[0].values()))
    centroids = np.zeros((polygons.shape[0], 3))
    for poly_id in range(len(polygons)):
        centroids[poly_id] = np.mean(polygons[poly_id], axis=0)
    print(centroids)
    x = [[5.219394, 1.0021215, 2.7038575]]
    df = pd.DataFrame(
        {
            "x": centroids[:, 0],
            "y": centroids[:, 1],
        }
    )
    print(layout)
    fig = px.scatter(df, x="x", y="y")
    layout[1].object = fig
    print(layout)
    print(fig.layout)


# @pn.depends(plot_pane.param.selected_data, watch=True)
def callback_plot(*events):
    print("PASS")
    print(events)
    print(plot_pane)


flowers = iris.flowers.copy()
cols = list(flowers.columns)[:-1]

rad_loader = pn.widgets.FileInput(accept=".rad")
rad_polygons = {}
watcher = rad_loader.param.watch(callback_file, ["value"], onlychanged=False)

x = pn.widgets.Select(name="x", options=cols)
y = pn.widgets.Select(name="y", options=cols, value="sepal_width")
n_clusters = pn.widgets.IntSlider(name="n_clusters", start=1, end=5, value=3)

file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "temp.html"))


fig = px.scatter()
plot_pane = pn.pane.Plotly(fig)
watcher_2 = plot_pane.param.watch(callback_plot, "selected_data", onlychanged=False)

layout = pn.Row(
    pn.WidgetBox(
        "# Iris K-Means Clustering",
        pn.Column(
            rad_loader,
            x,
            y,
            n_clusters,
        ),
    ),
    plot_pane,
)
layout.servable(title="Portfolio Optimizer")

    [0] WidgetBox
        [0] Markdown(str)
        [1] Column
            [0] FileInput(accept='.rad', filename='single_cell.rad', mime_type='application/octet-stream'..., value=b'cell_front p...)
            [1] Select(name='x', options=['sepal_length', ...], value='sepal_length')
            [2] Select(name='y', options=['sepal_length', ...], value='sepal_width')
            [3] IntSlider(end=5, name='n_clusters', start=1, value=3)
    [1] Plotly(Figure, relayout_data={'autosize': True}, viewport={'xaxis.range': [-1, ...})       
2023-11-08 10:48:46,304 ERROR: panel.reactive - Callback failed for object named "Plotly00798" changing properties {'relayout_data': {'selections': [{'line': {'color': None,
                                            'dash': 'dot',
                                            'width': 1},
                                   'opacity': None,
                                   'type': 'rect',
                                   'x0': 5.056083814814814,
                                   'x1': 5.767194925925925,
                                   'xref': 'x',
                                   'y0': 1.2472827903225805,
                                   'y1': 0.5376053709677417,
                                   'yref': 'y'}]},
 'selected_data': {'points': [{'curveNumber': 0,
                               'pointIndex': 0,
                               'pointNumber': 0,
                               'x': 5.219393999999999,
                               'y': 1.0021214999999999}],
                   'range': {'x': [5.056083814814814, 5.767194925925925],
                             'y': [0.5376053709677417, 1.2472827903225805]}}}
Traceback (most recent call last):
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\panel\reactive.py", line 383, in _process_events
    self.param.update(**self_events)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 1902, in update
    self_._batch_call_watchers()
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 2063, in _batch_call_watchers
    self_._execute_watcher(watcher, events)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 2025, in _execute_watcher
    watcher.fn(*args, **kwargs)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 669, in caller
    return function()
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 407, in _depends
    return func(*args, **kw)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\panel\pane\plotly.py", line 192, in _update_figure_layout
    self._figure.plotly_relayout(relayout_data)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\plotly\basedatatypes.py", line 2601, in plotly_relayout
    relayout_changes = self._perform_plotly_relayout(relayout_data)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\plotly\basedatatypes.py", line 2637, in _perform_plotly_relayout
    raise ValueError(
ValueError:
Invalid property path 'selections' for layout

tornado.application - ERROR - Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x000001E788BF5A90>>, <Task finished name='Task-179' coro=<ServerSession.with_document_locked() done, defined at C:\Users\dupon40\Anaconda3_copy\lib\site-packages\bokeh\server\session.py:77> exception=ValueError("\nInvalid property path 'selections' for layout\n")>)
Traceback (most recent call last):
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\tornado\ioloop.py", line 741, in _run_callback
    ret = callback()
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\tornado\ioloop.py", line 765, in _discard_future_result
    future.result()
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\bokeh\server\session.py", line 98, in _needs_document_lock_wrapper
    result = await result
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\panel\reactive.py", line 428, in _change_coroutine
    state._handle_exception(e)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\panel\io\state.py", line 436, in _handle_exception
    raise exception
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\panel\reactive.py", line 426, in _change_coroutine
    self._change_event(doc)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\panel\reactive.py", line 444, in _change_event
    self._process_events(events)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\panel\reactive.py", line 383, in _process_events
    self.param.update(**self_events)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 1902, in update
    self_._batch_call_watchers()
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 2063, in _batch_call_watchers
    self_._execute_watcher(watcher, events)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 2025, in _execute_watcher
    watcher.fn(*args, **kwargs)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 669, in caller
    return function()
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\param\parameterized.py", line 407, in _depends
    return func(*args, **kw)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\panel\pane\plotly.py", line 192, in _update_figure_layout
    self._figure.plotly_relayout(relayout_data)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\plotly\basedatatypes.py", line 2601, in plotly_relayout
    relayout_changes = self._perform_plotly_relayout(relayout_data)
  File "C:\Users\dupon40\Anaconda3_copy\lib\site-packages\plotly\basedatatypes.py", line 2637, in _perform_plotly_relayout
    raise ValueError(
ValueError:
Invalid property path 'selections' for layout

Thank you for any help provided with this

Kind regards
Olivier Dupon