python - 在 Bokeh 中更新 ColorBar

标签 python python-3.x bokeh

我正在尝试更新 Bokeh 中的 ColorBar,但标题和颜色本身都不会更新。这是一个最小的功能示例(Python 3.6.9、Bokeh 2.3.0、Tornado 6.1):

from bokeh.plotting import figure, curdoc
from bokeh.colors import HSL
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, LinearColorMapper, ColorBar, Select
import numpy as np

def colorize(data,reverse=False):
    if reverse:
        return [HSL(h-180,1.0,0.5).to_rgb() for h in data]
    else:
        return [HSL(h,1.0,0.5).to_rgb() for h in data]

def update(attr,old,new):
    if menu.value == 'reverse':
        y = -1 * x
        c = colorize(x,reverse=True)
    else:
        y = 1 * x
        c = colorize(x)
    source.data = {'x':x,'y':y,'c':c}
    #updateColorBar(p.right[0])
    updateColorBar(p._property_values['right'][0])

def updateColorBar(cb):
    if menu.value == 'reverse':
        cb.title = 'reverse'
        u = colorize(np.linspace(0,360,101,endpoint=True),
                reverse=True)
    else:
        cb.title = 'normal'
        u = colorize(np.linspace(0,360,101,endpoint=True))
    newcm = LinearColorMapper(palette=u,low=0.0,high=2*np.pi)
    cb.color_mapper.palette = newcm.palette
    cb.color_mapper.low = newcm.low
    cb.color_mapper.high = newcm.high

# prepare some data
x = np.linspace(0,360,361,endpoint=True)
y = x
c = colorize(x)

source = ColumnDataSource({'x':x,'y':y,'c':c})

# create a new plot with a title and axis labels
p = figure(title="Simple scatter example", x_axis_label="x",
                y_axis_label="y",toolbar_location="above")

# create a plot to show the colors
p.scatter('x', 'y',size=2,color='c',source=source)

u = colorize(np.linspace(0,360,101,endpoint=True))
color_mapper = LinearColorMapper(palette=u,low=0.0,high=2*np.pi)
color_bar = ColorBar(color_mapper=color_mapper,
                     label_standoff=12,
                     title='normal')

p.add_layout(color_bar, 'right')

menu = Select(title='Order',value='normal',
                options=['normal','reverse'])
menu.on_change('value',update)

t = column(children=[menu,p])

# show the results
curdoc().add_root(t)

我正在使用 bokeh serve --show file_name.py 运行这个示例。

当我从菜单中选择“反向”时,绘图本身会正确更新,但 ColorBar 没有变化。我关注了advice here尽可能做出最小的改变,但也许我的改变太小了?我的猜测是 LinearColorMapper 不会将更新推送到 ColorBar,但更改 ColorBar 上的标题也不起作用。

编辑: 通过将 print(cbar.title) 添加到更新方法的末尾,我可以看到颜色条的标题正在更新。当我从菜单中选择这两个项目时,它从“正常”变为“反向”并再次变回。看起来 ColorBar 根本没有被重绘。

编辑2: 如果我尝试完全替换 ColorBar,它就会消失。修改update函数,新增一个创建ColorBar:

def update(attr,old,new):
    if new == 'reverse':
        y = 360 - 1 * x
        c = colorize(x,reverse=True)
    else:
        y = 1 * x
        c = colorize(x)
    source.data = {'x':x,'y':y,'c':c}
    cbar = p.right[0]
    #updateColorBar(cbar,new)
    p.right[0] = makeColorBar()
    print(p.right[0].visible)

def makeColorBar():
    if menu.value == 'reverse':
        title = 'reverse'
        u = colorize(np.linspace(0,360,101,endpoint=True),True)
    else:
        title = 'normal'
        u = colorize(np.linspace(0,360,101,endpoint=True))
    cm = LinearColorMapper(palette=u,low=0.0,high=2*np.pi)
    return ColorBar(color_mapper=cm,label_standoff=12,
                          title=title)

当我以不同的方式运行时,使用 python3 -i file_name.py 并询问 p.right[0] 的身份,我得到 ColorBar (id='1042', ...)。如果我随后手动更改 menu.value = 'reverse'(True 打印到屏幕上)并查看 ColorBar 的标识,我得到 ColorBar(id='1057', ... )。看起来新的颜色条没有被推送到显示器,而旧的颜色条正在被删除。

Edit3:这是marked as a bug在 Bokeh 中,计划更新到版本 2.3.2。

最佳答案

这个错误 has been closed , 它看起来像是 version 3.0 的一部分.

关于python - 在 Bokeh 中更新 ColorBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66876346/

相关文章:

python - 如何使用处理时间过长的巨大匹配关键字文件?

Python 3 内置类型 __init__ 不调用 super().__init__?

python - 在 Django 中使用交互式控件制作 Bokeh 图

python - 将节点标签添加到 Bokeh 网络图

python - 在所有 python 对象上注入(inject)辅助函数?

python - 如何从对象中获取类的名称?

python - 周期性操作错误: (2006, 'MySQL server has gone away')

python - 在 python 中绘制条形图

css - Bokeh 图覆盖其他内容

python - CountVectorizer 删除只出现一次的特征