panel icon indicating copy to clipboard operation
panel copied to clipboard

Plots are no longer linked after selecting something in a widget

Open nconsulting opened this issue 1 year ago • 2 comments

ALL software version info

Windows 11 Python 3.10.10 Panel 1.4.0 and 1.4.1 Start command: panel serve 'app\test_panel.py' --autoreload --show Tested with latest versions of Firefox and Chrome

Description of expected behavior and the observed behavior

When I start the app, I can zoom and pan in one plot and the other plot moves along. When I select something in the select widget (also happens with other widgets). The linked panning and zooming stops to work. When I reload the page, the panning and zooming works again, until I select something.

Complete, minimal, self-contained example code that reproduces the issue

import pandas as pd
import panel as pn
pn.extension(design="material", sizing_mode="stretch_width")

def plot1(select_widget = ""):
    d = {'x': [1, 2, 3, 4, 5], 'y': [3, 4, 8, 2, 10]}
    df = pd.DataFrame(data=d)

    plot = df.hvplot.scatter(x="x", y="y", grid=True, shared_axes=True, title="Plot 1", tools=['box_select'], xlabel="", ylabel="")

    return plot

def plot2(select_widget = ""):
    d = {'x': [1, 2, 3, 4, 5], 'y': [5, 1, 3, 0, 5]}
    df = pd.DataFrame(data=d)

    plot = df.hvplot.scatter(x="x", y="y", grid=True, shared_axes=True, title="Plot 2", tools=['box_select'], xlabel="", ylabel="")

    return plot


select_widget = pn.widgets.Select(name='Select', options=[1, 2, 3])

bound_plot1 = pn.bind(plot1, select_widget=select_widget)
bound_plot2 = pn.bind(plot2, select_widget=select_widget)

pn.template.FastListTemplate(
    site="Site",
    title="Title",
    sidebar=[select_widget],
    main=[bound_plot1, bound_plot2],
).servable()

nconsulting avatar Apr 11 '24 12:04 nconsulting

Try wrapping the pn.bind inside a hv.DynamicMap

import pandas as pd
import panel as pn
import hvplot.pandas
import holoviews as hv
pn.extension(design="material", sizing_mode="stretch_width")

def plot1(select_widget = ""):
    d = {'x': [1, 2, 3, 4, 5], 'y': [3, 4, 8, 2, 10]}
    df = pd.DataFrame(data=d)

    plot = df.hvplot.scatter(x="x", y="y", grid=True, shared_axes=True, title="Plot 1", tools=['box_select'], xlabel="", ylabel="")

    return plot

def plot2(select_widget = ""):
    d = {'x': [1, 2, 3, 4, 5], 'y': [5, 1, 3, 0, 5]}
    df = pd.DataFrame(data=d)

    plot = df.hvplot.scatter(x="x", y="y", grid=True, shared_axes=True, title="Plot 2", tools=['box_select'], xlabel="", ylabel="")

    return plot


select_widget = pn.widgets.Select(name='Select', options=[1, 2, 3])

bound_plot1 = hv.DynamicMap(pn.bind(plot1, select_widget=select_widget))
bound_plot2 = hv.DynamicMap(pn.bind(plot2, select_widget=select_widget))

pn.template.FastListTemplate(
    site="Site",
    title="Title",
    sidebar=[select_widget],
    main=[bound_plot1, bound_plot2],
).show()

I tested it and it's still linked after the fact.

image

(This will eventually be put in a best practices guide, but for now, there's a list here https://discourse.holoviz.org/t/personal-opinions-about-best-practices-for-panel-holoviews/6789)

ahuang11 avatar Apr 11 '24 17:04 ahuang11

Thank you for the tip! This works for a simple plot wrapped into pn.bind. But I have 2 simple plots and one more complicated plot. The complicated plot consists of 2 scatter plots and a dynamicmap on top of it:

(:Overlay
   .NdOverlay.I :NdOverlay   [id,manual]
      :Scatter   [timestamp]   (price,index,manual)
   .Scatter.I   :Scatter   [timestamp]   (price), :DynamicMap   [])

I'm unable to wrap that into a DynamicMap. I tried a few combinations trying to break up the complicated plot, but no luck so far.

nconsulting avatar Apr 12 '24 08:04 nconsulting