使标记填充α值依赖于Bokeh

2024-05-14 02:53:10 发布

您现在位置:Python中文网/ 问答频道 /正文

在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']


Tags: fromimportalphafielddfbokehfigtransform
1条回答
网友
1楼 · 发布于 2024-05-14 02:53:10

正如您在问题中所述,您完全可以通过自定义转换来实现这一点。在我看来,这些代码有点麻烦,但希望这段代码能把它弄清楚

基本上,您需要三个步骤来创建自定义javascript函数并将其应用于bokeh中的字段名:

  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)

enter image description here

相关问题 更多 >