1

我正在尝试将图像网格链接到散点图,以便在将鼠标悬停在相应图像上时突出显示正确的散点图点。

问题是当迭代注册 DOM 事件时,它们似乎被覆盖,因此只有散点图的最后一个点被突出显示。如何为每个图像注册独立事件。

请参阅下面的可重现示例。

在此处输入图像描述

import io
import random

import ipywidgets as ipw
from ipyevents import Event
import numpy as np
import PIL
from PIL import Image as PILImage
from bqplot import LinearScale, Figure, Axis, Scatter

# Random ipywidget image generator
def random_image():
    arr = np.random.randint(255, size=(200, 200, 3), dtype=np.uint8)
    img = PILImage.fromarray(arr)
    with io.BytesIO() as fileobj:
        img.save(fileobj, 'PNG')
        img_b = fileobj.getvalue()
    img_w = ipw.Image(value=img_b)
    return img_w

# Create data
data = [{'x': idx, 'y': random.randint(1,10), 'image': random_image()}
         for idx in range(1,6)]

# Create scatter plot
xs = LinearScale()
ys = LinearScale()
xa = Axis(scale=xs)                                                
ya = Axis(scale=ys, orientation='vertical')                        
points = Scatter(x=[d['x'] for d in data],                                    
                 y=[d['y'] for d in data],                                   
                 scales={'x': xs, 'y': ys})
highlighted_point = Scatter(x=[-1000], y=[-1000], # Dummy point out of view
                            scales={'x': xs, 'y': ys},
                            preserve_domain={'x': True, 'y': True},
                            colors=['red'])
fig = Figure(marks=[points, highlighted_point], axes=[xa,ya])

# Add DOM events to images
img_list = []
for d in data:
    img = d['image']
    event = Event(source=img, watched_events=['mouseenter'])
    def handle_event(event):
        highlighted_point.x = [d['x']]
        highlighted_point.y = [d['y']]
    event.on_dom_event(handle_event)
    img_list.append(img)
images = ipw.HBox(img_list)
ipw.VBox([fig, images])
4

1 回答 1

1

我找到了一种使用方法functools.partial

import functools

# Event handler
def handle_event(idx, event):
    highlighted_point.x = [data[idx]['x']]
    highlighted_point.y = [data[idx]['y']]

# Add DOM events to images
img_list = []
for idx, d in enumerate(data):
    img = d['image']
    event = Event(source=img, watched_events=['mouseenter'])
    event.on_dom_event(functools.partial(handle_event, idx))
    img_list.append(img)
images = ipw.HBox(img_list)
ipw.VBox([fig, images])
于 2021-06-10T10:22:10.707 回答