【问题标题】:create interactive plots with bokeh python使用散景 python 创建交互式绘图
【发布时间】:2020-01-14 19:10:01
【问题描述】:

我想用散景在一个图中创建交互式绘图。 以下代码适用于 data_1,最后我得到一个 html 文件:

data_1 = ColumnDataSource(data=user_id_weekly01)
data_2 = ColumnDataSource(data=user_id_weekly02)


output_file("test.html")
#generate info box with html
TOOLTIPS = """
<div style="background-color:  #8b85af">
    <div>
        <span style="font-size: 17px; font-weight: bold; user_ID:">user_ID: @user_ID</span>
    </div>
    <div>
        <span style="font-size: 17px; font-weight: bold; user_ID_count:">requested reports: @user_ID_count</span>
    </div>
    <div>
        <span style="font-size: 17px; font-weight: bold; number_requested_plots:">requested plots: @number_requested_plots</span>
    </div>
</div>
        """



p = figure(plot_width=1000, plot_height=500, tooltips=TOOLTIPS,
       title="test")
p.vbar(source=data_1,x='user_ID',top='user_ID_count',bottom=0,width=1.0)

p.y_range.start = 0
p.xaxis.axis_label = "user_ID"
p.yaxis.axis_label = "number requested report"
p.outline_line_color = None
p.xaxis.axis_label_text_font_size = "13pt"
p.yaxis.axis_label_text_font_size = "13pt"
p.xaxis.major_label_text_font_size = "13pt"
p.yaxis.major_label_text_font_size = "13pt"
p.title.text_font_size = '13pt'

show(p)

现在,我不仅有 data_1,还有 data_2 等等。我想用散景滑块构建一些东西,以便能够在不同的地块上“滑动”。如果它不能与滑块一起使用,单击按钮也是一个聪明的解决方案。

data_1 ect. looks like:
user_ID user_ID_count   number_requested_plots
0   13  1   19
1   28  1   8
2   53  3   57
3   64  8   145
4   82  1   11
5   94  1   19
6   100 13  228
7   102 1   19

我期待一些提示,谢谢!

【问题讨论】:

    标签: python bokeh interactive


    【解决方案1】:

    您可以使用 CommonJS 并在滑块值更改时编写回调(请参阅bokeh docs)。例如:

    data_1 = ColumnDataSource(data=user_id_weekly01)
    data_2 = ColumnDataSource(data=user_id_weekly02)
    # add default source variable:
    source = ColumnDataSource(data=user_id_weekly01)
    
    # ...
    
    # and use it in your vbar:
    p.vbar(source=source,x='user_ID',top='user_ID_count',bottom=0,width=1.0)
    
    # ...
    
    # replace show(plt) with the following code:
    from bokeh.models import Slider, CustomJS
    from bokeh.layouts import column
    datasources = [data_1, data_2]
    slider  = Slider(start=0, end=len(datasources) -1, step=1, title="datasources", value=0)
    callback = CustomJS(args=dict(source=source, datasources=datasources), code="""
            var i = cb_obj.value;
            source.data = Object.assign({},datasources[i].data);
            source.change.emit();
        """)
    slider.js_on_change('value', callback)
    
    show(column(p,slider))
    

    这个想法是,在滑块值更改时,您将源数据替换为数据源列表中的源数据。

    【讨论】:

      【解决方案2】:

      如果我必须生成交互式绘图,我总是选择散景服务器。 优点:可以编写原生 python 代码,不用担心 JS 回调。最小的例子:

      确保从命令行运行bokeh serve --show test.py

      # test.py
      import numpy as np, pandas as pd
      from bokeh.layouts import column, row
      from bokeh.models import Slider,ColumnDataSource,TextInput
      from bokeh.plotting import figure, curdoc
      
      # Set up data
      df1 = pd.DataFrame(np.random.randint(9,25,size=(2,2)),columns=["A","B"])
      df2 = pd.DataFrame(np.arange(4,8).reshape(2,2),columns=["A","B"])
      dfs = [df1,df2]
      source = ColumnDataSource(df1)
      # Set up plot
      plot = figure(plot_height=400, plot_width=400, title="my source",x_range=[0,max(max(x["A"]) for x in dfs)+1],\
              y_range=[0,max(max(x["B"]) for x in dfs)+1])
      plot.scatter("A","B", source = source)
      
      
      
      # Set up widgets
      text = TextInput(title="title", value='my source')
      data = Slider(title="Choose Data",value=0, start=0, end=1)
      
      # Set up callbacks
      
      def update_title(attrname, old, new):
           plot.title.text = text.value
      
      text.on_change('value', update_title)
      
      def update_data(attrname, old, new):
          # Get the current slider values
          d = data.value
      
          # Generate new data
          if d == 0: source.data = df1
          if d == 1: source.data = df2
      
      
      data.on_change("value",update_data)
      
      
      # Set up layouts and add to document
      inputs = column(data)
      
      curdoc().add_root(row(inputs, plot))
      curdoc().title = "my source"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多