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