Python, Bokeh: How to assign extra y-axis to line glyph in streaming plot?

送分小仙女□ 提交于 2019-12-21 06:57:24

问题


my problem can by simplified with a streaming plot of two lines and two y-axes. Each line is assigned to a different y-axis. With a Select Widget I would like to choose which line is assigned to the primary/secondary axis.

This functionality is actually working in the code below. However, the axis assignment is only changed when the plot updates its data. I would like to have the axis assignment happen on change of the select widget.

I tried a couple of 'update' functions, but none of them work. I'm assuming that the 'stream' function updates the axis assignment. How, could this be done on change of the select widget?

# Import libraries
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, Range1d, LinearAxis
from bokeh.models.widgets import Button, Select
from bokeh.layouts import layout
from bokeh.plotting import figure
from random import randrange


# Create figure
f=figure()

# Create ColumnDataSource
source_01 = ColumnDataSource(dict(x=[],y=[]))
source_02 = ColumnDataSource(dict(x=[],y=[]))

# Create extra axis
extra_axis = f.extra_y_ranges = {"y2Range": Range1d(start=-10, end=10)}
f.add_layout(LinearAxis(y_range_name='y2Range'), 'left')

# Create Line
line_01 = f.line(x='x',y='y', color='blue', source=source_01, y_range_name='default')
line_02 = f.line(x='x',y='y', color='red' , source=source_02, y_range_name='y2Range')

# Update data
def update_all():
    new_data_01=dict(x=[randrange(1,10)],y=[randrange(1,10)])
    new_data_02=dict(x=[randrange(1,100)],y=[randrange(1,100)])
    source_01.stream(new_data_01,rollover=15)
    source_02.stream(new_data_02,rollover=15)

# Update axis function
def update_axis():
    f.extra_y_ranges['y2Range'].start = -20 #new secondary axis min
    f.extra_y_ranges['y2Range'].end = 80 #new secondary axis max
    f.y_range.start = 0 
    f.y_range.end   = 50

# Select Axis
def update_select_axis(attr, old, new):    
    if select.value == "Red":
        line_01.y_range_name = 'y2Range'
        line_02.y_range_name = 'default'
        line_01.update()
        line_02.update()
        f.update()
        f.y_range.update()
        f.extra_y_ranges.update()
        print('Primary axis: Red, Secondary Axis: BLue')
    elif select.value == "Blue":
        line_01.y_range_name = 'default'
        line_02.y_range_name = 'y2Range'
        line_01.update()
        line_02.update()
        f.update()
        f.y_range.update()
        f.extra_y_ranges.update()
        print('Primary axis: Blue, Secondary Axis: Red')

# Create Select
select = Select(title="Primary Y Axis:", value="Blue", options=["Red", "Blue"])

# Create Button
button = Button(label='Set Axes')

# Update axis range on click
button.on_click(update_axis)
select.on_change("value", update_select_axis)

# Add elements to curdoc 
lay_out=layout([[f, button, select]])
curdoc().add_root(lay_out)
curdoc().add_periodic_callback(update_all,5000)

来源:https://stackoverflow.com/questions/42814842/python-bokeh-how-to-assign-extra-y-axis-to-line-glyph-in-streaming-plot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!