Hi,
I’m trying to create a simple rectangle annotator, that works under servable Panel environment and allows the user to annotate initial list of rectangles and offers option to add new ones.
Based on the documentation example, I created the following minimal code:
import holoviews as hv
import panel as pn
hv.extension('bokeh')
initial_data = {"x0": [1, 2], "y0": [4, 5], "x1": [7, 6], "y1": [2, 9],
"Label": ["abc", "def"], "Color": ["red", "yellow"]}
boxes = hv.Rectangles(initial_data).opts(color="Color")
box_annotator = hv.annotate.instance()
annotator_layout = box_annotator(boxes.opts(width=800, height=400, fill_alpha=0.5, responsive=False),
annotations={'Label': str, 'Color': str})
button = pn.widgets.Button(name='Get data', button_type='primary')
def on_click(event):
df = box_annotator.annotated.dframe()
print(df)
button.on_click(on_click)
layout1 = pn.Column(annotator_layout, button)
layout1.servable()
if __name__ == "__main__":
layout1.show()
The code runs, shows two rectangles and a table + button to get the data back. Now, if I go to the table and directly try to update the Label (important: without touching the plot widget first), the on_click handler prints incorrect data. Namely, if I enter label text longer than the text coming from initial_data (e.g. replace “abc” with “bokeh”), the printed data frame will have only 3 characters of label - i.e. only “bok”.
x0 y0 x1 y1 Label Color
0 1.0 2.0 7.0 4.0 bok red
1 2.0 5.0 6.0 9.0 def yellow
Now, the things get interesting. If I go to the plot, activate the BoxEdit tool and draw a new rectangle, then the data frame will start to look correct and contain full labels.
If I run the same code in Jupyter (reading box_annotator.annotated.dframe() in a separate cell instead of using a button), the updates work fine.
Do you have any idea what I’m doing wrong in the Panel environment?
And also extra question: is there any way that the editable “Color” column can be linked to the color property of rectangles? Changing color from there does not trigger plot updates.