How to unlink selectively plots that are automatically linked?

How to unlink selectively plots that are automatically linked?

Context

I am trying to make a panel with several plots, each consisting of subplots with shared axes.
Each plot is made from a separate dataframe:

    plot_1 = df_1.hvplot.scatter('X', 'Y', by='Z', subplots=True)
    plot_2 = df_2.hvplot.scatter('X', 'Y', by='V', subplots=True)

I want to keep the subplots in plot_1 linked (shared_axes=True), and likewise the subplots in plot_2, but get plot_1 unlinked from plot_2.

Eventually, I want to save the panel as a static html, so I need JS links.

I figured out that plot_1 and plot_2 are automatically linked because of identically named variables ‘X’ and ‘Y’. Thread how-to-only-link-share-only-the-x-axis and a comment on Holoviews issue #3678
suggest to rename the variables in the dataframes, but in my target use case it would be much cumbersome.

Attempted solution

I tried to unlink subplots in plot_1 and plot_2, and then explicitly relink them using holoviews.plotting.links.Link. This does not work, and ends up with exception thrown from holoviews.plotting.bokeh.plot().

Simple reproducer:

# %%
import pandas as pd
import numpy as np
import panel as pn
import holoviews as hv
import hvplot.pandas

from holoviews.plotting.links import Link

# %%
# Two dataframes that have nothing to do with each other,
# apart from having identical column names (X and Y)
len_1 = 50
df_1 = pd.DataFrame({
    'X': np.linspace(0, 10, len_1),
    'Y': np.random.random(len_1),
    'Z': np.random.choice(['A','B'], len_1)
})

len_2 = 20
df_2 = pd.DataFrame({
    'X': np.linspace(-1, 1, len_2),
    'Y': np.random.random(len_2),
    'V': np.random.choice(['C','D'], len_2)
})

# %%
# Make a plot from each dataframe, break automatic links
plot_1 = df_1.hvplot.scatter('X', 'Y', by='Z', subplots=True).opts(shared_axes=False)
plot_2 = df_2.hvplot.scatter('X', 'Y', by='V', subplots=True).opts(shared_axes=False)

# %%
# Re-link subplots
link_1 = Link(*plot_1.values())
link_2 = Link(*plot_2.values())
# %%
# Put the plots in one layout and export as a static html page
layout = pn.Column(plot_1, plot_2)
layout.save('layout.html')

The last step (layout.save) throws exception:

KeyError: <class 'holoviews.plotting.links.Link'>

Am I taking the wrong way?

Version info

holoviews 1.13.4
hvplot 0.6.0
bokeh 2.2.3
panel 0.10.1

1 Like