Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't show figures toolbar on GridSpace #6127

Merged
merged 10 commits into from
Feb 23, 2024
Merged
3 changes: 1 addition & 2 deletions holoviews/plotting/bokeh/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,8 +614,7 @@ def initialize_plot(self, ranges=None, plots=None):
sync_legends(plot)
plot = self._make_axes(plot)
if hasattr(plot, "toolbar") and self.merge_tools:
plot.toolbar = merge_tools(plots)

plot.toolbar = merge_tools(plots, hide_toolbar=True)
title = self._get_title_div(self.keys[-1])
if title:
plot = Column(title, plot)
Expand Down
4 changes: 3 additions & 1 deletion holoviews/plotting/bokeh/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ def compute_layout_properties(
return aspect_info, dimension_info


def merge_tools(plot_grid, disambiguation_properties=None):
def merge_tools(plot_grid, *, disambiguation_properties=None, hide_toolbar=False):
"""
Merges tools defined on a grid of plots into a single toolbar.
All tools of the same type are merged unless they define one
Expand All @@ -397,6 +397,8 @@ def merge_tools(plot_grid, disambiguation_properties=None):
if isinstance(item, LayoutDOM):
for p in item.select(dict(type=Plot)):
tools.extend(p.toolbar.tools)
if hide_toolbar and hasattr(item, 'toolbar_location'):
item.toolbar_location = None
if isinstance(item, GridPlot):
item.toolbar_location = None

Expand Down
38 changes: 26 additions & 12 deletions holoviews/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
import sys
from collections.abc import Callable

import panel as pn
import pytest
from panel.tests.conftest import ( # noqa
from panel.tests.conftest import ( # noqa: F401
optional_markers,
port,
pytest_addoption,
pytest_configure,
server_cleanup,
)
from panel.tests.util import serve_and_wait

import holoviews as hv


def pytest_collection_modifyitems(config, items):
Expand All @@ -32,13 +36,15 @@ def pytest_collection_modifyitems(config, items):

with contextlib.suppress(ImportError):
import matplotlib as mpl
mpl.use('agg')

mpl.use("agg")


with contextlib.suppress(Exception):
# From Dask 2023.7,1 they now automatic convert strings
# https://docs.dask.org/en/stable/changelog.html#v2023-7-1
import dask

dask.config.set({"dataframe.convert-string": False})


Expand All @@ -49,40 +55,38 @@ def ibis_sqlite_backend():
except ImportError:
yield None
else:
ibis.set_backend('sqlite')
ibis.set_backend("sqlite")
yield
ibis.set_backend(None)


@pytest.fixture
def bokeh_backend():
import holoviews as hv
hv.renderer('bokeh')
hv.renderer("bokeh")
prev_backend = hv.Store.current_backend
hv.Store.current_backend = 'bokeh'
hv.Store.current_backend = "bokeh"
yield
hv.Store.current_backend = prev_backend


@pytest.fixture
def mpl_backend():
import holoviews as hv
hv.renderer('matplotlib')
hv.renderer("matplotlib")
prev_backend = hv.Store.current_backend
hv.Store.current_backend = 'matplotlib'
hv.Store.current_backend = "matplotlib"
yield
hv.Store.current_backend = prev_backend


@pytest.fixture
def plotly_backend():
import holoviews as hv
hv.renderer('plotly')
hv.renderer("plotly")
prev_backend = hv.Store.current_backend
hv.Store.current_backend = 'plotly'
hv.Store.current_backend = "plotly"
yield
hv.Store.current_backend = prev_backend


@pytest.fixture
def unimport(monkeypatch: pytest.MonkeyPatch) -> Callable[[str], None]:
"""
Expand All @@ -98,3 +102,13 @@ def unimport_module(modname: str) -> None:
monkeypatch.setattr(sys, "path", [])

return unimport_module


@pytest.fixture
def serve_hv(page, port): # noqa: F811
def serve_and_return_page(hv_obj):
serve_and_wait(pn.pane.HoloViews(hv_obj), port=port)
page.goto(f"http://localhost:{port}")
return page

return serve_and_return_page
8 changes: 8 additions & 0 deletions holoviews/tests/ui/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
try:
from playwright.sync_api import expect
except ImportError:
expect = None

from panel.tests.util import wait_until

__all__ = ("expect", "wait_until")
Empty file.
55 changes: 15 additions & 40 deletions holoviews/tests/ui/bokeh/test_callback.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import time

import numpy as np
import pytest

try:
from playwright.sync_api import expect
except ImportError:
pytestmark = pytest.mark.skip('playwright not available')

pytestmark = pytest.mark.ui

import panel as pn
from panel.pane.holoviews import HoloViews
from panel.tests.util import serve_and_wait, wait_until
import pytest

import holoviews as hv
from holoviews import Curve, DynamicMap, Scatter
from holoviews.streams import BoundsX, BoundsXY, BoundsY, Lasso, RangeXY

from .. import expect, wait_until

pytestmark = pytest.mark.ui


@pytest.mark.usefixtures("bokeh_backend")
@pytest.mark.parametrize(
Expand All @@ -28,18 +22,14 @@
(BoundsY, slice(1, None, 2), "boundsy"),
],
)
def test_box_select(page, port, BoundsTool, bound_slice, bound_attr):
def test_box_select(serve_hv, BoundsTool, bound_slice, bound_attr):
hv_scatter = Scatter([1, 2, 3]).opts(
tools=['box_select'], active_tools=['box_select']
)

bounds = BoundsTool(source=hv_scatter)

pn_scatter = HoloViews(hv_scatter)

serve_and_wait(pn_scatter, port=port)
page.goto(f"http://localhost:{port}")

page = serve_hv(hv_scatter)
hv_plot = page.locator('.bk-events')

expect(hv_plot).to_have_count(1)
Expand All @@ -57,18 +47,14 @@ def test_box_select(page, port, BoundsTool, bound_slice, bound_attr):


@pytest.mark.usefixtures("bokeh_backend")
def test_lasso_select(page, port):
def test_lasso_select(serve_hv):
hv_scatter = Scatter([1, 2, 3]).opts(
tools=['lasso_select'], active_tools=['lasso_select']
)

lasso = Lasso(source=hv_scatter)

pn_scatter = HoloViews(hv_scatter)

serve_and_wait(pn_scatter, port=port)
page.goto(f"http://localhost:{port}")

page = serve_hv(hv_scatter)
hv_plot = page.locator('.bk-events')

expect(hv_plot).to_have_count(1)
Expand Down Expand Up @@ -100,16 +86,12 @@ def test_lasso_select(page, port):
np.testing.assert_almost_equal(lasso.geometry, expected_array)

@pytest.mark.usefixtures("bokeh_backend")
def test_rangexy(page, port):
def test_rangexy(serve_hv):
hv_scatter = Scatter([1, 2, 3]).opts(active_tools=['box_zoom'])

rangexy = RangeXY(source=hv_scatter)

pn_scatter = HoloViews(hv_scatter)

serve_and_wait(pn_scatter, port=port)
page.goto(f"http://localhost:{port}")

page = serve_hv(hv_scatter)
hv_plot = page.locator('.bk-events')

expect(hv_plot).to_have_count(1)
Expand All @@ -127,19 +109,15 @@ def test_rangexy(page, port):
wait_until(lambda: rangexy.x_range == expected_xrange and rangexy.y_range == expected_yrange, page)

@pytest.mark.usefixtures("bokeh_backend")
def test_multi_axis_rangexy(page, port):
def test_multi_axis_rangexy(serve_hv):
c1 = Curve(np.arange(100).cumsum(), vdims='y')
c2 = Curve(-np.arange(100).cumsum(), vdims='y2')
s1 = RangeXY(source=c1)
s2 = RangeXY(source=c2)

overlay = (c1 * c2).opts(multi_y=True)

pn_scatter = HoloViews(overlay)

serve_and_wait(pn_scatter, port=port)
page.goto(f"http://localhost:{port}")

page = serve_hv(overlay)
hv_plot = page.locator('.bk-events')

expect(hv_plot).to_have_count(1)
Expand All @@ -163,7 +141,7 @@ def test_multi_axis_rangexy(page, port):


@pytest.mark.usefixtures("bokeh_backend")
def test_bind_trigger(page, port):
def test_bind_trigger(serve_hv):
# Regression test for https://github.com/holoviz/holoviews/issues/6013

BOUND_COUNT, RANGE_COUNT = [0], [0]
Expand All @@ -179,11 +157,8 @@ def range_function(x_range, y_range):

range_dmap = DynamicMap(range_function, streams=[hv.streams.RangeXY()])
bind_dmap = DynamicMap(pn.bind(bound_function))
widget = pn.pane.HoloViews(bind_dmap * range_dmap)

serve_and_wait(widget, port=port)
page.goto(f"http://localhost:{port}")

page = serve_hv(bind_dmap * range_dmap)
hv_plot = page.locator('.bk-events')
expect(hv_plot).to_have_count(1)

Expand Down
24 changes: 24 additions & 0 deletions holoviews/tests/ui/bokeh/test_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import numpy as np
import pytest

import holoviews as hv

from .. import expect

pytestmark = pytest.mark.ui


@pytest.mark.usefixtures("bokeh_backend")
def test_gridspace_toolbar(serve_hv):
def sine_curve(phase, freq):
xvals = [0.1 * i for i in range(100)]
return hv.Curve((xvals, [np.sin(phase + freq * x) for x in xvals]))

phases = [0, np.pi / 2, np.pi, 3 * np.pi / 2]
frequencies = [0.5, 0.75, 1.0, 1.25]
curve_dict_2D = {(p, f): sine_curve(p, f) for p in phases for f in frequencies}
gridspace = hv.GridSpace(curve_dict_2D, kdims=["phase", "frequency"])

page = serve_hv(gridspace)
bokeh_logo = page.locator(".bk-logo")
expect(bokeh_logo).to_have_count(1)
Loading