0

在 Bokeh 中,是否可以让标记 alpha 随指定字段中的值而变化?

例如,要按字段改变颜色和标记:

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
from bokeh.transform import factor_cmap,factor_mark

df = some dataframe
palette = ['#440154', '#404387', '#29788E', '#22A784', '#79D151', '#FDE724']
bok_sym = ['circle','asterisk','square_x','circle_x','diamond','hex']
cat_lst = list(df['cat_field'].unique())

df_cds = ColumnDataSource(data=df)

fig = figure(some kwargs)
fig.scatter(x='x',y='y',
            source = df_cds,
            marker = factor_mark('cat_field',bok_sym,cat_lst)
            fill_color = factor_cmap('cat_field',palette,cat_lst),
           )
show(fig)

alpha 似乎没有类似的显式函数,但 bokeh.transform 确实提供了通用变换

https://docs.bokeh.org/en/latest/docs/reference/transform.html

我尝试添加以下内容:

from bokeh.transform import transform

alph_lst = [0.2,0.9,0.9,0.9,0.9,0.9]

fig.scatter(x='x',y='y',
                source = df_cds,
                marker = factor_mark('cat_field',bok_sym,cat_lst)
                fill_color = factor_cmap('cat_field',palette,cat_lst),
                fill_alpha = transform('cat_field',dict(zip(cat_lst,alph_lst))),
               )

但没有成功。

干杯

编辑:

我会注意到我已经(未成功)尝试将透明度作为十六进制代码的一部分传递:

调色板 = ['#44015433', '#404387E6', '#29788EE6', '#22A784E6', '#79D151E6', '#FDE724E6']

4

1 回答 1

0

正如您在问题中所说,您绝对可以通过自定义转换来实现这一点。它们有点麻烦(在我看来),但希望这段代码可以清除它。

本质上,您需要 3 个步骤来创建自定义 javascript 函数并将其应用于散景中的字段名称:

  1. 编写实现所需转换的 javascript 代码。在我们的例子中,我们只是将分类值映射到字典中的 alpha 级别。
  2. 将此 javascript 片段放入一个CustomJSTransform对象中,将必要的参数作为字典提供给它。在这种情况下,我在 python 中构建了factor -> alpha映射并将其传递给 javascript。我们使用该vfunc参数是因为我们想将此转换应用于数据中某个类别的每个实例。
  3. 在您调用 plot 函数时,p.scatter使用该transform函数将您指定的列名与您的自定义转换联系起来。在这种情况下alpha = transform("cat_field", categorical_alpha_transformer)
import pandas as pd
import numpy as np

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
from bokeh.transform import factor_cmap, factor_mark, transform
from bokeh.models.transforms import CustomJSTransform
from bokeh.io import output_notebook, show

output_notebook()

v_func  = """
var new_xs = new Array(xs.length)
for(var i = 0; i < xs.length; i++) {
    new_xs[i] = alpha_map[xs[i]]
}
return new_xs
"""

df = pd.DataFrame({
    "cat_field": list("abcdef"), 
    "x": list(range(6)), 
    "y": list(range(6)),
})

palette = ['#440154', '#404387', '#29788E', '#22A784', '#79D151', '#FDE724']
bok_sym = ['circle','asterisk','square_x','circle_x','diamond','hex']
alphas = [.1, .25, .4, .55, .7, .85, 1]
cat_lst = list(df['cat_field'].unique())

alpha_map = dict(zip(cat_lst, alphas)) # {"a": .1, "b": .25, ... "f": 1}
categorical_alpha_transformer = CustomJSTransform(args={"alpha_map": alpha_map}, v_func=v_func)


df_cds = ColumnDataSource(data=df)

fig = figure(width=250, height=250)
fig.scatter(
    x='x',
    y='y',
    source = df_cds,
    marker = factor_mark('cat_field', bok_sym, cat_lst),
    fill_color = factor_cmap('cat_field', palette, cat_lst),
    size=20,
    alpha = transform("cat_field", categorical_alpha_transformer)
    
)

show(fig)

在此处输入图像描述

于 2020-11-02T02:28:52.383 回答