python - 通过悬停在散景中突出显示多个 hex_tiles
问题描述
我尝试在十六进制地图中可视化我的数据。为此,我在图形类中使用了 python bokeh 和相应的 hex_tile 函数。我的数据属于 8 个不同类别之一,每个类别都有不同的颜色。下图显示了当前的可视化:
当鼠标悬停在元素上时,我想添加更改元素(以及理想情况下的所有类成员)颜色的可能性。
我知道,这有点可能,因为散景本身提供了以下示例: https ://docs.bokeh.org/en/latest/docs/gallery/hexbin.html
但是,我自己不知道如何实现(因为这似乎是 hexbin 函数的一个特性,而不是简单的 hex_tile 函数)
目前我在 ColumnDataSource 中提供我的数据:
source = ColumnDataSource(data=dict(
r=x_row,
q=y_col,
color=colors_array,
ipc_class=ipc_array
))
其中“ipc_class”描述了元素所属的 8 个类之一。对于鼠标悬停工具提示,我使用了以下代码:
TOOLTIPS = [
("index", "$index"),
("(r,q)", "(@r, @q)"),
("ipc_class", "@ipc_class")
]
然后我将所有内容可视化:
p = figure(plot_width=1600, plot_height=1000, title="Ipc to Hexes with colors", match_aspect=True,
tools="wheel_zoom,reset,pan", background_fill_color='#440154', tooltips=TOOLTIPS)
p.grid.visible = False
p.hex_tile('q', 'r', source=source, fill_color='color')
我希望可视化添加一个功能,将鼠标悬停在一个元素上将导致以下情况之一:1.通过更改其颜色突出显示当前元素 2.通过更改其悬停在同一类的多个元素上突出显示color 3.当元素悬停在hex_tile元素(或完整类)上时改变外线颜色
散景可以实现这些功能中的哪些功能,我将如何实现?
编辑:在尝试重新实施托尼的建议后,一旦我的鼠标点击图表,所有元素都会变成粉红色,并且颜色不会变回。我的代码如下所示:
source = ColumnDataSource(data=dict(
x=x_row,
y=y_col,
color=colors_array,
ipc_class=ipc_array
))
p = figure(plot_width=800, plot_height=800, title="Ipc to Square with colors", match_aspect=True,
tools="wheel_zoom,reset,pan", background_fill_color='#440154')
p.grid.visible = False
p.hex_tile('x', 'y', source=source, fill_color='color')
###################################
code = '''
for (i in cb_data.renderer.data_source.data['color'])
cb_data.renderer.data_source.data['color'][i] = colors[i];
if (cb_data.index.indices != null) {
hovered_index = cb_data.index.indices[0];
hovered_color = cb_data.renderer.data_source.data['color'][hovered_index];
for (i = 0; i < cb_data.renderer.data_source.data['color'].length; i++) {
if (cb_data.renderer.data_source.data['color'][i] == hovered_color)
cb_data.renderer.data_source.data['color'][i] = 'pink';
}
}
cb_data.renderer.data_source.change.emit();
'''
TOOLTIPS = [
("index", "$index"),
("(x,y)", "(@x, @y)"),
("ipc_class", "@ipc_class")
]
callback = CustomJS(args=dict(colors=colors), code=code)
hover = HoverTool(tooltips=TOOLTIPS, callback=callback)
p.add_tools(hover)
########################################
output_file("hexbin.html")
show(p)
基本上,我从图形功能中删除了工具提示并将它们放到悬停工具中。由于我的图表中已经有红色,我将悬停颜色替换为“粉红色”。由于我不太确定“代码”变量中的每一行应该做什么,我对此很无助。我认为一个错误可能是,我的 ColumnDataSource 看起来与 Tony 的有所不同,我不知道如何将第一个和第三个元素以及第二个和第四个元素一起“分类”。对我来说,如果分类由“ipc_class”变量完成,那将是完美的。
解决方案
继上一篇文章的讨论之后,这里出现了针对 OP 代码的解决方案(Bokeh v1.1.0)。我所做的是:
1)添加了一个悬停工具
2) 为 HoverTool 添加了一个 JS 回调:
- 将十六进制颜色重置为原始颜色(
colors_array
在回调中传递) - 检查当前悬停的十六进制 (
hovered_index
)的索引 - 获取
ip_class
当前悬停的十六进制 (hovered_ip_class
) - 遍历
data_source.data['ip_class']
并找到所有与ip_class
悬停的六边形相同的六边形并为其设置新颜色 (pink
) - 向 BokehJS发送
source.change.emit()
信号以更新模型
编码:
from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource, CustomJS, HoverTool
colors_array = ["green", "green", "blue", "blue"]
x_row = [0, 1, 2, 3]
y_col = [1, 1, 1, 1]
ipc_array = ['A', 'B', 'A', 'B']
source = ColumnDataSource(data = dict(
x = x_row,
y = y_col,
color = colors_array,
ipc_class = ipc_array
))
p = figure(plot_width = 800, plot_height = 800, title = "Ipc to Square with colors", match_aspect = True,
tools = "wheel_zoom,reset,pan", background_fill_color = '#440154')
p.grid.visible = False
p.hex_tile('x', 'y', source = source, fill_color = 'color')
###################################
code = '''
for (let i in cb_data.renderer.data_source.data['color'])
cb_data.renderer.data_source.data['color'][i] = colors[i];
if (cb_data.index.indices != null) {
const hovered_index = cb_data.index.indices[0];
const hovered_ipc_class = cb_data.renderer.data_source.data['ipc_class'][hovered_index];
for (let i = 0; i < cb_data.renderer.data_source.data['ipc_class'].length; i++) {
if (cb_data.renderer.data_source.data['ipc_class'][i] == hovered_ipc_class)
cb_data.renderer.data_source.data['color'][i] = 'pink';
}
}
cb_data.renderer.data_source.change.emit();
'''
TOOLTIPS = [
("index", "$index"),
("(x,y)", "(@x, @y)"),
("ipc_class", "@ipc_class")
]
callback = CustomJS(args = dict(ipc_array = ipc_array, colors = colors_array), code = code)
hover = HoverTool(tooltips = TOOLTIPS, callback = callback)
p.add_tools(hover)
########################################
output_file("hexbin.html")
show(p)
结果:
推荐阅读
- java - 如何在 Java 中抑制一个特定类中的错误
- python - 如何展平不规则的元组
- asp.net - 将身份验证从 api 传递到 api [net core]
- r - 只有在 R 中满足两个单独的条件时,是否有办法转换某些数据框列中的所有 NA
- spring - Spring Boot:如何配置一组实现注入?
- ruby-on-rails - Having trouble pulling an external api for use in my rails backend
- r - 将相同的密度曲线添加到 R 中的绘图
- python - 确定具有周期性条件的二维网格中的相邻单元格
- scheme - 为什么太阳系的这种数值积分会继续运行?(麻省理工学院方案 SCMUTILS)
- java - How to compute the total execution time in multithread application