Как создать приложение Holoviews с несколькими независимыми графиками DynamicMap?

Я пытаюсь создать макет сетки (скажем, 2x2) графиков типа DynamicMap с использованием голографических изображений. Это должно быть приложение Holoviews / Bokeh.

После создания своих dmaps я выкладываю их, используя

layout = hv.Layout([dmap1, dmap2]).cols(2)

этот макет генерирует два графика рядом друг с другом.Проблема, с которой я столкнулся, заключается в том, что по умолчанию виджеты для каждой динамической карты группируются справа от строки без визуальной связи с графиками (панели инструментов карт также объединяются в только один).

Более того, если я передаю в макет более двух dmaps, я получаю сообщение об ошибке:

TypeError: DynamicMap does not accept AdjointLayout type, data elements have to be a ('ViewableElement', 'NdMapping', 'Layout'). 

Я использую рендерер в серверном режиме:

renderer = hv.renderer('bokeh')
renderer = renderer.instance(mode='server')

Таким образом, я хочу иметь сетку из более чем 2 независимо управляемых динамических графиков.


person fccoelho    schedule 04.02.2018    source источник


Ответы (1)


Здесь есть что распаковать, поэтому позвольте мне начать с ответа на этот вопрос:

виджеты для каждой динамической карты группируются справа от строки

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

import numpy as np
import holoviews as hv

from bokeh.io import curdoc
from bokeh.layouts import row

renderer = hv.renderer('bokeh').instance(mode='server')

dmap1 = hv.DynamicMap(lambda x: hv.Curve(np.random.rand(10)), kdims='x').redim.range(x=(0,5))
dmap2 = hv.DynamicMap(lambda y: hv.Scatter(np.random.rand(10)), kdims='y').redim.range(x=(0,5))

widget1 = renderer.get_widget(dmap1, None, position='above').state
widget2 = renderer.get_widget(dmap2, None, position='above').state

r = row(widget1, widget2)

doc = curdoc()
doc.add_root(r)

Мы создаем две независимые динамические карты, затем используем средство визуализации для создания отдельных графиков и виджетов, а затем составляем их, используя макет строки боке. Как видите, мы также можем определить позицию для виджетов, чтобы вместо того, чтобы располагать их справа, они были сверху.

панели инструментов карты также объединяются в одну

В недавнем PR была добавлена ​​новая merge_tools опция, позволяющая иметь отдельные панели инструментов в одном Макет.

Более того, если я передаю в макет более двух dmaps, я получаю сообщение об ошибке:

Вероятно, это связано с возвратом прилегающего объекта, что в настоящее время запрещено внутри DynamicMap. Вы случайно не пользуетесь методом .hist? В таком случае попробуйте вызвать его на DynamicMap вместо того, чтобы DynamicMap возвращал объект с примыкающим к нему Histogram.

person philippjfr    schedule 04.02.2018
comment
Спасибо за отличный ответ @philippjfr. Но как насчет нескольких строк? Просто продолжай добавлять корни? - person fccoelho; 05.02.2018
comment
Я получаю эту ошибку при попытке создать виджеты: rmeans_w = renderer.get_widget (rmeans, None, position = 'above'). State AttributeError: объект 'BokehSelectionWidget' не имеет атрибута 'state' - person fccoelho; 05.02.2018
comment
А как насчет более сложных макетов? Как вы переходите, чтобы строить только виджеты? а не сюжеты? У Bokeh есть функция компоновки, которая, похоже, не принимает hv dmaps: ValueError: в компоновку можно вставлять только элементы LayoutDOM. Пытался вставить:: DynamicMap [Exchanges, Symbols, Window] типа ‹class 'holoviews.core.spaces.DynamicMap'› - person fccoelho; 05.02.2018
comment
›Я получаю эту ошибку при попытке создать виджеты. Вы уверены, что создали экземпляр средства визуализации в режиме« сервера », используя: renderer = hv.renderer ('bokeh'). Instance (mode = 'server')› Способ вы переходите в row только свои виджеты? Эти .state в виджете BokehServerWidget содержат макет боке как для графика, так и для виджетов. Если вам просто нужен сюжет, вы можете использовать renderer.get_plot(dmap).state. - person philippjfr; 05.02.2018
comment
Да, я использую средство визуализации в режиме сервера: renderer = hv.renderer ('bokeh') renderer = renderer.instance (mode = 'server') - person fccoelho; 05.02.2018
comment
Хорошо, нашел! Я создавал рендерер, получал виджеты и только в конце переводил рендерер в «серверный» режим. Спасибо еще раз - person fccoelho; 05.02.2018
comment
@philippjfr, спасибо за ответ. Однако я получаю сообщение об ошибке AttributeError: 'HoloViews' object has no attribute 'state'. Это отличается от того, что @fccoelho видел раньше. Кажется, что метод get_wedget возвращает объект HoloViews, у которого нет атрибута «состояние». - person user4015990; 20.04.2020
comment
Вы правы, начиная с HoloViews 1.13.0 виджеты HoloViews строятся на Panel. Я обновлю пост, когда у меня будет возможность. - person philippjfr; 22.04.2020