The below code allows you to edit the DataFrames and other parameters have that updated in the chart and table but I can’t find a way to capture the point clicks or holoviews Table changes and update the dataframe with these as well. Can anybody help?
import panel as pn
import param
import numpy as np
import holoviews as hv
from holoviews import opts
import random
hv.extension("bokeh")
pn.extension()
class CirclePoints(param.Parameterized):
df_circle_points = param.DataFrame(
pd.DataFrame(
{"x": [3, 2.6, -3.85, 0], "y": [2.6, -3, 1, 4], "z": [0.2, 0.4, 0.6, 0.8]}
)
)
df_circle_points_old = param.DataFrame(
pd.DataFrame(
{"x": [3, 2.6, -3.85, 0], "y": [2.6, -3, 1, 4], "z": [0.2, 0.4, 0.6, 0.8]}
)
)
radius = param.Number(4.0)
circle_centre_x = param.Number(0.0)
circle_centre_y = param.Number(0.0)
num_points = param.Integer(4, bounds=(0, 20))
@param.depends("df_circle_points", watch=True)
def points_change(self):
df_new = self.df_circle_points_old.merge(
self.df_circle_points, how="outer", indicator=True
).loc[lambda x: x["_merge"] == "right_only"]
print(df_new)
self.df_circle_points_old = self.df_circle_points.copy()
def table(self):
return hv.Table(self.df_circle_points, ["x", "y"], "z")
@param.depends("df_circle_points", "radius", "circle_centre_x", "circle_centre_y")
def view(self):
buffer = 0.2
hv_points = hv.Points(self.df_circle_points, vdims="z").redim.range(
x=(
min(np.min(self.df_circle_points.x), -self.radius) - buffer,
max(np.max(self.df_circle_points.x), self.radius) + buffer,
),
y=(
min(np.min(self.df_circle_points.y), -self.radius) - buffer,
max(np.max(self.df_circle_points.y), self.radius) + buffer,
),
)
point_stream = streams.PointDraw(
data=hv_points.columns(),
num_objects=self.num_points,
source=hv_points,
empty_value=0,
)
table = self.table()
DataLink(hv_points, table)
circle_and_points = (
hv_points
* hv.Ellipse(self.circle_centre_x, self.circle_centre_y, 2 * self.radius)
+ table
).opts(
opts.Layout(merge_tools=False),
opts.Points(
active_tools=["point_draw"],
color="z",
height=400,
size=10,
tools=["hover"],
width=400,
cmap="RdYlGn",
),
opts.Table(editable=True),
)
return circle_and_points
circle_pts = CirclePoints(name="Test")
pn.Column(pn.Row(circle_pts.param), pn.Row(circle_pts.view)).show()