Bokeh 链接散点图与 CDSView 源数据 - 'hover_color' 仅适用于图中的最后一个字形

Bokeh linked scatter charts with CDSView source data - 'hover_color' only works on the last glyph in figure

我正在链接两个散点图,它们具有与 Bokeh 源相同的基础 pandas 数据框。

我正在使用 CDS View 对数据进行切片。问题在于识别两个图表(链接刷)中数据点的悬停颜色(金色)仅适用于每个图中的最后一个字形,即黑色汽车。悬停时红点不会变成金色,只有黑点会 - 请看图片。

我发现如果我改变编码字形的顺序(即先是黑色然后是红色),那么红点会变成金色而不是黑色...我希望所有的点都变成金色悬停在两个图表上时,无论它们属于哪个字形。

我花了很多时间试图找到解决这个问题的方法,但没有成功。我对 Bokeh 比较陌生,可能错过了一些明显的东西。将不胜感激。

import pandas as pd
import bokeh.plotting as bk
from bokeh.models.sources import ColumnDataSource, CDSView
from bokeh.io import show
from bokeh.layouts import row
from bokeh.models.tools import HoverTool
from bokeh.models.filters import GroupFilter

data = {'Make':  ['Tesla', 'Honda', 'VW', 'Audi' ],
        'Color': ['black', 'black', 'red', 'red' ],
        'Price': [12, 23, 54, 78 ],
        'Hp': [64, 28, 12, 11 ],
        'Score': [125, 128, 112, 111 ],
        'Milage': [64, 228, 212, 211 ],
        'Origin': ['USA', 'Japan', 'Germany', 'Germany' ]}

df = pd.DataFrame (data, columns = ['Make','Color','Price','Hp', 'Score', 'Milage', 'Origin'])
source = ColumnDataSource(df)
   
view_red = CDSView(source=source, filters=[GroupFilter(column_name='Color', group='red')])
view_black = CDSView(source=source, filters=[GroupFilter(column_name='Color', group='black')])

#-----

TOOLS = 'box_select, pan, box_zoom, reset'
f1 = bk.figure(plot_width=400, plot_height=300, tools=TOOLS)

reds = f1.circle('Score', 'Price', fill_color="red", fill_alpha=1.0,
                 hover_color='gold', legend_label="red", 
                 size=15, view=view_red, source=source)
    
blacks = f1.hex('Score', 'Price', fill_color="black", fill_alpha=1.0,
                  hover_color='gold', legend_label="black", 
                  size=15, view=view_black, source=source)

hover = HoverTool(mode = 'mouse')
hover.tooltips = [('Make', '@Make'), ('Price', '@Price'), ('Color', '@Color')]
f1.add_tools(hover)

#-----

f2 = bk.figure(plot_width=400, plot_height=300, tools=TOOLS)

reds = f2.circle('Hp', 'Milage', fill_color="red", fill_alpha=1.0,
                 hover_color='gold', legend_label="red", 
                 size=15, view=view_red, source=source)
    
blacks = f2.hex('Hp', 'Milage', fill_color="black", fill_alpha=1.0,
                  hover_color='gold', legend_label="black", 
                  size=15, view=view_black, source=source)

hover = HoverTool(mode = 'mouse')
hover.tooltips = [('Hp', '@Hp'), ('Origin', '@Origin'), ('Color', '@Color')]
f2.add_tools(hover)

#-----

charts = row(children=[f1, f2])
show(charts)

为了完整性:这个简化的示例构成了一个更大的脚本的一部分,该脚本具有用于显示每个图表中的字形的按钮。谢谢

Reds dont turn gold

Blacks turn gold

Bokeh 的 Bryan 告知这是一个已知问题,并提供了一个解决方法,即使用不同的 CDS,即一个用于圆圈,一个用于六边形。缺点是数据会重复,但它解决了上面概述的问题。

import pandas as pd
import bokeh.plotting as bk
from bokeh.models.sources import ColumnDataSource, CDSView
from bokeh.io import show
from bokeh.layouts import row
from bokeh.models.tools import HoverTool
from bokeh.models.filters import GroupFilter

data = {'Make':  ['Tesla', 'Honda', 'VW', 'Audi' ],
        'Color': ['black', 'black', 'red', 'red' ],
        'Price': [12, 23, 54, 78 ],
        'Hp': [64, 28, 12, 11 ],
        'Score': [125, 128, 112, 111 ],
        'Milage': [64, 228, 212, 211 ],
        'Origin': ['USA', 'Japan', 'Germany', 'Germany' ]}

df = pd.DataFrame (data, columns = ['Make','Color','Price','Hp', 'Score', 'Milage', 'Origin'])
source = ColumnDataSource(df)
source2 = ColumnDataSource(df)
   
view_red = CDSView(source=source, filters=[GroupFilter(column_name='Color', group='red')])
view_black = CDSView(source=source2, filters=[GroupFilter(column_name='Color', group='black')])

#-----

TOOLS = 'box_select, pan, box_zoom, reset'
f1 = bk.figure(plot_width=400, plot_height=300, tools=TOOLS)

reds = f1.circle('Score', 'Price', fill_color="red", fill_alpha=1.0,
                 hover_color='gold', legend_label="red", 
                 size=15, view=view_red, source=source)
    
blacks = f1.hex('Score', 'Price', fill_color="black", fill_alpha=1.0,
                  hover_color='gold', legend_label="black", 
                  size=15, view=view_black, source=source2)

hover = HoverTool(mode = 'mouse')
hover.tooltips = [('Make', '@Make'), ('Price', '@Price'), ('Color', '@Color')]
f1.add_tools(hover)

#-----

f2 = bk.figure(plot_width=400, plot_height=300, tools=TOOLS)

reds = f2.circle('Hp', 'Milage', fill_color="red", fill_alpha=1.0,
                 hover_color='gold', legend_label="red", 
                 size=15, view=view_red, source=source)
    
blacks = f2.hex('Hp', 'Milage', fill_color="black", fill_alpha=1.0,
                  hover_color='gold', legend_label="black", 
                  size=15, view=view_black, source=source2)

hover = HoverTool(mode = 'mouse')
hover.tooltips = [('Hp', '@Hp'), ('Origin', '@Origin'), ('Color', '@Color')]
f2.add_tools(hover)

#-----

charts = row(children=[f1, f2])
show(charts)

可在此处找到有关此问题的更多信息:

https://discourse.bokeh.org/t/bokeh-linked-scatter-charts-with-cdsview-source-data-hover-color-only-works-on-the-last-glyph-in-figure/7603