Изменение элементов компоновки фигуры во время подачи боке

У меня есть шестнадцатеричный график, отображающий тепловую карту для моих данных. Для этого я использую 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))

Однако цветная полоса не добавляется во время выполнения. Я также пытался добавить его заранее, тогда он будет отображаться, но не обновляться. Как я могу добавить цветную полосу и/или обновить ее во время выполнения?

Позвольте дать вам подсказку: 1) всегда предоставляйте минимальный, но исполняемый код Здесь очень мало людей, готовых прилагать дополнительные усилия, чтобы копировать/вставлять по частям ваши блоки кода и самостоятельно добавлять необходимые импорты, чтобы в конечном итоге воссоздать вашу полную программу 2) Ограничьте и сосредоточьте свой код и свое описание только на своей проблеме. Многие программисты читают код и быстрее понять функциональность, глядя на код, а не читая текст, описывающий код, который вы пропустили. Я предлагаю вам отредактировать свой вопрос, следуя этим рекомендациям.

Tony 07.05.2019 14:43

Я изменил вопрос и предоставил работоспособный пример. При первом написании вопроса я уже подготовил этот фрагмент, однако не смог восстановить ошибку, при которой обновления моей визуализации полностью прекратятся. Я надеялся, что какой-нибудь эксперт увидит мою ошибку, когда я предоставлю исходный код. Спасибо, что нашли время, чтобы прочитать его

Daniel Töws 08.05.2019 08:05
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
353
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Во-первых, переместите настройку макета за пределы обратного вызова для кнопки и пусть обратный вызов только обновляет данные.

Затем используйте функцию 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))

Это работает отлично, большое спасибо. Есть ли простой способ удалить цветную полосу при обновлении? У меня есть одна визуализация данных, которая нуждается в панели

Daniel Töws 08.05.2019 10:09

Вы можете установить свойство visible для color_bar в обратном вызове, например. color_bar.visible = False

Oluwafemi Sule 08.05.2019 13:57

Другие вопросы по теме