web-dev-qa-db-ja.com

プロットとウィジェットの配置のためのボケレイアウト

ボケアプリの特定のデザインを念頭に置いています。 bokeh 0.12.3とボケサーバーを使用してすべての同期を維持しています。私のモックアップを見てください:

enter image description here

左側には静的なナビゲーションバーがあり、ビューの右側は手動で追加されたプロットで構成されます。右側のプロット列の量は、w.r.tで変更されます。ウィンドウサイズ。私はボケレイアウトのドキュメントをよく知っています プロットとウィジェットのレイアウト ですが、もう少し複雑です。これは私が現在持っているレイアウトです:

doc_layout = layout(children=[[column(radio_buttons,
                                      cbx_buttons,
                                      div,
                                      data_table,
                                      plot,
                                      button)]],
                    sizing_mode='scale_width')
curdoc().add_root(doc_layout)

私が使用する新しいプロットを追加するために:

doc_layout.children[-1].children.append(plot)
# appends plot to layout children [[column(..), plot]]

しかし、その振る舞いは非常に奇妙で、私が実際に達成したいことはまったくありません。代わりに、新しいプロットが列(メニューパネル)の上部に追加されます。

ここでは、私が何を意味するのかを試してみることができる短い例を示します。

from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.models.sources import ColumnDataSource
from bokeh.models.widgets import Button, DataTable, TableColumn
from bokeh.layouts import layout, widgetbox, column, row

WIDTH = 200
HEIGHT = 200

def add_plot():
    p = figure(width=WIDTH, height=HEIGHT, tools=[], toolbar_location=None)
    p.line([0, 1, 2, 3, 4, 5], [0, 1, 4, 9, 16, 25])
    doc_layout.children[-1].children.append(p)

src = ColumnDataSource(dict(x=[0, 1, 2, 3, 4, 5], y=[0, 1, 4, 9, 16, 25]))
t1 = DataTable(source=src, width=WIDTH, height=HEIGHT,
               columns=[TableColumn(field='x', title='x'),
                        TableColumn(field='y', title='y')])
b = Button(label='add plot')
b.on_click(add_plot)

doc_layout = layout([[widgetbox(b, t1)]], sizing_mode='scale_width')
curdoc().add_root(doc_layout)

この問題を克服するための最良の解決策は何であるかわかりません。さまざまなサイズ設定モードのlayout()から、さまざまな組み合わせのgridplot()column()/row()まで、いくつか試してみました。以前のバージョンでは、ナビゲーションメニューがページの左側ではなく上部に配置されていましたが、すべてが機能しているように見えました。

layout(children=[[widgetbox(radio_button, cbx_button),
                  widgetbox(data_table),
                  widgetbox(div),
                  widgetbox(button)],
                  [Spacer()]],
       sizing_mode='scale_width')
11
jofroe

コールバックの最後の行を次のように変更できます。

doc_layout.children[0].children[-1].children.append(p)

そして、レイアウトを次のように変更します。

doc_layout = layout(sizing_mode='scale_width') 
doc_layout.children.append(row(column(widgetbox(b, t1)), column()))

しかし、その後、あなたが望むように正確に伝播しないでください。そのためには、カスタムのcssスタイリングを行う必要があると思います。

あなたが ディレクトリ形式 アプリであると仮定すると、1つのオプションは、ヘッダーにstyleブロックを追加できるtemplate/index.htmlファイルを作成することです。あなたのプロットをinline-blocksか何かにするために。

<style>
  .bk-whatever-class {
    ...
  }
</style>

ブラウザの開発者ツールを使用して、適切なクラスを見つけ、それらをおもちゃにします。しかし、おそらく最善の解決策ではありません。

ウィジェットの場合、 css_classes 属性があり、そのウィジェットが使用するクラスを指定できますが、残念ながら、それはプロットキャンバスには役立ちません。

mycol = column(css_classes=['myclass'])
2
ryanjdillon