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

Update to bokeh 3 #2549

Merged
merged 1 commit into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ on:

env:
NUMBA_NUM_THREADS: 1
OMP_NUM_THREADS: 1
MKL_NUM_THREADS: 1
MPLBACKEND: Agg
PYTEST_ADDOPTS: --color=yes
GITHUB_PR_NUMBER: ${{ github.event.number }}
Expand Down
1 change: 1 addition & 0 deletions docs/changes/2549.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update bokeh dependency to version 3.x.
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ dependencies:
- pip
- astropy>=5.3,<7
- black
- bokeh=2
- bokeh=3
- nbsphinx
- cython
- graphviz
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ requires-python = ">=3.10"

dependencies = [
"astropy >=5.3,<7.0.0a0",
"bokeh ~=2.0",
"bokeh ~=3.0",
"docutils",
"eventio >=1.9.1, <2.0.0a0",
"iminuit >=2",
Expand Down
32 changes: 17 additions & 15 deletions src/ctapipe/visualization/bokeh.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
)
from bokeh.palettes import Greys256, Inferno256, Magma256, Viridis256, d3
from bokeh.plotting import figure
from bokeh.transform import transform
from matplotlib.colors import to_hex

from ..instrument import CameraGeometry, PixelShape
Expand Down Expand Up @@ -239,10 +240,10 @@ def norm(self, norm):
else:
raise ValueError(f"Unsupported norm {norm}")

self._color_mapper = norm(self.cmap)
self._color_mapper = norm(palette=self.cmap)
if self._patches is not None:
color = dict(transform=self._color_mapper)
self._patches.glyph.update(fill_color=color, line_color=color)
color = transform("values", self._color_mapper)
self._patches.glyph.update(fill_color=color)

if self._color_bar is not None:
self._color_bar.update(color_mapper=self._color_mapper)
Expand Down Expand Up @@ -373,7 +374,7 @@ def enable_pixel_picker(self, callback):
self.figure.add_tools(TapTool())
self.datasource.selected.on_change("indices", callback)

def highlight_pixels(self, pixels, color="g", linewidth=1, alpha=0.75):
def highlight_pixels(self, pixels, color="green", linewidth=1, alpha=0.75):
"""
Highlight the given pixels with a colored line around them

Expand All @@ -393,7 +394,7 @@ def highlight_pixels(self, pixels, color="g", linewidth=1, alpha=0.75):
n_pixels = self._geometry.n_pixels
pixels = np.asanyarray(pixels)

if pixels.dtype != np.bool:
if pixels.dtype != bool:
selected = np.zeros(n_pixels, dtype=bool)
selected[pixels] = True
pixels = selected
Expand Down Expand Up @@ -454,7 +455,6 @@ def add_ellipse(self, centroid, length, width, angle, asymmetry=0.0, **kwargs):
3rd-order moment for directionality if known
kwargs:
any MatPlotLib style arguments to pass to the Ellipse patch

"""
ellipse = Ellipse(
x=centroid[0],
Expand Down Expand Up @@ -585,6 +585,15 @@ def __init__(
frame_name = (frame or subarray.tel_coords.frame).__class__.__name__
title = f"{subarray.name} ({frame_name})"

# color by type if no value given
if values is None:
types = list({str(t) for t in subarray.telescope_types})
cmap = cmap or d3["Category10"][10][: len(types)]
field = "type"
else:
cmap = "inferno"
field = "values"

super().__init__(
use_notebook=use_notebook,
title=title,
Expand All @@ -595,15 +604,8 @@ def __init__(
**figure_kwargs,
)

# color by type if no value given
if values is None:
types = list({str(t) for t in subarray.telescope_types})
cmap = cmap or d3["Category10"][10][: len(types)]
self._color_mapper = CategoricalColorMapper(palette=cmap, factors=types)
field = "type"
else:
self.cmap = "inferno"
field = "values"

self.frame = frame
self.subarray = subarray
Expand All @@ -617,7 +619,7 @@ def __init__(
alpha=alpha,
)

color = dict(field=field, transform=self._color_mapper)
color = transform(field_name=field, transform=self._color_mapper)
self._patches = self.figure.circle(
x="x",
y="y",
Expand Down Expand Up @@ -687,7 +689,7 @@ def values(self, new_values):
if self._patches.glyph.fill_color["field"] == "type":
self.norm = "lin"
self.cmap = "inferno"
color = dict(field="values", transform=self._color_mapper)
color = transform(field_name="values", transform=self._color_mapper)
self._patches.glyph.update(fill_color=color, line_color=color)

# recreate color bar, updating does not work here
Expand Down
2 changes: 2 additions & 0 deletions src/ctapipe/visualization/tests/test_bokeh.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def test_camera_image(example_event, example_subarray, tmp_path):
display.image = np.random.normal(size=geom.n_pixels)
assert np.all(display.image == image)

display.highlight_pixels(display.image > 0)

output_path = tmp_path / "test.html"
output_file(output_path)
save(display.figure, filename=output_path)
Expand Down