bokeh / bokeh

Interactive Data Visualization in the browser, from Python
https://bokeh.org
BSD 3-Clause "New" or "Revised" License
19.39k stars 4.19k forks source link

[BUG] image_rgba selection #12207

Closed gmerritt123 closed 2 years ago

gmerritt123 commented 2 years ago

Software versions

Python version : 3.7.12 | packaged by conda-forge | (default, Oct 26 2021, 05:37:49) [MSC v.1916 64 bit (AMD64)] IPython version : 7.33.0 Tornado version : 6.1 Bokeh version : 2.4.3

node.js version : v17.9.0 npm version : 8.5.5 Operating system : Windows-10-10.0.19041-SP0

Browser name and version

No response

Jupyter notebook / Jupyter Lab version

No response

Expected behavior

Instantiating an image_rgba glyph containing multiple images with the aim of selecting individual "whole images" (i.e. indices in the CDS) using a TapTool does not work:

As per @bryevdv via discourse:

 p.image_rgba(image='img', x='x', y='y', dw='dw', dh='dh', source=source,

             # just this, like any other glyph
             nonselection_alpha=0.2)

The above does fails.

I made a workaround attempt at making a Quad glyph running off the same CDS as the image_rgba, thinking that the user could select the Quads instead (see example code along with gifs).

Observed behavior

Now what’s failing seems to be a graphical bug of some sort. If I don’t render the image, I can select the quad glyph no problem:

works

But if I turn on the image_rgba line of code --> See the console error in the gif here:

doesnt

Example code

import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS, Quad, CustomJSTransform,TapTool

#create a bunch of image rgbas
names = ['image1','image2','image3']
xs = [0,40,80]
ys = [0,50,100]
widths = [10,30,40]
heights= [15,24,40]
images = []
for im in range(len(xs)):
    N = 20
    img = np.empty((N,N), dtype=np.uint32)
    view = img.view(dtype=np.uint8).reshape((N, N, 4))
    for i in range(N):
        for j in range(N):
            view[i, j, 0] = int(i/N*255)
            view[i, j, 1] = 158
            view[i, j, 2] = int(j/N*255)
            view[i, j, 3] = 255
    images.append(img)

p = figure()

src = ColumnDataSource(data = {'x':xs,'y':ys,'widths':widths
                               ,'heights':heights,'img':images
                               ,'names':names})

#point image to src
#TapTool/Selection glyph fails when image is added
# imrend = p.image_rgba(image='img', x='x', y='y', dw='widths', dh='heights',source=src)
# imrend.level='underlay' #tried playing with this, didn't change anything

#also drive a quad glyph off the same source with some CustomJSTransforms
# Quad takes left, right, bottom and top args, while image_rgba basically takes left, bottom, height and width
#we can calculate the right and top args using the left, bottom, height and width fields "on the fly"
wTransform = CustomJSTransform(args=dict(src=src)
                               ,v_func='''return xs.map((x,i)=>x+src.data['widths'][i])''') #used to add width to every x (for calculating the right)
hTransform = CustomJSTransform(args=dict(src=src)
                               ,v_func='''return xs.map((y,i)=>y+src.data['heights'][i])''') #used to add height to every y (for calculating the top)
#create the quad glyph using these transforms
qglyph = Quad(left='x', bottom='y', right={'field':'x','transform':wTransform}
                                   , top={'field':'y','transform':hTransform}
                                  ,fill_alpha=0.1,line_alpha=0)
#same thing but make a selection glyph 
qsglyph = Quad(left='x', bottom='y', right={'field':'x','transform':wTransform}
                                   , top={'field':'y','transform':hTransform}
                                  ,fill_alpha=0.2,line_alpha=.5,fill_color='red')
qrend = p.add_glyph(source_or_glyph=src,glyph=qglyph,selection_glyph=qsglyph)

tap_tool = TapTool(renderers=[qrend])
p.add_tools(tap_tool)

show(p)

Stack traceback or browser console output

No response

Screenshots

Relevant discourse thread:

https://discourse.bokeh.org/t/how-to-define-the-tap-selection-on-the-image-when-the-image-is-plotted-by-image-rgba/9330/2

github-actions[bot] commented 1 month ago

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