在 Bokeh 中更新 ColorBar
Updating a ColorBar in 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
结合使用。
当我从菜单中选择 'reverse' 时,绘图本身会正确更新,但 ColorBar 没有变化。我按照 advice here 进行了尽可能小的更改,但也许我的更改太小了?我的猜测是 LinearColorMapper 不会将更新推送到 ColorBar,但更改 ColorBar 上的标题也不起作用。
编辑:
通过在更新方法的末尾添加 print(cbar.title)
,我可以看到颜色栏的标题正在更新。它从 'normal' 变为 'reverse' 然后又变回来,因为我 select 菜单中的两个项目。看起来 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, it looks like it is part of version 3.0。
我正在尝试更新 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
结合使用。
当我从菜单中选择 'reverse' 时,绘图本身会正确更新,但 ColorBar 没有变化。我按照 advice here 进行了尽可能小的更改,但也许我的更改太小了?我的猜测是 LinearColorMapper 不会将更新推送到 ColorBar,但更改 ColorBar 上的标题也不起作用。
编辑:
通过在更新方法的末尾添加 print(cbar.title)
,我可以看到颜色栏的标题正在更新。它从 'normal' 变为 'reverse' 然后又变回来,因为我 select 菜单中的两个项目。看起来 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, it looks like it is part of version 3.0。