У меня есть шестнадцатеричный график, отображающий тепловую карту для моих данных. Для этого я использую ColumnDataSource, содержащий информацию о x, y, а также значения и цвет для этого элемента. Кроме того, я предоставляю цветную полосу для шестнадцатеричного графика, показывающую информацию, какое значение приведет к какому цвету. Это должно работать для разных наборов данных, однако я не могу обновить цветовую полосу в соответствии с минимальными и высокими значениями во время выполнения.
Вот пример кода (простой пример myapp, предоставленный bokeh), где каждое нажатие кнопки должно добавлять цветную полосу с разными значениями:
from random import random
from bokeh.layouts import column
from bokeh.models import Button, LinearColorMapper, ColorBar, BasicTicker
from bokeh.palettes import RdYlBu3
from bokeh.plotting import figure, curdoc
from colorcet import CET_L18 as palette
# create a plot and style its properties
p = figure(x_range=(0, 100), y_range=(0, 100), toolbar_location=None)
p.border_fill_color = 'black'
p.background_fill_color = 'black'
p.outline_line_color = None
p.grid.grid_line_color = None
# add a text renderer to our plot (no data yet)
r = p.text(x=[], y=[], text=[], text_color=[], text_font_size = "20pt",
text_baseline = "middle", text_align = "center")
i = 0
ds = r.data_source
# create a callback that will add a number in a random location
def callback():
global i
# BEST PRACTICE --- update .data in one step with a new dict
new_data = dict()
new_data['x'] = ds.data['x'] + [random()*70 + 15]
new_data['y'] = ds.data['y'] + [random()*70 + 15]
new_data['text_color'] = ds.data['text_color'] + [RdYlBu3[i%3]]
new_data['text'] = ds.data['text'] + [str(i)]
ds.data = new_data
color_mapper = LinearColorMapper(palette=palette, low=0, high=1000*i)
color_bar = ColorBar(color_mapper=color_mapper, ticker=BasicTicker(),
label_standoff=12, border_line_color=None, location=(0, 0), orientation = "horizontal")
p.add_layout(color_bar, 'below')
i = i + 1
# add a button widget and configure with the call back
button = Button(label = "Press Me")
button.on_click(callback)
#show(p)
# put the button and plot in a layout and add to the document
curdoc().add_root(column(button, p))
Однако цветная полоса не добавляется во время выполнения. Я также пытался добавить его заранее, тогда он будет отображаться, но не обновляться. Как я могу добавить цветную полосу и/или обновить ее во время выполнения?
Я изменил вопрос и предоставил работоспособный пример. При первом написании вопроса я уже подготовил этот фрагмент, однако не смог восстановить ошибку, при которой обновления моей визуализации полностью прекратятся. Я надеялся, что какой-нибудь эксперт увидит мою ошибку, когда я предоставлю исходный код. Спасибо, что нашли время, чтобы прочитать его






Во-первых, переместите настройку макета за пределы обратного вызова для кнопки и пусть обратный вызов только обновляет данные.
Затем используйте функцию linear_cmap из bokeh.transform для построения линейной карты цветов. Эта функция дает вам преобразователь для получения цвета для значения в цветовой палитре.
Наконец, обновите значение high преобразования в обратном вызове.
from random import random
from bokeh.layouts import column
from bokeh.models import Button, ColorBar, BasicTicker
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, curdoc
from colorcet import CET_L18 as palette
from bokeh.transform import linear_cmap
# create a plot and style its properties
p = figure(x_range=(0, 100), y_range=(0, 100), toolbar_location=None)
p.border_fill_color = 'black'
p.background_fill_color = 'black'
p.outline_line_color = None
p.grid.grid_line_color = None
i = 0
color_mapper = linear_cmap(field_name='text', palette=palette, low=0, high=i)
color_bar = ColorBar(
color_mapper=color_mapper['transform'],
ticker=BasicTicker(),
label_standoff=12,
border_line_color='black',
location=(0, 0),
orientation = "horizontal")
# add a text renderer to our plot (no data yet)
ds = ColumnDataSource(dict(x=[],y=[],text=[]))
r = p.text(x='x', y='y', text='text', text_color=color_mapper, text_font_size = "20pt",
text_baseline = "middle", text_align = "center", source=ds)
p.add_layout(color_bar, 'below')
# create a callback that will add a number in a random location
def callback():
global i
i = i + 1
# BEST PRACTICE --- update .data in one step with a new dict
new_data = dict()
new_data['x'] = ds.data['x'] + [random()*70 + 15]
new_data['y'] = ds.data['y'] + [random()*70 + 15]
new_data['text'] = ds.data['text'] + [i]
ds.data = new_data
color_mapper['transform'].high = i
# add a button widget and configure with the call back
button = Button(label = "Press Me")
button.on_click(callback)
#show(p)
# put the button and plot in a layout and add to the document
curdoc().add_root(column(button, p))
Это работает отлично, большое спасибо. Есть ли простой способ удалить цветную полосу при обновлении? У меня есть одна визуализация данных, которая нуждается в панели
Вы можете установить свойство visible для color_bar в обратном вызове, например. color_bar.visible = False
Позвольте дать вам подсказку: 1) всегда предоставляйте минимальный, но исполняемый код Здесь очень мало людей, готовых прилагать дополнительные усилия, чтобы копировать/вставлять по частям ваши блоки кода и самостоятельно добавлять необходимые импорты, чтобы в конечном итоге воссоздать вашу полную программу 2) Ограничьте и сосредоточьте свой код и свое описание только на своей проблеме. Многие программисты читают код и быстрее понять функциональность, глядя на код, а не читая текст, описывающий код, который вы пропустили. Я предлагаю вам отредактировать свой вопрос, следуя этим рекомендациям.