在 Bokeh 中使标记 fill_alpha 值依赖
make marker fill_alpha value-dependent in Bokeh
在 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']
正如您在问题中所述,您绝对可以使用自定义转换来实现这一点。绕过它们有点麻烦(在我看来),但希望这段代码能解决它。
基本上,您需要 3 个步骤来创建自定义 javascript 函数并将其应用于散景中的字段名称:
- 编写 javascript 实现所需转换的代码。在我们的例子中,我们只是将分类值映射到字典中的 alpha 级别。
- 将此 javascript 片段放入
CustomJSTransform
对象中,将必要的参数作为字典提供给它。在这种情况下,我在 python 中构建了 factor -> alpha
映射并将其传递给 javascript。我们使用了 vfunc
参数,因为我们想将此转换应用于数据中类别的每个实例。
- 在您对绘图函数的调用中
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)
在 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']
正如您在问题中所述,您绝对可以使用自定义转换来实现这一点。绕过它们有点麻烦(在我看来),但希望这段代码能解决它。
基本上,您需要 3 个步骤来创建自定义 javascript 函数并将其应用于散景中的字段名称:
- 编写 javascript 实现所需转换的代码。在我们的例子中,我们只是将分类值映射到字典中的 alpha 级别。
- 将此 javascript 片段放入
CustomJSTransform
对象中,将必要的参数作为字典提供给它。在这种情况下,我在 python 中构建了factor -> alpha
映射并将其传递给 javascript。我们使用了vfunc
参数,因为我们想将此转换应用于数据中类别的每个实例。 - 在您对绘图函数的调用中
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)