Skip to content

Correctly process ImageStack data for hover tooltips #13454

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

Merged
merged 1 commit into from
Oct 20, 2023

Conversation

ianthomas23
Copy link
Member

FIxes bug in ImageStack colormapping where we were modifying the user-supplied image data directly to deal with the color_baseline (user-specified or minimum of supplied data). The ImageStack rendered correctly but the hover tooltip was wrong. There was also a similar incorrect offset in color bar limits. This avoids changing the supplied image data and corrects the color bar limits. I have changed the existing tests which rather simplistically always had a minimum value of 0 so subtracting the minimum value had no effect.

The image produced by the example listed in the issue is now:
first

A more complicated example directly comparing Bokeh and Datashader doing the colormapping:

from bokeh.models import EqHistColorMapper, WeightedStackColorMapper
from bokeh.palettes import varying_alpha_palette
from bokeh.plotting import figure, row, show
import datashader.transfer_functions as tf
import numpy as np
import xarray as xr

n = 20
min_alpha = 40
color_baseline = None
colors = ["red", "green", "blue"]

def categorical_data():
    samples = 1000
    rng = np.random.default_rng(92478)

    centers = [(0.3, 0.3), (0.7, 0.5), (0.3, 0.7)]
    radii = [0.2, 0.3, 0.15]
    ncats = len(radii)

    dx = 1.0/n
    data = np.zeros((n, n, ncats), dtype=np.uint32)

    for k in range(ncats):
        x = rng.normal(centers[k][0], radii[k], samples)
        y = rng.normal(centers[k][1], radii[k], samples)
        i = (x / dx).astype(int)
        j = (y / dx).astype(int)
        for ii, jj in zip(i, j):
            if 0 <= ii < n and 0 <= jj < n:
                if np.isnan(data[jj, ii, k]):
                    data[jj, ii, k] = 1
                else:
                    data[jj, ii, k] += 1
    return data

data = categorical_data()
data += 5

ps = []
for i in range(2):
    title = "Bokeh" if i == 0 else "Datashader"
    kwargs = dict(width=420, height=350, title=f"Colormapping in {title}")
    kwargs["tooltips"] = [("values", "@image")]
    if i > 0:
        kwargs["x_range"] = ps[0].x_range
        kwargs["y_range"] = ps[0].y_range
        kwargs["width"] = 350
    p = figure(**kwargs)
    ps.append(p)

    if i == 0:  # Bokeh colormapping
        alpha_mapper = EqHistColorMapper(palette=varying_alpha_palette(color="#000", n=10, start_alpha=min_alpha))
        color_mapper = WeightedStackColorMapper(
            palette=colors, nan_color=(0, 0, 0, 0),
            alpha_mapper=alpha_mapper, color_baseline=color_baseline,
        )
        im = p.image_stack(image=[data], x=0, y=0, dw=1, dh=1, color_mapper=color_mapper)

        color_bar = im.construct_color_bar()
        p.add_layout(color_bar, "right")
    else:  # Datashader colormapping
        coords = np.arange(n, dtype=np.float64)
        cat = ["A", "B", "C"]  # <U1 "F" "M"
        da = xr.DataArray(data=data, dims=["y", "x", "cat"],
            coords=dict(x=coords, y=coords, cat=["A", "B", "C"]))
        im = tf.shade(
            da, color_key=colors, min_alpha=min_alpha,
            color_baseline=color_baseline,
        ).to_numpy()
        p.image_rgba(image=[im], x=0, y=0, dw=1, dh=1)

show(row(ps))

second

@ianthomas23 ianthomas23 added this to the 3.3.1 milestone Oct 17, 2023
@codecov
Copy link

codecov bot commented Oct 17, 2023

Codecov Report

Merging #13454 (ce87d74) into branch-3.4 (6022971) will not change coverage.
The diff coverage is n/a.

@@             Coverage Diff             @@
##           branch-3.4   #13454   +/-   ##
===========================================
  Coverage       92.67%   92.67%           
===========================================
  Files             320      320           
  Lines           20361    20361           
===========================================
  Hits            18869    18869           
  Misses           1492     1492           

@ianthomas23 ianthomas23 merged commit 0931768 into branch-3.4 Oct 20, 2023
@ianthomas23 ianthomas23 deleted the ianthomas23/13452_image_stack_tooltip_bug branch October 20, 2023 09:07
@bryevdv bryevdv mentioned this pull request Oct 24, 2023
@bryevdv bryevdv modified the milestones: 3.4, 3.3.1 Oct 31, 2023
Chiemezuo pushed a commit to Chiemezuo/bokeh that referenced this pull request Aug 27, 2024
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] ImageStack hover tooltip shows incorrect numbers
3 participants