Reputation: 85
I am trying to create plots in python using bokeh that allow dynamic visualization of data in bins. It's worth knowing that I am relatively new to python, very new to bokeh, and I know ZERO javascript. I have consulted this:
Link a Span or Cursor in between plots with Bokeh in Python
and this:
http://docs.bokeh.org/en/latest/docs/user_guide/interaction/callbacks.html
but am having trouble implementing the necessary parts of each. Here is my code prior to adding the requested capabilities:
from bokeh.layouts import column, widgetbox
from bokeh.models.widgets import Slider
from bokeh.models import Span, CustomJS
output_file('Raw_Spectra_and_Spillover_Data.html')
# widgets for bin setup
Pix1_LowLow = Slider(start = self.StartDAC, end = self.EndDAC, value = 129, step = 1, title = 'Pixel-1 - Low Bin - Low Thresh')
Pix1_LowHigh = Slider(start = self.StartDAC, end = self.EndDAC, value = 204, step = 1, title = 'Pixel-1 - Low Bin - High Thresh')
Pix1_HighLow = Slider(start = self.StartDAC, end = self.EndDAC, value = 218, step = 1, title = 'Pixel-1 - High Bin - Low Thresh')
Pix1_HighHigh = Slider(start = self.StartDAC, end = self.EndDAC, value = 500, step = 1, title = 'Pixel-1 - High Bin - High Thresh')
plot1spect = figure(width=700, height=250, title='pixel-1 Spectrum')
plot1spect.line(self.SpectDACvals1[0], self.SpectrumData1[0], line_width=2)
plot1spect_LowLowSpan = Span(location=Pix1_LowLow.value, dimension = 'height')
plot1spect_LowHighSpan = Span(location=Pix1_LowHigh.value, dimension = 'height')
plot1spect_HighLowSpan = Span(location=Pix1_HighLow.value, dimension = 'height')
plot1spect_HighHighSpan = Span(location=Pix1_HighHigh.value, dimension = 'height')
plot1spect.renderers.extend([plot1spect_LowLowSpan, plot1spect_LowHighSpan, plot1spect_HighLowSpan, plot1spect_HighHighSpan])
plot1spill = figure(width=700, height=250, title='pixel-1 Spillover')
plot1spill.line(self.SpillDACvals1[0], self.SpillData1[0], line_width=2)
plot1spill_LowLowSpan = Span(location=Pix1_LowLow.value, dimension = 'height')
plot1spill_LowHighSpan = Span(location=Pix1_LowHigh.value, dimension = 'height')
plot1spill_HighLowSpan = Span(location=Pix1_HighLow.value, dimension = 'height')
plot1spill_HighHighSpan = Span(location=Pix1_HighHigh.value, dimension = 'height')
plot1spill.renderers.extend([plot1spill_LowLowSpan, plot1spill_LowHighSpan, plot1spill_HighLowSpan, plot1spill_HighHighSpan])
show(row(plot1spect,plot1spill, widgetbox(Pix1_LowLow, Pix1_LowHigh, Pix1_HighLow, Pix1_HighHigh)))
This code gives me this:
If someone can show me how get Pix1_LowLow
slider to dynamically control the location of plot1spect_LowLowSpan
, then I can extend the technique to the other sliders and spans. Many thanks in advance!
python 3.5.2 - bokeh 12.0
Upvotes: 6
Views: 2883
Reputation: 34568
Here is a minimal complete example. Note that the recommended way to add annotations like Span
is with plot.add_layout
as shown below:
from bokeh.layouts import row, widgetbox
from bokeh.models import Slider, Span, CustomJS
from bokeh.plotting import figure, output_file, show
slider = Slider(start=0, end=10, value=3, step=0.1, title='Slider')
plot = figure(width=700, height=250, x_range=(0,10), y_range=(-1, 1))
span = Span(location=slider.value, dimension='height')
plot.add_layout(span)
callback = CustomJS(args=dict(span=span), code="""
span.location = cb_obj.value
""")
slider.js_on_change('value', callback)
output_file('span_slider.html')
show(row(plot, widgetbox(slider)))
Upvotes: 6
Reputation: 85
Thanks to @bigreddot for providing the answer. This is the code that implemented my solution specifically... Now how to do this programmatically for 128 data files... hmmmm..
from bokeh.layouts import row, widgetbox
from bokeh.models import Span, CustomJS, Slider
output_file('Raw_Spectra_and_Spillover_Data.html')
# widgets for bin setup
Pix1_LowLow = Slider(start = self.StartDAC, end = self.EndDAC, value = 129, step = 1, title = 'Pixel-1 - Low Bin - Low Thresh')
Pix1_LowHigh = Slider(start = self.StartDAC, end = self.EndDAC, value = 204, step = 1, title = 'Pixel-1 - Low Bin - High Thresh')
Pix1_HighLow = Slider(start = self.StartDAC, end = self.EndDAC, value = 218, step = 1, title = 'Pixel-1 - High Bin - Low Thresh')
Pix1_HighHigh = Slider(start = self.StartDAC, end = self.EndDAC, value = 500, step = 1, title = 'Pixel-1 - High Bin - High Thresh')
plot1spect = figure(width=700, height=250, title='pixel-1 Spectrum')
plot1spect.line(self.SpectDACvals1[0], self.SpectrumData1[0], line_width=2)
plot1spect_LowLowSpan = Span(location=Pix1_LowLow.value, dimension = 'height')
plot1spect.add_layout(plot1spect_LowLowSpan)
plot1spect_LowHighSpan = Span(location=Pix1_LowHigh.value, dimension = 'height')
plot1spect.add_layout(plot1spect_LowHighSpan)
plot1spect_HighLowSpan = Span(location=Pix1_HighLow.value, dimension = 'height')
plot1spect.add_layout(plot1spect_HighLowSpan)
plot1spect_HighHighSpan = Span(location=Pix1_HighHigh.value, dimension = 'height')
plot1spect.add_layout(plot1spect_HighHighSpan)
#plot1spect.renderers.extend([plot1spect_LowLowSpan, plot1spect_LowHighSpan, plot1spect_HighLowSpan, plot1spect_HighHighSpan])
plot1spill = figure(width=700, height=250, title='pixel-1 Spillover')
plot1spill.line(self.SpillDACvals1[0], self.SpillData1[0], line_width=2)
plot1spill_LowLowSpan = Span(location=Pix1_LowLow.value, dimension = 'height')
plot1spill.add_layout(plot1spill_LowLowSpan)
plot1spill_LowHighSpan = Span(location=Pix1_LowHigh.value, dimension = 'height')
plot1spill.add_layout(plot1spill_LowHighSpan)
plot1spill_HighLowSpan = Span(location=Pix1_HighLow.value, dimension = 'height')
plot1spill.add_layout(plot1spill_HighLowSpan)
plot1spill_HighHighSpan = Span(location=Pix1_HighHigh.value, dimension = 'height')
plot1spill.add_layout(plot1spill_HighHighSpan)
#plot1spill.renderers.extend([plot1spill_LowLowSpan, plot1spill_LowHighSpan, plot1spill_HighLowSpan, plot1spill_HighHighSpan])
Pix1_LowLow.callback = CustomJS(args=dict(span1 = plot1spect_LowLowSpan,
span2 = plot1spill_LowLowSpan,
slider = Pix1_LowLow),
code = """span1.location = slider.value; span2.location = slider.value""")
Pix1_LowHigh.callback = CustomJS(args=dict(span1 = plot1spect_LowHighSpan,
span2 = plot1spill_LowHighSpan,
slider = Pix1_LowHigh),
code = """span1.location = slider.value; span2.location = slider.value""")
Pix1_HighLow.callback = CustomJS(args=dict(span1 = plot1spect_HighLowSpan,
span2 = plot1spill_HighLowSpan,
slider = Pix1_HighLow),
code = """span1.location = slider.value; span2.location = slider.value""")
Pix1_HighHigh.callback = CustomJS(args=dict(span1 = plot1spect_HighHighSpan,
span2 = plot1spill_HighHighSpan,
slider = Pix1_HighHigh),
code = """span1.location = slider.value; span2.location = slider.value""")
Here is a repeat of the plots, but now each slider manipulates the respective span in both plots...
Upvotes: 0