Here are the examples of the python api bokeh.__version__ taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
5 Examples
0
View Source File : interact.py
License : MIT License
Project Creator : nasa
License : MIT License
Project Creator : nasa
def show_interact_widget(tpf, notebook_url='localhost:8888',
max_cadences=30000,
aperture_mask='pipeline',
exported_filename=None):
"""Display an interactive Jupyter Notebook widget to inspect the pixel data.
The widget will show both the lightcurve and pixel data. The pixel data
supports pixel selection via Bokeh tap and box select tools in an
interactive javascript user interface.
Note: at this time, this feature only works inside an active Jupyter
Notebook, and tends to be too slow when more than ~30,000 cadences
are contained in the TPF (e.g. short cadence data).
Parameters
----------
tpf : lightkurve.TargetPixelFile
Target Pixel File to interact with
notebook_url: str
Location of the Jupyter notebook page (default: "localhost:8888")
When showing Bokeh applications, the Bokeh server must be
explicitly configured to allow connections originating from
different URLs. This parameter defaults to the standard notebook
host and port. If you are running on a different location, you
will need to supply this value for the application to display
properly. If no protocol is supplied in the URL, e.g. if it is
of the form "localhost:8888", then "http" will be used.
max_cadences : int
Raise a RuntimeError if the number of cadences shown is larger than
this value. This limit helps keep browsers from becoming unresponsive.
"""
try:
import bokeh
if bokeh.__version__[0] == '0':
warnings.warn("interact() requires Bokeh version 1.0 or later", LightkurveWarning)
except ImportError:
log.error("The interact() tool requires the `bokeh` Python package; "
"you can install bokeh using e.g. `conda install bokeh`.")
return None
aperture_mask = tpf._parse_aperture_mask(aperture_mask)
if exported_filename is None:
exported_filename = make_default_export_name(tpf)
try:
exported_filename = str(exported_filename)
except:
log.error('Invalid input filename type for interact()')
raise
if ('.fits' not in exported_filename.lower()):
exported_filename += '.fits'
lc = tpf.to_lightcurve(aperture_mask=aperture_mask)
npix = tpf.flux[0, :, :].size
pixel_index_array = np.arange(0, npix, 1).reshape(tpf.flux[0].shape)
# Bokeh cannot handle many data points
# https://github.com/bokeh/bokeh/issues/7490
if len(lc.cadenceno) > max_cadences:
msg = 'Interact cannot display more than {} cadences.'
raise RuntimeError(msg.format(max_cadences))
def create_interact_ui(doc):
# The data source includes metadata for hover-over tooltips
lc_source = prepare_lightcurve_datasource(lc)
tpf_source = prepare_tpf_datasource(tpf, aperture_mask)
# Create the lightcurve figure and its vertical marker
fig_lc, vertical_line = make_lightcurve_figure_elements(lc, lc_source)
# Create the TPF figure and its stretch slider
pedestal = np.nanmin(tpf.flux)
fig_tpf, stretch_slider = make_tpf_figure_elements(tpf, tpf_source,
pedestal=pedestal,
fiducial_frame=0)
# Helper lookup table which maps cadence number onto flux array index.
tpf_index_lookup = {cad: idx for idx, cad in enumerate(tpf.cadenceno)}
# Interactive slider widgets and buttons to select the cadence number
cadence_slider = Slider(start=np.min(tpf.cadenceno),
end=np.max(tpf.cadenceno),
value=np.min(tpf.cadenceno),
step=1,
title="Cadence Number",
width=490)
r_button = Button(label=">", button_type="default", width=30)
l_button = Button(label=" < ", button_type="default", width=30)
export_button = Button(label="Save Lightcurve",
button_type="success", width=120)
message_on_save = Div(text=' ',width=600, height=15)
# Callbacks
def update_upon_pixel_selection(attr, old, new):
"""Callback to take action when pixels are selected."""
# Check if a selection was "re-clicked", then de-select
if ((sorted(old) == sorted(new)) & (new != [])):
# Trigger recursion
tpf_source.selected.indices = new[1:]
if new != []:
selected_indices = np.array(new)
selected_mask = np.isin(pixel_index_array, selected_indices)
lc_new = tpf.to_lightcurve(aperture_mask=selected_mask)
lc_source.data['flux'] = lc_new.flux
ylims = get_lightcurve_y_limits(lc_source)
fig_lc.y_range.start = ylims[0]
fig_lc.y_range.end = ylims[1]
else:
lc_source.data['flux'] = lc.flux * 0.0
fig_lc.y_range.start = -1
fig_lc.y_range.end = 1
message_on_save.text = " "
export_button.button_type = "success"
def update_upon_cadence_change(attr, old, new):
"""Callback to take action when cadence slider changes"""
if new in tpf.cadenceno:
frameno = tpf_index_lookup[new]
fig_tpf.select('tpfimg')[0].data_source.data['image'] = \
[tpf.flux[frameno, :, :] - pedestal]
vertical_line.update(location=tpf.time[frameno])
else:
fig_tpf.select('tpfimg')[0].data_source.data['image'] = \
[tpf.flux[0, :, :] * np.NaN]
lc_source.selected.indices = []
def go_right_by_one():
"""Step forward in time by a single cadence"""
existing_value = cadence_slider.value
if existing_value < np.max(tpf.cadenceno):
cadence_slider.value = existing_value + 1
def go_left_by_one():
"""Step back in time by a single cadence"""
existing_value = cadence_slider.value
if existing_value > np.min(tpf.cadenceno):
cadence_slider.value = existing_value - 1
def save_lightcurve():
"""Save the lightcurve as a fits file with mask as HDU extension"""
if tpf_source.selected.indices != []:
selected_indices = np.array(tpf_source.selected.indices)
selected_mask = np.isin(pixel_index_array, selected_indices)
lc_new = tpf.to_lightcurve(aperture_mask=selected_mask)
lc_new.to_fits(exported_filename, overwrite=True,
flux_column_name='SAP_FLUX',
aperture_mask=selected_mask.astype(np.int),
SOURCE='lightkurve interact',
NOTE='custom mask',
MASKNPIX=np.nansum(selected_mask))
if message_on_save.text == " ":
text = ' < font color="black"> < i>Saved file {} < /i> < /font>'
message_on_save.text = text.format(exported_filename)
export_button.button_type = "success"
else:
text = ' < font color="gray"> < i>Saved file {} < /i> < /font>'
message_on_save.text = text.format(exported_filename)
else:
text = ' < font color="gray"> < i>No pixels selected, no mask saved < /i> < /font>'
export_button.button_type = "warning"
message_on_save.text = text
def jump_to_lightcurve_position(attr, old, new):
if new != []:
cadence_slider.value = lc.cadenceno[new[0]]
# Map changes to callbacks
r_button.on_click(go_right_by_one)
l_button.on_click(go_left_by_one)
tpf_source.selected.on_change('indices', update_upon_pixel_selection)
lc_source.selected.on_change('indices', jump_to_lightcurve_position)
export_button.on_click(save_lightcurve)
cadence_slider.on_change('value', update_upon_cadence_change)
# Layout all of the plots
sp1, sp2, sp3, sp4 = (Spacer(width=15), Spacer(width=30),
Spacer(width=80), Spacer(width=60))
widgets_and_figures = layout([fig_lc, fig_tpf],
[l_button, sp1, r_button, sp2,
cadence_slider, sp3, stretch_slider],
[export_button, sp4, message_on_save])
doc.add_root(widgets_and_figures)
output_notebook(verbose=False, hide_banner=True)
return show(create_interact_ui, notebook_url=notebook_url)
def show_skyview_widget(tpf, notebook_url='localhost:8888', magnitude_limit=18):
0
View Source File : interact.py
License : MIT License
Project Creator : nasa
License : MIT License
Project Creator : nasa
def show_skyview_widget(tpf, notebook_url='localhost:8888', magnitude_limit=18):
"""skyview
Parameters
----------
tpf : lightkurve.TargetPixelFile
Target Pixel File to interact with
notebook_url: str
Location of the Jupyter notebook page (default: "localhost:8888")
When showing Bokeh applications, the Bokeh server must be
explicitly configured to allow connections originating from
different URLs. This parameter defaults to the standard notebook
host and port. If you are running on a different location, you
will need to supply this value for the application to display
properly. If no protocol is supplied in the URL, e.g. if it is
of the form "localhost:8888", then "http" will be used.
magnitude_limit : float
A value to limit the results in based on Gaia Gmag. Default, 18.
"""
try:
import bokeh
if bokeh.__version__[0] == '0':
warnings.warn("interact_sky() requires Bokeh version 1.0 or later",
LightkurveWarning)
except ImportError:
log.error("The interact_sky() tool requires the `bokeh` Python package; "
"you can install bokeh using e.g. `conda install bokeh`.")
return None
# Try to identify the "fiducial frame", for which the TPF WCS is exact
zp = (tpf.pos_corr1 == 0) & (tpf.pos_corr2 == 0)
zp_loc, = np.where(zp)
if len(zp_loc) == 1:
fiducial_frame = zp_loc[0]
else:
fiducial_frame = 0
def create_interact_ui(doc):
# The data source includes metadata for hover-over tooltips
tpf_source = None
# Create the TPF figure and its stretch slider
pedestal = np.nanmin(tpf.flux)
fig_tpf, stretch_slider = make_tpf_figure_elements(tpf, tpf_source,
pedestal=pedestal,
fiducial_frame=fiducial_frame,
plot_width=640, plot_height=600)
fig_tpf, r = add_gaia_figure_elements(tpf, fig_tpf,
magnitude_limit=magnitude_limit)
# Optionally override the default title
if tpf.mission == 'K2':
fig_tpf.title.text = "Skyview for EPIC {}, K2 Campaign {}, CCD {}.{}".format(
tpf.targetid, tpf.campaign, tpf.module, tpf.output)
elif tpf.mission == 'Kepler':
fig_tpf.title.text = "Skyview for KIC {}, Kepler Quarter {}, CCD {}.{}".format(
tpf.targetid, tpf.quarter, tpf.module, tpf.output)
elif tpf.mission == 'TESS':
fig_tpf.title.text = 'Skyview for TESS {} Sector {}, Camera {}.{}'.format(
tpf.targetid, tpf.sector, tpf.camera, tpf.ccd)
# Layout all of the plots
widgets_and_figures = layout([fig_tpf, stretch_slider])
doc.add_root(widgets_and_figures)
output_notebook(verbose=False, hide_banner=True)
return show(create_interact_ui, notebook_url=notebook_url)
0
View Source File : interact_bls.py
License : MIT License
Project Creator : nasa
License : MIT License
Project Creator : nasa
def show_interact_widget(lc, notebook_url='localhost:8888', minimum_period=None,
maximum_period=None, resolution=2000):
"""Show the BLS interact widget.
Parameters
----------
notebook_url: str
Location of the Jupyter notebook page (default: "localhost:8888")
When showing Bokeh applications, the Bokeh server must be
explicitly configured to allow connections originating from
different URLs. This parameter defaults to the standard notebook
host and port. If you are running on a different location, you
will need to supply this value for the application to display
properly. If no protocol is supplied in the URL, e.g. if it is
of the form "localhost:8888", then "http" will be used.
minimum_period : float or None
Minimum period to assess the BLS to. If None, default value of 0.3 days
will be used.
maximum_period : float or None
Maximum period to evaluate the BLS to. If None, the time coverage of the
lightcurve / 4 will be used.
resolution : int
Number of points to use in the BLS panel. Lower this value to have a faster
but less accurate compute time. You can also vary this value using the
Resolution Slider.
"""
try:
import bokeh
if bokeh.__version__[0] == '0':
warnings.warn("interact_bls() requires Bokeh version 1.0 or later", LightkurveWarning)
except ImportError:
log.error("The interact_bls() tool requires the `bokeh` package; "
"you can install bokeh using e.g. `conda install bokeh`.")
return None
try:
from astropy.timeseries import BoxLeastSquares
except ImportError:
try:
from astropy.stats import BoxLeastSquares
except ImportError:
log.error("The `interact_bls()` tool requires AstroPy v3.1 or later.")
def _create_interact_ui(doc, minp=minimum_period, maxp=maximum_period, resolution=resolution):
"""Create BLS interact user interface."""
if minp is None:
minp = 0.3
if maxp is None:
maxp = (lc.time[-1] - lc.time[0])/2
time_format = ''
if lc.time_format == 'bkjd':
time_format = ' - 2454833 days'
if lc.time_format == 'btjd':
time_format = ' - 2457000 days'
# Some sliders
duration_slider = Slider(start=0.01,
end=0.5,
value=0.05,
step=0.01,
title="Duration [Days]",
width=400)
npoints_slider = Slider(start=500,
end=10000,
value=resolution,
step=100,
title="BLS Resolution",
width=400)
# Set up the period values, BLS model and best period
period_values = np.logspace(np.log10(minp), np.log10(maxp), npoints_slider.value)
period_values = period_values[(period_values > duration_slider.value) &
(period_values < maxp)]
model = BoxLeastSquares(lc.time, lc.flux)
result = model.power(period_values, duration_slider.value)
loc = np.argmax(result.power)
best_period = result.period[loc]
best_t0 = result.transit_time[loc]
# Some Buttons
double_button = Button(label="Double Period", button_type="danger", width=100)
half_button = Button(label="Half Period", button_type="danger", width=100)
text_output = Paragraph(text="Period: {} days, T0: {}{}".format(
np.round(best_period, 7),
np.round(best_t0, 7), time_format),
width=350, height=40)
# Set up BLS source
bls_source = prepare_bls_datasource(result, loc)
bls_help_source = prepare_bls_help_source(bls_source, npoints_slider.value)
# Set up the model LC
mf = model.model(lc.time, best_period, duration_slider.value, best_t0)
mf /= np.median(mf)
mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2)) > 0.9)
model_lc = LightCurve(lc.time[mask], mf[mask])
model_lc = model_lc.append(LightCurve([(lc.time[0] - best_t0) + best_period/2], [1]))
model_lc = model_lc.append(LightCurve([(lc.time[0] - best_t0) + 3*best_period/2], [1]))
model_lc_source = ColumnDataSource(data=dict(
time=np.sort(model_lc.time),
flux=model_lc.flux[np.argsort(model_lc.time)]))
# Set up the LC
nb = int(np.ceil(len(lc.flux)/5000))
lc_source = prepare_lightcurve_datasource(lc[::nb])
lc_help_source = prepare_lc_help_source(lc)
# Set up folded LC
nb = int(np.ceil(len(lc.flux)/10000))
f = lc.fold(best_period, best_t0)
f_source = prepare_folded_datasource(f[::nb])
f_help_source = prepare_f_help_source(f)
f_model_lc = model_lc.fold(best_period, best_t0)
f_model_lc = LightCurve([-0.5], [1]).append(f_model_lc)
f_model_lc = f_model_lc.append(LightCurve([0.5], [1]))
f_model_lc_source = ColumnDataSource(data=dict(
phase=f_model_lc.time,
flux=f_model_lc.flux))
def _update_light_curve_plot(event):
"""If we zoom in on LC plot, update the binning."""
mint, maxt = fig_lc.x_range.start, fig_lc.x_range.end
inwindow = (lc.time > mint) & (lc.time < maxt)
nb = int(np.ceil(inwindow.sum()/5000))
temp_lc = lc[inwindow]
lc_source.data = {'time': temp_lc.time[::nb],
'flux': temp_lc.flux[::nb]}
def _update_folded_plot(event):
loc = np.argmax(bls_source.data['power'])
best_period = bls_source.data['period'][loc]
best_t0 = bls_source.data['transit_time'][loc]
# Otherwise, we can just update the best_period index
minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end
f = lc.fold(best_period, best_t0)
inwindow = (f.time > minphase) & (f.time < maxphase)
nb = int(np.ceil(inwindow.sum()/10000))
f_source.data = {'phase': f[inwindow].time[::nb],
'flux': f[inwindow].flux[::nb]}
# Function to update the widget
def _update_params(all=False, best_period=None, best_t0=None):
if all:
# If we're updating everything, recalculate the BLS model
minp, maxp = fig_bls.x_range.start, fig_bls.x_range.end
period_values = np.logspace(np.log10(minp), np.log10(maxp), npoints_slider.value)
ok = (period_values > duration_slider.value) & (period_values < maxp)
if ok.sum() == 0:
return
period_values = period_values[ok]
result = model.power(period_values, duration_slider.value)
ok = np.isfinite(result['power']) & np.isfinite(result['duration']) &\
np.isfinite(result['transit_time']) & np.isfinite(result['period'])
bls_source.data = dict(
period=result['period'][ok],
power=result['power'][ok],
duration=result['duration'][ok],
transit_time=result['transit_time'][ok])
loc = np.nanargmax(bls_source.data['power'])
best_period = bls_source.data['period'][loc]
best_t0 = bls_source.data['transit_time'][loc]
minpow, maxpow = bls_source.data['power'].min()*0.95, bls_source.data['power'].max()*1.05
fig_bls.y_range.start = minpow
fig_bls.y_range.end = maxpow
# Otherwise, we can just update the best_period index
minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end
f = lc.fold(best_period, best_t0)
inwindow = (f.time > minphase) & (f.time < maxphase)
nb = int(np.ceil(inwindow.sum()/10000))
f_source.data = {'phase': f[inwindow].time[::nb],
'flux': f[inwindow].flux[::nb]}
mf = model.model(lc.time, best_period, duration_slider.value, best_t0)
mf /= np.median(mf)
mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2)) > 0.9)
model_lc = LightCurve(lc.time[mask], mf[mask])
model_lc_source.data = {'time': np.sort(model_lc.time),
'flux': model_lc.flux[np.argsort(model_lc.time)]}
f_model_lc = model_lc.fold(best_period, best_t0)
f_model_lc = LightCurve([-0.5], [1]).append(f_model_lc)
f_model_lc = f_model_lc.append(LightCurve([0.5], [1]))
f_model_lc_source.data = {'phase': f_model_lc.time,
'flux': f_model_lc.flux}
vertical_line.update(location=best_period)
fig_folded.title.text = 'Period: {} days \t T0: {}{}'.format(
np.round(best_period, 7),
np.round(best_t0, 7), time_format)
text_output.text = "Period: {} days, \t T0: {}{}".format(
np.round(best_period, 7),
np.round(best_t0, 7), time_format)
# Callbacks
def _update_upon_period_selection(attr, old, new):
"""When we select a period we should just update a few things, but we should not recalculate model
"""
if len(new) > 0:
new = new[0]
best_period = bls_source.data['period'][new]
best_t0 = bls_source.data['transit_time'][new]
_update_params(best_period=best_period, best_t0=best_t0)
def _update_model_slider(attr, old, new):
"""If the duration slider is updated, then update the whole model set."""
_update_params(all=True)
def _update_model_slider_EVENT(event):
"""If we update the duration slider, we should update the whole model set.
This is the same as the _update_model_slider but it has a different call signature...
"""
_update_params(all=True)
def _double_period_event():
fig_bls.x_range.start *= 2
fig_bls.x_range.end *= 2
_update_params(all=True)
def _half_period_event():
fig_bls.x_range.start /= 2
fig_bls.x_range.end /= 2
_update_params(all=True)
# Help Hover Call Backs
def _update_folded_plot_help_reset(event):
f_help_source.data['phase'] = [(np.max(f.time) - np.min(f.time)) * 0.98 + np.min(f.time)]
f_help_source.data['flux'] = [(np.max(f.flux) - np.min(f.flux)) * 0.98 + np.min(f.flux)]
def _update_folded_plot_help(event):
f_help_source.data['phase'] = [(fig_folded.x_range.end - fig_folded.x_range.start) * 0.95 + fig_folded.x_range.start]
f_help_source.data['flux'] = [(fig_folded.y_range.end - fig_folded.y_range.start) * 0.95 + fig_folded.y_range.start]
def _update_lc_plot_help_reset(event):
lc_help_source.data['time'] = [(np.max(lc.time) - np.min(lc.time)) * 0.98 + np.min(lc.time)]
lc_help_source.data['flux'] = [(np.max(lc.flux) - np.min(lc.flux)) * 0.9 + np.min(lc.flux)]
def _update_lc_plot_help(event):
lc_help_source.data['time'] = [(fig_lc.x_range.end - fig_lc.x_range.start) * 0.95 + fig_lc.x_range.start]
lc_help_source.data['flux'] = [(fig_lc.y_range.end - fig_lc.y_range.start) * 0.9 + fig_lc.y_range.start]
def _update_bls_plot_help_event(event):
bls_help_source.data['period'] = [bls_source.data['period'][int(npoints_slider.value*0.95)]]
bls_help_source.data['power'] = [(np.max(bls_source.data['power']) - np.min(bls_source.data['power'])) * 0.98
+ np.min(bls_source.data['power'])]
def _update_bls_plot_help(attr, old, new):
bls_help_source.data['period'] = [bls_source.data['period'][int(npoints_slider.value*0.95)]]
bls_help_source.data['power'] = [(np.max(bls_source.data['power']) - np.min(bls_source.data['power'])) * 0.98
+ np.min(bls_source.data['power'])]
# Create all the figures.
fig_folded = make_folded_figure_elements(f, f_model_lc, f_source, f_model_lc_source, f_help_source)
fig_folded.title.text = 'Period: {} days \t T0: {}{}'.format(np.round(best_period, 7), np.round(best_t0, 5), time_format)
fig_bls, vertical_line = make_bls_figure_elements(result, bls_source, bls_help_source)
fig_lc = make_lightcurve_figure_elements(lc, model_lc, lc_source, model_lc_source, lc_help_source)
# Map changes
# If we click a new period, update
bls_source.selected.on_change('indices', _update_upon_period_selection)
# If we change the duration, update everything, including help button for BLS
duration_slider.on_change('value', _update_model_slider)
duration_slider.on_change('value', _update_bls_plot_help)
# If we increase resolution, update everything
npoints_slider.on_change('value', _update_model_slider)
# Make sure the vertical line always goes to the best period.
vertical_line.update(location=best_period)
# If we pan in the BLS panel, update everything
fig_bls.on_event(PanEnd, _update_model_slider_EVENT)
fig_bls.on_event(Reset, _update_model_slider_EVENT)
# If we pan in the LC panel, rebin the points
fig_lc.on_event(PanEnd, _update_light_curve_plot)
fig_lc.on_event(Reset, _update_light_curve_plot)
# If we pan in the Folded panel, rebin the points
fig_folded.on_event(PanEnd, _update_folded_plot)
fig_folded.on_event(Reset, _update_folded_plot)
# Deal with help button
fig_bls.on_event(PanEnd, _update_bls_plot_help_event)
fig_bls.on_event(Reset, _update_bls_plot_help_event)
fig_folded.on_event(PanEnd, _update_folded_plot_help)
fig_folded.on_event(Reset, _update_folded_plot_help_reset)
fig_lc.on_event(PanEnd, _update_lc_plot_help)
fig_lc.on_event(Reset, _update_lc_plot_help_reset)
# Buttons
double_button.on_click(_double_period_event)
half_button.on_click(_half_period_event)
# Layout the widget
doc.add_root(layout([
[fig_bls, fig_folded],
fig_lc,
[Spacer(width=70), duration_slider, Spacer(width=50), npoints_slider],
[Spacer(width=70), double_button, Spacer(width=70), half_button, Spacer(width=300), text_output]
]))
output_notebook(verbose=False, hide_banner=True)
return show(_create_interact_ui, notebook_url=notebook_url)
0
View Source File : test___init__.py
License : MIT License
Project Creator : rthorst
License : MIT License
Project Creator : rthorst
def test___version___type():
assert isinstance(b.__version__, string_types)
def test___version___defined():
0
View Source File : test___init__.py
License : MIT License
Project Creator : rthorst
License : MIT License
Project Creator : rthorst
def test___version___defined():
assert b.__version__ != 'unknown'
def test_license(capsys):