def _make_plot(num_objects=0): source = ColumnDataSource(dict(xs=[], ys=[])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 3), y_range=Range1d(0, 3), min_border=0) renderer = plot.add_glyph(source, MultiLine(xs='xs', ys='ys')) tool = FreehandDrawTool(num_objects=num_objects, renderers=[renderer]) plot.add_tools(tool) plot.toolbar.active_multi = tool code = RECORD("xs", "source.data.xs") + RECORD("ys", "source.data.ys") plot.add_tools(CustomAction(callback=CustomJS(args=dict(source=source), code=code))) plot.toolbar_sticky = False return plot
def initialize(self, plot_id=None): plot = self.plot stream = self.streams[0] if stream.styles: self._create_style_callback(plot.handles['cds'], plot.handles['glyph'], 'xs') poly_tool = FreehandDrawTool( empty_value=stream.empty_value, num_objects=stream.num_objects, renderers=[plot.handles['glyph_renderer']], ) plot.state.tools.append(poly_tool) self._update_cds_vdims() CDSCallback.initialize(self, plot_id)
def initialize(self, plot_id=None): try: from bokeh.models import FreehandDrawTool except: param.main.warning('FreehandDraw requires bokeh >= 0.13.0') return plot = self.plot stream = self.streams[0] poly_tool = FreehandDrawTool( empty_value=stream.empty_value, num_objects=stream.num_objects, renderers=[plot.handles['glyph_renderer']], ) plot.state.tools.append(poly_tool) super(FreehandDrawCallback, self).initialize(plot_id)
def modify_doc(doc): source = ColumnDataSource(dict(xs=[], ys=[])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 3), y_range=Range1d(0, 3), min_border=0) renderer = plot.add_glyph(source, MultiLine(xs='xs', ys='ys')) tool = FreehandDrawTool(num_objects=num_objects, renderers=[renderer]) plot.add_tools(tool) plot.toolbar.active_multi = tool div = Div(text='False') def cb(attr, old, new): if cds_data_almost_equal(new, expected): div.text = 'True' source.on_change('data', cb) code = RECORD("matches", "div.text") plot.add_tools(CustomAction(callback=CustomJS(args=dict(div=div), code=code))) doc.add_root(column(plot, div))
def modify_doc(doc): source = ColumnDataSource(dict(xs=[], ys=[])) renderer = plot.add_glyph(source, MultiLine(xs='xs', ys='ys')) tool = FreehandDrawTool(num_objects=num_objects, renderers=[renderer]) plot.add_tools(tool) plot.toolbar.active_multi = tool div = Div(text='False') def cb(attr, old, new): if cds_data_almost_equal(new, expected): div.text = 'True' source.on_change('data', cb) code = RECORD("matches", "div.text") plot.tags.append( CustomJS(name="custom-action", args=dict(div=div), code=code)) doc.add_root(column(plot, div))
def initialize(self, plot_id=None): plot = self.plot cds = plot.handles['cds'] glyph = plot.handles['glyph'] stream = self.streams[0] if stream.styles: self._create_style_callback(cds, glyph) kwargs = {} if stream.tooltip: kwargs[CUSTOM_TOOLTIP] = stream.tooltip if stream.empty_value is not None: kwargs['empty_value'] = stream.empty_value poly_tool = FreehandDrawTool( num_objects=stream.num_objects, renderers=[plot.handles['glyph_renderer']], **kwargs) plot.state.tools.append(poly_tool) self._update_cds_vdims(cds.data) CDSCallback.initialize(self, plot_id)
from bokeh.plotting import figure, output_file, show from bokeh.models import FreehandDrawTool output_file("tools_box_edit.html") p = figure(x_range=(0, 10), y_range=(0, 10), width=400, height=400, title='Freehand Draw Tool') renderer = p.multi_line([[1, 9]], [[5, 5]], line_width=5, alpha=0.4, color='red') draw_tool = FreehandDrawTool(renderers=[renderer], num_objects=3) p.add_tools(draw_tool) p.toolbar.active_drag = draw_tool show(p)
def create_interact_ui(doc): source = ColumnDataSource( data={ "image": [z], "x": x, "y": y, "dw": [x.max() - x.min()], "dh": [y.max() - y.min()], } ) plot = figure( x_range=(x.min(), x.max()), y_range=(y.min(), y.max()), plot_width=550, plot_height=600 ) palette = get_bokeh_palette(cmap) full_plot = plot.image( image="image", x="x", y="y", dw="dw", dh=y.max() - y.min(), source=source, palette=palette, ) plot.xaxis.axis_label = u"Frequency mod \u0394\u03BD" plot.yaxis.axis_label = "Frequency" slider = b_Slider( start=dnu_min, end=dnu_max, value=(dnu_min + dnu_max) / 2, step=step, title=u"\u0394\u03BD", format="0.000", ) # Slider callback def update_upon_dnu_change(attr, old, new): x, y, z = echelle( freq, power, new, sampling=sampling, ) if scale is not None: if scale is "sqrt": z = np.sqrt(z) elif scale is "log": z = np.log10(z) full_plot.data_source.data["image"] = [z] full_plot.data_source.data["dw"] = [x.max() - x.min()] plot.x_range.start = x.min() plot.x_range.end = x.max() slider.on_change("value", update_upon_dnu_change) # Adjust some toolbar options r = plot.multi_line(line_width=15, alpha=0.2, color="red") plot.add_tools(FreehandDrawTool(renderers=[r])) plot.toolbar.logo = None plot.toolbar.active_drag = None # Layout all of the plots widgets_and_figures = column(slider, plot) doc.add_root(widgets_and_figures)
def JSandDivDoublePlotWithToggle(x_axis, y_axisRaw, y_axisBin, change_points=[], title="", TOOLTIPS=[], transList=[], alarmList=[], abnormalList=[]): if TOOLTIPS: plot = figure(tooltips=TOOLTIPS, title=title, x_axis_label='Timestamp', y_axis_label='Flux', sizing_mode="stretch_both") else: TOOLTIPS = [ ("index", "$index"), ("(x,y)", "(@x{0,0}, @y{0,0.000}"), ] plot = figure(tooltips=TOOLTIPS, title=title, x_axis_label='Timestamp', y_axis_label='Flux', sizing_mode="stretch_both") rawSource = ColumnDataSource(data=dict(x=x_axis, y=y_axisRaw)) rawLine = plot.line('x', 'y', source=rawSource, line_alpha=0.4, color='black', line_width=2, legend_label="Raw") rawCircle = plot.circle(x_axis, y_axisRaw, color="black", fill_alpha=0.4, legend_label="Raw", size=2) toggle1 = Toggle(label="Raw Data", button_type="success", active=True) toggle1.js_link('active', rawLine, 'visible') toggle1.js_link('active', rawCircle, 'visible') binSource = ColumnDataSource(data=dict(x=x_axis, y=y_axisBin)) binLine = plot.line('x', 'y', source=binSource, color='red', line_width=4, legend_label="DyBin") toggle2 = Toggle(label="Dynamic bin", button_type="success", active=True) toggle2.js_link('active', binLine, 'visible') if change_points: for change_point in change_points: change_point_span = Span(location=float(change_point), dimension='height', line_color='#009E73', line_dash='dashed', line_width=1) plot.add_layout(change_point_span) toggle3 = Toggle(label="AnswerTran", button_type="success", active=True) if transList: for trans in transList: start_point = int(trans[0]) end_point = int(trans[1]) tran_box = BoxAnnotation(left=x_axis[start_point], right=x_axis[end_point], fill_alpha=0.2, fill_color="#F0E442") L_span = Span(location=x_axis[start_point], dimension='height', line_color='#a2ff00', line_dash='4 4', line_width=2) R_span = Span(location=x_axis[end_point], dimension='height', line_color='#a2ff00', line_dash='4 4', line_width=2) plot.add_layout(tran_box) plot.add_layout(L_span) plot.add_layout(R_span) toggle3.js_link('active', tran_box, 'visible') toggle3.js_link('active', L_span, 'visible') toggle3.js_link('active', R_span, 'visible') toggle4 = Toggle(label="Alarm", button_type="success", active=True) if alarmList: for alarm in alarmList: # alarm : start,end,alarm start_point = int(alarm['start']) end_point = int(alarm['end']) alarm_point = int(alarm['alarm']) alarm_box = BoxAnnotation(left=x_axis[start_point], right=x_axis[end_point], fill_alpha=0.2, fill_color="#F0E442") alarm_span = Span(location=x_axis[alarm_point], dimension='height', line_color='#a2ff00', line_dash='4 4', line_width=2) plot.add_layout(alarm_box) plot.add_layout(alarm_span) toggle4.js_link('active', alarm_box, 'visible') toggle4.js_link('active', alarm_span, 'visible') toggle5 = Toggle(label="F-test", button_type="success", active=True) if abnormalList: for abnormal in abnormalList: start_point = int(abnormal[0]) end_point = int(abnormal[1]) abnormal_box = BoxAnnotation(left=x_axis[start_point], right=x_axis[end_point], fill_alpha=0.2, fill_color="#F0E442") L_abnormal_span = Span(location=x_axis[start_point], dimension='height', line_color='#a2ff00', line_dash='4 4', line_width=2) R_abnormal_span = Span(location=x_axis[end_point], dimension='height', line_color='#a2ff00', line_dash='4 4', line_width=2) plot.add_layout(abnormal_box) plot.add_layout(L_abnormal_span) plot.add_layout(R_abnormal_span) toggle5.js_link('active', abnormal_box, 'visible') toggle5.js_link('active', L_abnormal_span, 'visible') toggle5.js_link('active', R_abnormal_span, 'visible') plot.legend.border_line_width = 3 plot.legend.click_policy = "hide" plot.legend.border_line_color = "navy" plot.legend.border_line_alpha = 0. plot.xaxis.axis_label_text_font_size = "16pt" plot.xaxis.major_label_text_font_size = "13pt" plot.yaxis.axis_label_text_font_size = "16pt" plot.yaxis.major_label_text_font_size = "13pt" drawSource = ColumnDataSource(data=dict(x=[], y=[])) r = plot.multi_line('xs', 'ys', source=drawSource) tool = FreehandDrawTool(renderers=[r]) plot.add_tools(tool) js, div = components( layout([plot], row(toggle1, toggle2, toggle3, toggle4, toggle5, sizing_mode='scale_width'), sizing_mode="stretch_both")) return js, div
def plot_image(filename, save=False): hdu = fits.open(filename) dheader = dict(hdu[0].header) for k in dheader: if len(k) >= 2: print(f"{k}: {dheader[k]}") print(hdu.info()) data = hdu[0].data # quick hot pixel/ cosmic ray mask mask, cdata = detect_cosmics( data, psfmodel='gauss', psffwhm=4, psfsize=2*round(4)+1, # just a guess sepmed=False, sigclip = 4.25, niter=3, objlim=10, cleantype='idw', verbose=False ) # show how many pixels are saturated SATURATION = 2**(hdu[0].header['bitpix']) mmask = cdata >= SATURATION*0.9 labels, ngroups = label(mmask) print('Saturated Areas:',ngroups) labeli, counts = np.unique(labels, return_counts=True) bad_pix = {'x':[], 'y':[], 'value':[]} # loop through each group to find position for i in range(1,labeli[-1]+1): imask = labels == i yc,xc = np.argwhere(imask).mean(0) bad_pix['x'].append(xc) bad_pix['y'].append(yc) bad_pix['value'].append(cdata[imask].mean()) pprint(bad_pix) # create a figure with text on mouse hover\ print("Saturated pixels are marked with red. These are pixels which have exceeded the maximum value for brightness, and are thus not suitable for use as comparison stars.") fig = figure(tooltips=[("x", "$x"), ("y", "$y"), ("value", "@image")], plot_width=800, plot_height=800, tools=[PanTool(),BoxZoomTool(),WheelZoomTool(),ResetTool(),HoverTool()]) fig.x_range.range_padding = fig.y_range.range_padding = 0 r = fig.multi_line('x', 'y', source={'x':[],'y':[]},color='white',line_width=3) fig.add_tools(FreehandDrawTool(renderers=[r])) ##TODO: add colorbar # set up a colobar + data range color_mapper = LogColorMapper(palette="Cividis256", low=np.percentile(data, 55), high=np.percentile(data, 99)) # must give a vector of image data for image parameter fig.image( image=[cdata], x=0, y=0, dw=hdu[0].data.shape[1], dh=hdu[0].data.shape[0], level="image", color_mapper=color_mapper ) # plot saturated stars fig.x(bad_pix['x'], bad_pix['y'], size=25, color='red', line_width=3) fig.x(bad_pix['x'], bad_pix['y'], size=25, color='white', line_width=1) # TODO figure out hover value fig.grid.grid_line_width = 0.5 color_bar = ColorBar(color_mapper=color_mapper, ticker=LogTicker(), label_standoff=12, border_line_color=None, location=(0,0)) fig.add_layout(color_bar, 'right') if save: output_file("interactivefits.html") else: show(fig)