是否可以在图像上启用悬停工具(由image()
,image_rgba()
或image_url()
创建的字形),以便在将鼠标悬停在点上时显示一些上下文数据图片。在文档中,我发现只有线条或标记等字形的悬停工具的参考和示例。
可能的解决方法解决方案:
我认为可以将2d信号数据转换为具有x,y和值列的柱状Dataframe格式。并使用rect
字形而不是图像。但这也需要正确处理颜色映射。特别是,当值是实数而不是可以传递给某些调色板的整数时处理这种情况。
答案 0 :(得分:1)
好的,在深入研究文档和示例之后,我可能会自己回答这个问题。
悬浮对图像(2d信号)数据的影响对于如何在Bokeh中设计此功能没有任何意义。如果需要添加一些附加到数据点的额外信息,则需要将数据放入适当的数据模型 - 平面数据模型。
基本上,需要将他的数据整理成带有x,y和value列的表格格式(参见Tidy Data article by H.Wickham)。现在每行代表一个数据点,人们可以自然地将任何上下文信息添加为附加列。
例如,以下代码将完成工作:
def flatten(matrix: np.ndarray,
extent: Optional[Tuple[float, float, float, float]] = None,
round_digits: Optional[int] = 0) -> pd.DataFrame:
if extent is None:
extent = (0, matrix.shape[1], 0, matrix.shape[0])
x_min, x_max, y_min, y_max = extent
df = pd.DataFrame(data=matrix)\
.stack()\
.reset_index()\
.rename(columns={'level_0': 'y', 'level_1': 'x', 0: 'value'})
df.x = df.x / df.x.max() * (x_max - x_min) + x_min
df.y = df.y / df.y.max() * (y_max - y_min) + y_min
if round_digits is not None:
df = df.round({'x': round_digits, 'y': round_digits})
return df
rect
字形和ColumnDataSource
然后,使用rect
字形代替image
,相应地映射x,y,并将值列正确地映射到字形的颜色美学。
round
def InteractiveImage(img: pd.DataFrame,
x: str,
y: str,
value: str,
width: Optional[int] = None,
height: Optional[int] = None,
color_pallete: Optional[List[str]] = None,
tooltips: Optional[List[Tuple[str]]] = None) -> Figure:
"""
Notes
-----
both x and y should be sampled with a constant rate
Parameters
----------
img
x
Column name to map on x axis coordinates
y
Column name to map on y axis coordinates
value
Column name to map color on
width
Image width
height
Image height
color_pallete
Optional. Color map to use for values
tooltips
Optional.
Returns
-------
bokeh figure
"""
if tooltips is None:
tooltips = [
(value, '@' + value),
(x, '@' + x),
(y, '@' + y)
]
if color_pallete is None:
color_pallete = bokeh.palettes.viridis(50)
x_min, x_max = img[x].min(), img[x].max()
y_min, y_max = img[y].min(), img[y].max()
if width is None:
width = 500 if height is None else int(round((x_max - x_min) / (y_max - y_min) * height))
if height is None:
height = int(round((y_max - y_min) / (x_max - x_min) * width))
img['color'] = (img[value] - img[value].min()) / (img[value].max() - img[value].min()) * (len(color_pallete) - 1)
img['color'] = img['color'].round().map(lambda x: color_pallete[int(x)])
source = ColumnDataSource(data={col: img[col] for col in img.columns})
fig = figure(width=width,
height=height,
x_range=(x_min, x_max),
y_range=(y_min, y_max),
tools='pan,wheel_zoom,box_zoom,reset,hover,save')
def sampling_period(values: pd.Series) -> float:
# @TODO think about more clever way
return next(filter(lambda x: not pd.isnull(x) and 0 < x, values.diff().round(2).unique()))
x_unit = sampling_period(img[x])
y_unit = sampling_period(img[y])
fig.rect(x=x, y=y, width=x_unit, height=y_unit, color='color', line_color='color', source=source)
fig.select_one(HoverTool).tooltips = tooltips
return fig
####注意:但是这需要相当高的计算价格
答案 1 :(得分:1)
基于Alexander Reshytko的上述自我回答,我已经实现了一个大多数已经准备好下架的版本,并举了一些例子。修改它以适应您自己的应用程序应该更直接,并且不依赖于我真正使用或理解的Pandas数据帧。 Github: Bokeh - Image with HoverTool
上的代码和示例答案 2 :(得分:1)
Bokeh版本0.12.16支持HoverTool
image
的{{1}}。看到:
bokeh release 0.12.16
以下是我使用glyphs
将鼠标悬停在图片上并在其顶部添加一个隐藏(bokeh.plotting.image
)alpha=0
并具有悬停功能的方法数据坐标。我将它用于大约1500行和40000列的图像。
bokeh.plotting.quad
此处显示了选择{0}的最小值和最大值的功能的完整示例和图像:Utilities for interactive scientific plots using python, bokeh and javascript. 更新:最新散景已经支持# This is used for hover and taptool
imquad = p.quad(top=[y1], bottom=[y0], left=[x0], right=[x1],alpha=0)
color_mapper
个调色板,但是当我创建此代码时,我需要从matplotlib
生成它们
在显示的示例中,我决定不在cmap
函数中使用matplotlib.cm.get_cmap
在图像上显示工具提示。相反,我将它们显示在单独的tooltips=None
字形中。