holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.47k stars 489 forks source link

Access to Holoview Layouts setting common toolbar and shared_datasource #604

Open johnzzzzzzz opened 4 years ago

johnzzzzzzz commented 4 years ago

I have a Holoviews Layout that sets .opts.Layout(shared_datasource=True, toolbar="left"), but the Holoview's displayed_layout can't handle elements of different sizes.

I want Panel to change the displayed layout using pn.Rows and pn.Columns, but keep the common toolbar and shared_datasouce, implemented by Holoviews Layout.

When the Holoview's Layout is displayed in an pn.panel the display-layout is the same as when not using Panel. (yucky display-layout, but working common toolbar and shared_datasource)

When sub_elements of the Holoview layout are accessed and put into pn.Row and pn.Columns, pn.Row(hv_panel.object[1], hv_panel.object[2]), the display-layout is great, but each element has its own toolbar and selecting data does not work across elements.

Is there a way to relayout a Holoview Layout AND retain the Holoviews common features?

jbednar commented 4 years ago

That's a very timely question, because we just merged a PR that addresses at least some of those goals! Can you check https://github.com/pyviz/panel/pull/586 and see if it takes care of what you're after? Now's the time to speak up about it, before we make the release, so it's the right time to check it out...

johnzzzzzzz commented 4 years ago

I can supply a self contained test example. But I am not sure if I have the pattern right.

  1. Create a Holoviews layout object with multiple elements and the opts for shared data, shared axis, and common toolbar
  2. Wrap the hv_layout in a Panel.panel
  3. pull out the elements of the hv_layouts and rewrap them in rows and columns Or is there a better pattern that you are advocate?
philippjfr commented 4 years ago

Shared axes are now implemented. Shared data will be easy to implement but isn't yet. A shared toolbar should hopefully also be straightforward. I may also add a standard gridded layout in addition to the gridspec that's already there.

johnzzzzzzz commented 4 years ago

Here is self contained code that has all the features, I consider important for data brushing between multiple views of the same data model.

  1. Shared data table
  2. Time series plot (short and wide)
  3. Several scatter plots showing the correlation between columns
  4. Data Brushing between plots
  5. Linked Axes
  6. Common toolbar
  7. Dimming Legends
  8. Hovertool to show a row from the shared data
import pandas as pd, holoviews as hv, panel as pn, numpy as np
from bokeh.models import HoverTool
hv.extension('bokeh')
pn.extension()
# Define Data
df  = pd.DataFrame(np.random.randn(100, 3), columns=list('ABC')).cumsum()
df['date'] = pd.date_range('1/1/2000', periods=100)
# Define Hover Tool
tooltips = [('','@date{%F}'),
            ('A','@A{0,0.00}'),
            ('B', '@B{0,0.0}'),
            ('C', '@C{0,0}')]
formatters = dict(date='datetime',
                  A='numeral',
                  B='numeral',
                  C='numeral')
hover = HoverTool(tooltips=tooltips, formatters=formatters)
# Define Plots
ts_b = hv.Scatter(df, 'date', 'B', label='B')
ts_c = hv.Scatter(df, 'date', 'C', label='C')
ts = (ts_b * ts_c).opts(height=200, width=400, legend_position='top_right')
ab = hv.Points(df, ['A','B']).opts(height=200, width=200)
ac = hv.Points(df, ['A','C']).opts(height=200, width=200)
space = hv.Div('').options(height=1, width=1)
# Layout Plots using Holoviews
hv_layout = (ts + space + ab + ac).cols(2)
# Layout options to link plots for data brushing
hv_layout.opts(hv.opts.Scatter(tools=['box_select', 'lasso_select', 'tap', hover]),
               hv.opts.Points(tools=['box_select', 'lasso_select', 'tap', hover]),
               hv.opts.Layout(shared_datasource=True,
                              toolbar="left",
                              title = 'Example Holoviews Shared Data Layout'))
display(hv_layout)
# Relayout using panel
hv_panel = pn.panel(hv_layout)
pn_layout = pn.Column(
            pn.Row(hv_panel.object[0]),
            pn.Row(hv_panel.object[2], hv_panel.object[3]))
display(pn_layout)
vandhana12 commented 3 months ago

Hello @philippjfr , is there any update for the common toolbar?