def make_sidebar(): global sidebar, master_selector master_selector = Select(title="MASTOR SELECTOR:", value="test", options=["test", 'sandbox', 'template', "timeseries", "mdr_history"]) def selector_func(attrname, old, new): new_master_plot( master_selector.value ) master_selector.on_change('value', selector_func ) sidebar = vform(master_selector)
def layout(): date_select = DateRangeSlider( name="period", title="Period:", value=(start, end), bounds=(bounds_start, bounds_end), value_labels='show', range=(dict(days=1), None)) date_select.on_change('value', on_date_change) country_select = Select(title="Host Site Country:", value="World", options=country_choices) country_select.on_change('value', on_country_change) controls = VBoxModelForm(_children=[Paragraph(text="Date Range"), Paragraph(text=""), # spacing hack Paragraph(text=""), date_select, country_select]) vboxsmall = VBoxModelForm(_children=[controls, source_par]) #hbox1 = HBox(children=[job_loc_plot_builder(), vboxsmall]) #hbox2 = HBox(children=[weekday_builder(), jobtype_builder()]) #layout = VBox(children=[hbox1, hbox2]) layout = VBox(children=[vboxsmall]) return layout
def compose_layout(self): """Compose the layout ot the app, the main elements are the widgets to select the dataset, the metric, a div for the title, a plot and a table """ # Load metrics and datasets self.metrics = get_metrics(default='AM1') self.datasets = get_datasets(default='cfht') # Get args from the app URL or use defaults args = get_url_args(doc=curdoc, defaults={'metric': self.metrics['default']}) self.selected_dataset = args['ci_dataset'] self.selected_metric = args['metric'] # get specifications for the selected metric self.specs = get_specs(self.selected_metric) self.selected_window = args['window'] # dataset select widget dataset_select = Select(title="Data Set:", value=self.selected_dataset, options=self.datasets['datasets'], width=100) dataset_select.on_change("value", self.on_dataset_change) # thresholds are used to make plot annotations self.configure_thresholds() # metric select widget metric_select = Select(title="Metric:", value=self.selected_metric, options=self.metrics['metrics'], width=100) metric_select.on_change("value", self.on_metric_change) self.data = \ get_meas_by_dataset_and_metric(self.selected_dataset, self.selected_metric, self.selected_window) self.update_data_source() self.make_plot() self.make_table() if len(self.data['values']) < 1: self.loading.text = "No data to display" else: self.loading.text = "" self.layout = column(row(widgetbox(metric_select, width=150), widgetbox(dataset_select, width=150)), widgetbox(self.title, width=1000), self.plot, widgetbox(self.table_title, width=1000), self.table)
def create_layout(): year_select = Select(title="Year:", value="2010", options=years) location_select = Select(title="Location:", value="World", options=locations) year_select.on_change('value', on_year_change) location_select.on_change('value', on_location_change) controls = WidgetBox(children=[year_select, location_select],height=150,width=600) layout = Column(children=[controls, pyramid(), population()]) return layout
def create_layout(): year_select = Select(title="Year:", value="2010", options=years) location_select = Select(title="Location:", value="World", options=locations) year_select.on_change('value', on_year_change) location_select.on_change('value', on_location_change) controls = HBox(children=[year_select, location_select]) layout = VBox(children=[controls, pyramid(), population()]) return layout
def create_layout(self): from bokeh.models.widgets import Select, HBox, VBox years = list(map(str, sorted(self.df.Year.unique()))) locations = sorted(self.df.Location.unique()) year_select = Select(title="Year:", value="2010", options=years) location_select = Select(title="Location:", value="World", options=locations) year_select.on_change('value', self.on_year_change) location_select.on_change('value', self.on_location_change) controls = HBox(year_select, location_select) self.layout = VBox(controls, self.plot)
def main(): state_xs, state_ys = get_us_state_outline() left, right = minmax(state_xs) bottom, top = minmax(state_ys) plot = Figure(title=TITLE, plot_width=1000, plot_height=700, tools="pan, wheel_zoom, box_zoom, reset", x_range=Range1d(left, right), y_range=Range1d(bottom, top), x_axis_label='Longitude', y_axis_label='Latitude') plot_state_outline(plot, state_xs, state_ys) density_overlay = DensityOverlay(plot, left, right, bottom, top) density_overlay.draw() grid_slider = Slider(title="Details", value=density_overlay.gridcount, start=10, end=100, step=10) grid_slider.on_change("value", density_overlay.grid_change_listener) radiance_slider = Slider(title="Min. Radiance", value=density_overlay.radiance, start=np.min(density_overlay.rad), end=np.max(density_overlay.rad), step=10) radiance_slider.on_change("value", density_overlay.radiance_change_listener) listener = ViewListener(plot, density_overlay, name="viewport") plot.x_range.on_change("start", listener) plot.x_range.on_change("end", listener) plot.y_range.on_change("start", listener) plot.y_range.on_change("end", listener) backends = ["CPU", "HSA"] default_value = backends[kde.USE_HSA] backend_select = Select(name="backend", value=default_value, options=backends) backend_select.on_change('value', density_overlay.backend_change_listener) doc = curdoc() doc.add(VBox(children=[plot, grid_slider, radiance_slider, backend_select])) doc.add_periodic_callback(density_overlay.periodic_callback, 0.5)
class DataViewer(): def __init__(self): img = imageio.imread("gray.png").astype(np.uint8) self.target = np.empty(img.shape[:2], dtype=np.uint32) view = self.target.view(dtype=np.uint8).reshape((img.shape[0], img.shape[1], 4)) view[:, :, :3] = img view[:, :, 3] = 255 self.fig = self.define_figure('image') self.source = ColumnDataSource(data={"image": [self.target], "dh": [self.target.shape[0]], "dw": [self.target.shape[1]]}) self.regist_image(self.fig, self.source) self.select = Select(title="Option:", value="gray.png", options=["gray.png", "white.png", "black.png", "julia.jpeg"]) self.plot = column(self.select, self.fig) self.select.on_change("value", self.update_image) def define_figure(self, title): return figure(title=title, match_aspect=True, tools="",) def regist_image(self, fig, source): fig.image_rgba('image', x=0, y=0, dh="dh", dw="dw", source=source) def update_image(self, attr, old, new): print(attr, old, new) img = imageio.imread(new).astype(np.uint8) img_ = np.empty(img.shape[:2], dtype=np.uint32) view = img_.view(dtype=np.uint8).reshape((img.shape[0], img.shape[1], 4)) view[:, :, :3] = img view[:, :, 3] = 255 self.fig.title.text = new self.source.data = {"image": [img_], "dh": [img_.shape[0]], "dw": [img_.shape[1]]}
("Drunk%", "@state_percent{1.11}" + "%"), ("Speeding%", "@state_percent_sp{1.11}" + "%")])) select = Select(title="Color States By:", value="None", options=["None", "Drunk%", "Speeding%"]) def update_color(attrname, old, new): if select.value == "Drunk%": patch_source.data["colors"] = drunk_colors patch_source.data["alpha"] = [.3]*len(state_names) elif select.value == "Speeding%": patch_source.data["colors"] = speeding_colors patch_source.data["alpha"] = [.3]*len(state_names) else: patch_source.data["colors"] = no_colors patch_source.data["alpha"] = [0]*len(state_names) select.on_change('value', update_color) # -------------------------------------- def gen_dict(df): return dict( x=df["x"], y=df["y"], r=df["r"], MONTH=df["MONTH"], DAY=df["DAY"], YEAR=df["YEAR"], FATALS=df["FATALS"], DRUNK_DR=df["DRUNK_DR"], SP=df["SP"], WEATHER=df["WEATHER"]
class MultipletAnalysis: MULTIPLET_ERROR = 1000000 MULTIPLETS = { 's': { 'table': [1], 'sum': 1, 'j': [] }, 'd': { 'table': [1, 1], 'sum': 2, 'j': [[0, 1]] }, 't': { 'table': [1, 2, 1], 'sum': 3, 'j': [[0, 1]] }, 'q': { 'table': [1, 3, 3, 1], 'sum': 4, 'j': [[0, 1]] }, 'p': { 'table': [1, 4, 6, 4, 1], 'sum': 5, 'j': [[0, 1]] }, 'h': { 'table': [1, 5, 10, 10, 5, 1], 'sum': 6, 'j': [[0, 1]] }, 'hept': { 'table': [1, 6, 15, 20, 15, 6, 1], 'sum': 7, 'j': [[0, 1]] }, 'dd': { 'table': [[1, 1], [1, 1]], 'sum': 4, 'j': [[0, 1], [0, 2]] }, 'ddd': { 'table': [[1, 1], [1, 1], [1, 1], [1, 1]], 'sum': 8, 'j': [[0, 1], [0, 2], [0, 4]] }, 'dt': { 'table': [[1, 2, 1], [1, 2, 1]], 'sum': 6, 'j': [[0, 1], [0, 3]] }, 'td': { 'table': [1, 1, 2, 2, 1, 1], 'sum': 6, 'j': [[0, 1], [0, 2]] }, 'ddt': { 'table': [[1, 2, 1], [1, 2, 1], [1, 2, 1], [1, 2, 1]], 'sum': 12, 'j': [[0, 1], [0, 3], [0, 6]] } } def __init__(self, logger, spectrumId, dic, udic, pdata, dataSource, peakPicking, integration, reference): self.logger = logger self.id = spectrumId self.dic = dic self.udic = udic self.pdata = pdata self.dataSource = dataSource self.peakPicking = peakPicking peakPicking.addObserver(self.recalculateAllMultipletsForPeaks) self.integration = integration self.integration.addObserver(lambda ratio: self.updateIntervals( ratio, self.sources['table'].data['integral'])) reference.addObserver(lambda n: referenceObserver(self, n)) self.sources = dict() def create(self): self.oldData = dict(peaks=[], classes=[]) self.sources['table'] = ColumnDataSource( dict(xStart=[], xStop=[], name=[], classes=[], j=[], h=[], integral=[], peaks=[], top=[], bottom=[])) columns = [ TableColumn(field="xStart", title="start", formatter=NumberFormatter(format="0.00")), TableColumn(field="xStop", title="stop", formatter=NumberFormatter(format="0.00")), TableColumn(field="name", title="Name"), TableColumn(field="classes", title="Class"), TableColumn(field="j", title="J"), TableColumn(field="h", title="H", formatter=NumberFormatter(format="0")), TableColumn(field="integral", title="Integral", formatter=NumberFormatter(format="0.00")) ] self.dataTable = DataTable(source=self.sources['table'], columns=columns, reorderable=False, width=500) self.sources['table'].on_change( 'selected', lambda attr, old, new: self.rowSelect(new['1d']['indices'])) self.sources['table'].on_change( 'data', lambda attr, old, new: self.dataChanged(new)) self.manual = CustomButton( label="Multiplet Analysis", button_type="primary", width=250, error="Please select area using the multiplet analysis tool.") self.manual.on_click(self.manualMultipletAnalysis) self.createTool() self.title = Div(text="<strong>Edit Multiplet:</strong>", width=500) self.classes = Select(title="Class:", options=[ "m", "s", "d", "t", "q", "p", "h", "hept", "dd", "ddd", "dt", "td", "ddt" ], width=100, disabled=True) self.classes.on_change( 'value', lambda attr, old, new: self.manualChange('classes', new)) self.integral = TextInput(title="Integral:", value="", placeholder="Integral", width=175, disabled=True) self.integral.on_change( 'value', lambda attr, old, new: self.changeIntegral(new)) self.j = TextInput(title='J-list:', value="", width=175, disabled=True) self.j.on_change('value', lambda attr, old, new: self.manualChange('j', new)) self.delete = Button(label="Delete Multiplet", button_type="danger", width=500, disabled=True) self.delete.on_click(self.deleteMultiplet) self.reportTitle = Div(text="<strong>Multiplet Report:</strong>") self.report = Paragraph(width=500) def createTool(self): callback = CustomJS(args=dict(button=self.manual), code=""" /// get BoxSelectTool dimensions from cb_data parameter of Callback var geometry = cb_data['geometry']; button.data = { x0: geometry['x0'], x1: geometry['x1'], y: geometry['y'], y0: geometry['y0'], y1: geometry['y1'] }; // Callback to the backend button.clicks++; """) self.tool = BothDimensionsSelectTool(tool_name="Multiplet Analysis", icon="my_icon_multiplet_analysis", callback=callback, id="multipletAnalysisTool") def rowSelect(self, ids): if len(ids) == 1: self.selected = ids[0] # Enable options self.classes.disabled = False self.classes.value = self.sources['table'].data['classes'][ self.selected] self.integral.disabled = False self.integral.value = str( self.sources['table'].data['integral'][self.selected]) self.j.disabled = False self.j.value = self.sources['table'].data['j'][self.selected] self.delete.disabled = False self.peakPicking.selectByPPM( self.sources['table'].data['peaks'][self.selected]) else: deselectRows(self.sources['table']) def recalculateAllMultipletsForPeaks(self): data = self.sources['table'].data patch = dict(classes=[], j=[]) for pos, start, stop in zip(range(len(data['xStart'])), data['xStart'], data['xStop']): ppm = self.peakPicking.getPPMInSpace(start, stop) peaks = self.peakPicking.getPeaksInSpace(start, stop) multiplet = self.predictMultiplet(peaks) patch['classes'].append((pos, multiplet)) patch['j'].append((pos, self.calcJ(ppm, multiplet))) self.sources['table'].patch(patch) def manualMultipletAnalysis(self, dimensions): self.peakPicking.manualPeakPicking(dimensions, notify=False) # Check if empty if not self.peakPicking.peaksIndices: return integral = round(self.integration.calcIntegral(dimensions), 3) peaks = [self.pdata[i] for i in self.peakPicking.peaksIndices] multiplet = self.predictMultiplet(peaks) ppm = sorted([ self.dataSource.data['ppm'][i] for i in self.peakPicking.peaksIndices ]) data = { 'xStart': [dimensions['x0']], 'xStop': [dimensions['x1']], 'name': [ 'A' if not self.sources['table'].data['name'] else chr(ord(self.sources['table'].data['name'][-1]) + 1) ], 'classes': [multiplet], 'j': [self.calcJ(ppm, multiplet)], 'h': [round(integral)], 'integral': [integral], 'peaks': [ppm], 'top': [dimensions['y1']], 'bottom': [dimensions['y0']] } # Add to DataTable self.sources['table'].stream(data) # Select the multiplet in the table self.sources['table'].selected = { '0d': { 'glyph': None, 'indices': [] }, '1d': { 'indices': [len(self.sources['table'].data['xStart']) - 1] }, '2d': { 'indices': {} } } def calcJ(self, ppm, multiplet): if multiplet in self.MULTIPLETS: js = self.MULTIPLETS[multiplet]['j'] calc = sorted([ round(abs(ppm[j[0]] - ppm[j[1]]) * getFrequency(self.udic), 1) for j in js ], reverse=True) return ', '.join(str(j) for j in calc) + ' Hz' return "" def predictMultiplet(self, peaks): for key, value in self.MULTIPLETS.iteritems(): if len(peaks) == value['sum'] and self.checkMultiplet( value['table'], peaks): return key return "m" def checkMultiplet(self, multiplet, peaks): if not multiplet: return True # check list if isinstance(multiplet[0], list): return self.checkMultiplet(multiplet[0], peaks) and self.checkMultiplet( multiplet[1:], peaks) else: return self.checkMultiplicity(multiplet, peaks) def checkMultiplicity(self, multiplet, peaks): if not multiplet: return True for (m, peak) in zip(multiplet[1:], peaks[1:]): low = m * peaks[0] - self.MULTIPLET_ERROR high = m * peaks[0] + self.MULTIPLET_ERROR if peak < low or peak > high: return False return True def dataChanged(self, data): self.updateMultipletReport() label = getLabel(self.udic) if label == "1H": newData = [(np.median(peaks), c) for (peaks, c) in zip(data['peaks'], data['classes'])] oldData = [ (np.median(peaks), c) for (peaks, c) in zip(self.oldData['peaks'], self.oldData['classes']) ] added = list(set(newData) - set(oldData)) removed = list(set(oldData) - set(newData)) SpectrumDB.RemovePeaks(self.id, removed) SpectrumDB.AddPeaks(self.id, added) self.oldData = { 'peaks': [i[0] for i in newData], 'classes': [i[1] for i in newData] } def updateMultipletReport(self): label = getLabel(self.udic) text = "" if label == "1H": data = self.sources['table'].data text = getMetadata(self.dic, self.udic) + " δ = " + ", ".join( ("{:0.2f}".format(np.median(peaks)) if classes != 'm' else "{:0.2f}-{:0.2f}".format(peaks[-1], peaks[0])) + " ({}, ".format(classes) + ("J={}, ".format(j) if classes != 'm' and classes != 's' else "") + "{:d}H)".format(int(h)) for (peaks, classes, j, h) in sorted( zip(data['peaks'], data['classes'], data['j'], data['h']), reverse=True) if h > 0) + "." self.report.text = text def manualChange(self, key, new): if self.sources['table'].data[key][self.selected] != new: patch = {key: [(self.selected, new)]} self.sources['table'].patch(patch) def changeIntegral(self, new): try: new = float(new) data = self.sources['table'].data['integral'] old = data[self.selected] ratio = new / old self.updateIntervals(ratio, data) self.integration.updateIntervals( ratio, self.integration.sources['table'].data) except: pass def updateIntervals(self, ratio, data): h, integral = [], [] for pos, val in zip(xrange(len(data)), data): newIntegral = val * ratio h.append((pos, round(newIntegral))) integral.append((pos, newIntegral)) self.sources['table'].patch(dict(h=h, integral=integral)) def deleteMultiplet(self): xStart = list(self.sources['table'].data['xStart']) xStop = list(self.sources['table'].data['xStop']) name = list(self.sources['table'].data['name']) classes = list(self.sources['table'].data['classes']) j = list(self.sources['table'].data['j']) h = list(self.sources['table'].data['h']) integral = list(self.sources['table'].data['integral']) peaks = list(self.sources['table'].data['peaks']) top = list(self.sources['table'].data['top']) bottom = list(self.sources['table'].data['bottom']) xStart.pop(self.selected) xStop.pop(self.selected) name.pop(self.selected) classes.pop(self.selected) j.pop(self.selected) h.pop(self.selected) integral.pop(self.selected) peaks.pop(self.selected) top.pop(self.selected) bottom.pop(self.selected) self.sources['table'].data = { 'xStart': xStart, 'xStop': xStop, 'name': name, 'classes': classes, 'j': j, 'h': h, 'integral': integral, 'peaks': peaks, 'top': top, 'bottom': bottom } deselectRows(self.sources['table']) self.disableOptions() def disableOptions(self): self.classes.disabled = True self.integral.disabled = True self.j.disabled = True self.delete.disabled = True def draw(self, plot): self.tool.addToPlot(plot)
class StockApp(VBox): extra_generated_classes = [["StockApp", "StockApp", "VBox"]] jsmodel = "VBox" Y = Instance(ColumnDataSource) # plots hist1 = Instance(Plot) hist2 = Instance(Plot) hist3 = Instance(Plot) # data source source = Instance(ColumnDataSource) risk_source = Instance(ColumnDataSource) # layout boxes mainrow = Instance(HBox) ticker1_box = Instance(HBox) ticker2_box = Instance(HBox) ticker3_box = Instance(HBox) ticker4_box = Instance(HBox) ticker5_box = Instance(HBox) second_row = Instance(HBox) histrow = Instance(HBox) # inputs ticker1 = String(default="1.2*(1.1-x)") ticker1p = String(default="-1.2") ticker2 = String(default="4.0") ticker2p = String(default="0.0") ticker3 = String(default="500") ticker3_1 = String(default="252") ticker3_2 = String(default="0.01") ticker4 = String(default="100") ticker4_1 = String(default="1.01") ticker4_2 = String(default="Milstein") button = String(default="") ticker1_select = Instance(TextInput) ticker1p_select = Instance(TextInput) ticker2_select = Instance(TextInput) ticker2p_select = Instance(TextInput) ticker3_select = Instance(TextInput) ticker3_1_select = Instance(TextInput) ticker3_2_select = Instance(TextInput) ticker4_select = Instance(TextInput) ticker4_1_select = Instance(TextInput) ticker4_2_select = Instance(Select) button_select = Instance(TextInput) input_box = Instance(VBoxForm) def __init__(self, *args, **kwargs): super(StockApp, self).__init__(*args, **kwargs) self._dfs = {} @classmethod def create(cls): """ This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ # create layout widgets obj = cls() obj.mainrow = HBox() obj.ticker1_box = HBox(width=500) obj.ticker2_box = HBox(width=500) obj.ticker3_box = HBox(width=467) obj.ticker4_box = HBox(width=500) obj.ticker5_box = HBox(width=500) obj.second_row = HBox() obj.histrow = HBox() obj.input_box = VBoxForm(width=600) # create input widgets obj.make_inputs() # outputs #obj.make_source() obj.main_mc(252,500,0.01,'Milstein',1.01) obj.make_plots() # layout obj.set_children() return obj def make_inputs(self): self.ticker1_select = TextInput( name='ticker1', title='Drift Function:', value='1.2*(1.1-x)', ) self.ticker1p_select = TextInput( name='ticker1p', title='Drift Derivative:', value='-1.2', ) self.ticker2_select = TextInput( name='ticker2', title='Volatility Function:', value='4.0', ) self.ticker2p_select = TextInput( name='ticker2p', title='Volatility Derivative:', value='0.0', ) self.ticker3_select = TextInput( name='ticker3', title='Number of Paths:', value='500' ) self.ticker3_1_select = TextInput( name='ticker3_1', title='Number of Points:', value='252' ) self.ticker3_2_select = TextInput( name='ticker3_2', title='Time Step:', value='0.01' ) self.ticker4_select = TextInput( name='ticker4', title='Histogram Line:', value='100' ) self.ticker4_1_select = TextInput( name='ticker4_1', title='Initial Value:', value='1.01' ) self.ticker4_2_select = Select( name='ticker4_2', title='MC Scheme:', value='Milstein', options=['Euler','Milstein', 'Pred/Corr'] ) self.button_select = TextInput( name='button', title='Type any word containing "run" to run Simulation ', value = '' ) def make_source(self): self.source = ColumnDataSource(data=self.Y) def main_mc(self,num_pts,num_paths, delta_t, method, Y0): def a(x): return eval(self.ticker1) def ap(x): return eval(self.ticker1p) def b(x): return eval(self.ticker2) def bp(x): return eval(self.ticker2p) rpaths = np.random.normal(0, delta_t, size=(num_pts,num_paths)) Y = np.array([[Y0]*num_paths]) dt_vec = np.array([delta_t]*num_paths) if method == 'Milstein': for i in xrange(0,num_pts): tY = Y[-1,:] dW = rpaths[i,:] Y = np.vstack([Y, tY + a(tY)*dt_vec + b(tY)*dW + 0.5*b(tY)*bp(tY)*(dW*dW-dt_vec)]) elif method == 'Pred/Corr': # Predictor corrector method is taken from equation 2.6 in this paper: # http://www.qfrc.uts.edu.au/research/research_papers/rp222.pdf rpaths2 = np.random.normal(0, delta_t, size=(num_pts,num_paths)) for i in xrange(0,num_pts): tY = Y[-1,:] Ybar = tY + a(tY)*dt_vec + b(tY)*rpaths[i,:] abar_before = a(tY) - 0.5*b(tY)*bp(tY) abar_after = a(Ybar) - 0.5*b(Ybar)*bp(Ybar) Y = np.vstack([Y, tY + 0.5*(abar_before + abar_after)*dt_vec + 0.5*(b(tY)+b(Ybar))*rpaths2[i,:]]) else: # default to Euler Scheme for i in xrange(0,num_pts): tY = Y[-1,:] Y = np.vstack([Y, tY + a(tY)*dt_vec + b(tY)*rpaths[i,:]]) return Y # return simulated paths def path_plot(self): num_paths_plot = min(50,int(self.ticker3)) hist_point = int(self.ticker4) #print 'Hist Point ', hist_point Y = self.Y.as_matrix() pltdat = Y[:,0:num_paths_plot] mY, MY = min(Y[hist_point,:]), max(Y[hist_point,:]) plt.plot(pltdat, alpha=0.1, linewidth=1.8) sns.tsplot(pltdat.T,err_style='ci_band', ci=[68,95,99], alpha=1, \ linewidth = 2.5, color='indianred') #sns.tsplot(pltdat.T,err_style='ci_band', ci=[68,95,99,99.99999], alpha=1, \ # linewidth = 2.5, condition='Mean Path', color='indianred') plt.plot([hist_point, hist_point], [0.99*mY, 1.01*MY], 'k-',label='Time Series Histogram') plt.xlabel('Time Step') plt.ylabel('Price') #plt.legend() p = mpl.to_bokeh() p.title = 'Mean Path (Red), MC Paths (Background) and Density Line (Black)' p.title_text_font_size= str(TITLE_SIZE)+'pt' return p def hist_den_plot(self): Y = self.Y.as_matrix() hist_point = int(self.ticker4) delta_t = float(self.ticker3_2) data = Y[hist_point,:] sns.distplot(data, color='k', hist_kws={"color":"b"}, norm_hist=True) #sns.distplot(data, color='k', hist_kws={"color":"b"}) plt.hist(data) plt.title('Distribution at T = ' + str(np.round(delta_t*hist_point,4)) + ' with Mean: ' +str(np.round(np.mean(data),4)) + ' and Std Dev: ' + str(np.round(np.std(data),4))) plt.xlabel('Price Bins') plt.ylabel('Bin Count') p = mpl.to_bokeh() p.title_text_font_size= str(TITLE_SIZE)+'pt' return p def mc_results(self): # Compute Monte Carlo results Y = self.Y.as_matrix() Y0 = float(self.ticker4_1) hist_point = int(self.ticker4) num_paths = int(self.ticker3) center_point = np.mean(Y[hist_point,:]) stkgrid = np.linspace(0.5*center_point,1.5*center_point,100) meanlst = np.array([]) stdlst = np.array([]) paylst = np.array([]) for stk in stkgrid: meanlst = np.append(meanlst, np.mean(payoff(Y[hist_point,:],stk))) stdlst = np.append(stdlst,np.std(payoff(Y[hist_point,:],stk))/np.sqrt(num_paths)) plt.plot(stkgrid,meanlst+2*stdlst, 'g-') plt.plot(stkgrid,meanlst-2*stdlst,'g-',label='2-Sig Error') plt.plot(stkgrid,meanlst+stdlst,'r-') plt.plot(stkgrid,meanlst-stdlst,'r-',label='1-Sig Error') plt.plot(stkgrid,meanlst,'b',label='Mean') plt.title('MC Option Price (Blue) with 1-Sig (Red) and 2-Sig (Green) Errors') plt.xlabel('Strike') plt.ylabel('Value') p = mpl.to_bokeh() p.title_text_font_size= str(TITLE_SIZE)+'pt' return p def hist_plot(self): histdf = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD')) #pltdf = self.source.to_df().set_index('date').dropna() #qlow, qhigh = mquantiles(pltdf[ticker],prob=[0.01,0.99]) #tdf = pltdf[ticker] #histdf = tdf[((tdf > qlow) & (tdf < qhigh))] hist, bins = np.histogram(histdf, bins=50) width = 0.7 * (bins[1] - bins[0]) center = (bins[:-1] + bins[1:]) / 2 start = bins.min() end = bins.max() top = hist.max() p = figure( title=' Histogram', plot_width=600, plot_height=400, tools="", title_text_font_size="16pt", x_range=[start, end], y_range=[0, top], x_axis_label = ' Bins', y_axis_label = 'Bin Count' ) p.rect(center, hist / 2.0, width, hist) return p def make_plots(self): self.hist_plots() def hist_plots(self): self.hist1 = self.path_plot() self.hist2 = self.hist_den_plot() self.hist3 = self.mc_results() def set_children(self): self.children = [self.mainrow, self.second_row] self.mainrow.children = [self.input_box, self.hist1] self.second_row.children = [self.hist2, self.hist3] self.input_box.children = [self.ticker1_box, self.ticker2_box, self.ticker3_box,self.ticker4_box,self.ticker5_box] self.ticker1_box.children =[self.ticker1_select, self.ticker1p_select] self.ticker2_box.children =[self.ticker2_select, self.ticker2p_select] self.ticker3_box.children =[self.ticker3_select, self.ticker3_1_select, self.ticker3_2_select] self.ticker4_box.children =[self.ticker4_select, self.ticker4_1_select, self.ticker4_2_select] self.ticker5_box.children =[self.button_select] def input_change(self, obj, attrname, old, new): if obj == self.ticker4_2_select: self.ticker4_2 = new if obj == self.ticker4_1_select: self.ticker4_1 = new if obj == self.ticker4_select: self.ticker4 = new if obj == self.ticker3_2_select: self.ticker3_2 = new if obj == self.ticker3_1_select: self.ticker3_1 = new if obj == self.ticker3_select: self.ticker3 = new if obj == self.ticker2p_select: self.ticker2p = new if obj == self.ticker2_select: self.ticker2 = new if obj == self.ticker1p_select: self.ticker1p = new if obj == self.ticker1_select: self.ticker1 = new if obj == self.button_select: self.button = new if 'run' in self.button: self.make_source() self.make_plots() self.set_children() curdoc().add(self) #self.make_source() #self.make_plots() #self.set_children() #curdoc().add(self) def setup_events(self): super(StockApp, self).setup_events() if self.ticker1_select: self.ticker1_select.on_change('value', self, 'input_change') if self.ticker1p_select: self.ticker1p_select.on_change('value', self, 'input_change') if self.ticker2_select: self.ticker2_select.on_change('value', self, 'input_change') if self.ticker2p_select: self.ticker2p_select.on_change('value', self, 'input_change') if self.ticker3_select: self.ticker3_select.on_change('value', self, 'input_change') if self.ticker3_1_select: self.ticker3_1_select.on_change('value', self, 'input_change') if self.ticker3_2_select: self.ticker3_2_select.on_change('value', self, 'input_change') if self.ticker4_select: self.ticker4_select.on_change('value', self, 'input_change') if self.ticker4_1_select: self.ticker4_1_select.on_change('value', self, 'input_change') if self.ticker4_2_select: self.ticker4_2_select.on_change('value', self, 'input_change') if self.button_select: self.button_select.on_change('value',self, 'input_change') @property def Y(self): tmpdf = pd.DataFrame(self.main_mc(int(self.ticker3_1),int(self.ticker3),float(self.ticker3_2),self.ticker4_2,float(self.ticker4_1))) tmpdf.columns = ['Col_' + str(i) for i in xrange(len(tmpdf.columns))] #print tmpdf return tmpdf
""" Rescale given values to reasonable symbol sizes in the plot. """ max_size = 50.0 min_size = 5.0 # Rescale max. slope = (max_size - min_size) / (values.max() - values.min()) return slope * (values - values.max()) + max_size # Directory selection. dirs = os.listdir(model.parent_dir) dirs.sort() directory_selection = Select(options=dirs, value=dirs[1]) directory_selection.on_change('value', directory_update) # Init model first time. model.frames = get_frames(directory_selection.value) # Slider to select frame. idx_selection_slider = Slider(start=model.idxs[0], end=model.idxs[-1], step=1.0, value=model.idxs[0], title="Select frame id") idx_selection_slider.on_change('value', idx_slider_update) # Spinner to select frame. idx_selection_spinner = Spinner(low=model.idxs[0], high=model.idxs[-1],
) p.xaxis.axis_label = "Time of Day" p.yaxis.axis_label = "Wait time (min)" p.title.text = select.value p.add_tools(HoverTool(tooltips=[("date", "@date")], renderers=lr, mode='mouse')) # Update canvas for new roller coaster def update(att, old, new): # Clear the lines off of the plot #while len(lr) > 0: # render = lr.pop(0) # p.renderers.remove(render) for render in lr: render.visible = False # Draw new lines draw_plot(select.value) # Update plot when new value chosen from dropdown select.on_change('value', update) # Initialize plot layout = column(select, p) draw_plot(rides[3][0]) # Add it to web page curdoc().add_root(layout) curdoc().title = "Hershey Park Wait times"
barchart._yaxis.formatter = NumeralTickFormatter(format="0%") barchart.y_range = Range1d(0, 1) barchart.outline_line_color = None barchart.toolbar_location = 'right' barchart.logo = None for renderer in barchart.select(GlyphRenderer): if renderer.data_source.data['height'] != [0]: year = renderer.data_source.data['year'] num_dnf = data['dnfs'].loc[data['year'] == year] num_entries = data['entries'].loc[data['year'] == year] percent_dnf = data['percentage_dnf'].loc[data['year'] == year] hover = HoverTool(renderers=[renderer], tooltips=[("# DNFs", '%d' % num_dnf.values[0]), ("# Entries", '%d' % num_entries.values[0]), ("% DNF", '%.2f%%' % (100 * percent_dnf.values[0]))]) barchart.add_tools(hover) return barchart select_event.on_change('value', on_event_change) layout = HBox(children=[select_event, generate_chart(selectable_events[2])]) curdoc().add_root(layout)
here=np.loadtxt('here5.csv',str,delimiter='\n') here=list(here) here_height=df_counts['numbers'] y_here_height=here_height/2.0 source.data=dict( x=here[:10], y=y_here_height[:10], height=here_height[:10] ) plot.tools=[hover] plot.xaxis.major_label_orientation=np.pi/3 plot.x_range.factors=here[:10] new_height=here_height[:10].values plot.y_range.end=new_height[0]+200 #plot.rect(x=axis_map[x_axis.value],y=height_map[x_axis.value],height=height_map[x_axis.value]*2.0) #plot.x_range.on_change('_bounds_as_factors',update) x_axis.on_change('value',update) cities.on_change('value',update) companies.on_change('value',update) industries.on_change('value',update) #filters=VBox(x_axis) #tot=HBox(filters,plot) #show(tot) curdoc().add_root(HBox(inputs,plot))
class MetaModelVisualization(object): """ Top-level container for the Meta Model Visualization. Attributes ---------- prob : Problem Name of variable corresponding to Problem Component meta_model : MetaModel Name of empty Meta Model Component object reference resolution : int Number used to calculate width and height of contour plot is_structured_meta_model : Bool Boolean used to signal whether the meta model is structured or unstructured slider_source : ColumnDataSource Data source containing dictionary of sliders contour_training_data_source : ColumnDataSource Data source containing dictionary of training data points bottom_plot_source : ColumnDataSource Data source containing data for the bottom subplot bottom_plot_scatter_source : ColumnDataSource Data source containing scatter point data for the bottom subplot right_plot_source : ColumnDataSource Data source containing data for the right subplot right_plot_scatter_source : ColumnDataSource Data source containing scatter point data for the right subplot contour_plot_source : ColumnDataSource Data source containing data for the contour plot input_names : list List of input data titles as strings output_names : list List of output data titles as strings training_inputs : dict Dictionary of input training data x_input_select : Select Bokeh Select object containing a list of inputs for the x axis y_input_select : Select Bokeh Select object containing a list of inputs for the y axis output_select : Select Bokeh Select object containing a list of inputs for the outputs x_input_slider : Slider Bokeh Slider object containing a list of input values for the x axis y_input_slider : Slider Bokeh Slider object containing a list of input values for the y axis slider_dict : dict Dictionary of slider names and their respective slider objects predict_inputs : dict Dictionary containing training data points to predict at. num_inputs : int Number of inputs num_outputs : int Number of outputs limit_range : array Array containing the range of each input scatter_distance : TextInput Text input for user to enter custom value to calculate distance of training points around slice line right_alphas : array Array of points containing alpha values for right plot bottom_alphas : array Array of points containing alpha values for bottom plot dist_range : float Value taken from scatter_distance used for calculating distance of training points around slice line x_index : int Value of x axis column y_index : int Value of y axis column output_variable : int Value of output axis column sliders_and_selects : layout Layout containing the sliders and select elements doc_layout : layout Contains first row of plots doc_layout2 : layout Contains second row of plots Z : array A 2D array containing contour plot data """ def __init__(self, model, resolution=50, doc=None): """ Initialize parameters. Parameters ---------- model : MetaModelComponent Reference to meta model component resolution : int Value used to calculate the size of contour plot meshgrid doc : Document The bokeh document to build. """ self.prob = Problem() self.resolution = resolution logging.getLogger("bokeh").setLevel(logging.ERROR) # If the surrogate model coming in is structured if isinstance(model, MetaModelUnStructuredComp): self.is_structured_meta_model = False # Create list of input names, check if it has more than one input, then create list # of outputs self.input_names = [ name[0] for name in model._surrogate_input_names ] if len(self.input_names) < 2: raise ValueError('Must have more than one input value') self.output_names = [ name[0] for name in model._surrogate_output_names ] # Create reference for untructured component self.meta_model = MetaModelUnStructuredComp( default_surrogate=model.options['default_surrogate']) # If the surrogate model coming in is unstructured elif isinstance(model, MetaModelStructuredComp): self.is_structured_meta_model = True self.input_names = [name for name in model._var_rel_names['input']] if len(self.input_names) < 2: raise ValueError('Must have more than one input value') self.output_names = [ name for name in model._var_rel_names['output'] ] self.meta_model = MetaModelStructuredComp( distributed=model.options['distributed'], extrapolate=model.options['extrapolate'], method=model.options['method'], training_data_gradients=model. options['training_data_gradients'], vec_size=1) # Pair input list names with their respective data self.training_inputs = {} self._setup_empty_prob_comp(model) # Setup dropdown menus for x/y inputs and the output value self.x_input_select = Select(title="X Input:", value=[x for x in self.input_names][0], options=[x for x in self.input_names]) self.x_input_select.on_change('value', self._x_input_update) self.y_input_select = Select(title="Y Input:", value=[x for x in self.input_names][1], options=[x for x in self.input_names]) self.y_input_select.on_change('value', self._y_input_update) self.output_select = Select(title="Output:", value=[x for x in self.output_names][0], options=[x for x in self.output_names]) self.output_select.on_change('value', self._output_value_update) # Create sliders for each input self.slider_dict = {} self.predict_inputs = {} for title, values in self.training_inputs.items(): slider_data = np.linspace(min(values), max(values), self.resolution) self.predict_inputs[title] = slider_data # Calculates the distance between slider ticks slider_step = slider_data[1] - slider_data[0] slider_object = Slider(start=min(values), end=max(values), value=min(values), step=slider_step, title=str(title)) self.slider_dict[title] = slider_object self._slider_attrs() # Length of inputs and outputs self.num_inputs = len(self.input_names) self.num_outputs = len(self.output_names) # Precalculate the problem bounds. limits = np.array([[min(value), max(value)] for value in self.training_inputs.values()]) self.limit_range = limits[:, 1] - limits[:, 0] # Positional indicies self.x_index = 0 self.y_index = 1 self.output_variable = self.output_names.index( self.output_select.value) # Data sources are filled with initial values # Slider Column Data Source self.slider_source = ColumnDataSource(data=self.predict_inputs) # Contour plot Column Data Source self.contour_plot_source = ColumnDataSource(data=dict( z=np.random.rand(self.resolution, self.resolution))) self.contour_training_data_source = ColumnDataSource(data=dict( x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution))) # Bottom plot Column Data Source self.bottom_plot_source = ColumnDataSource(data=dict( x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution))) self.bottom_plot_scatter_source = ColumnDataSource( data=dict(bot_slice_x=np.repeat(0, self.resolution), bot_slice_y=np.repeat(0, self.resolution))) # Right plot Column Data Source self.right_plot_source = ColumnDataSource(data=dict( x=np.repeat(0, self.resolution), y=np.repeat(0, self.resolution))) self.right_plot_scatter_source = ColumnDataSource( data=dict(right_slice_x=np.repeat(0, self.resolution), right_slice_y=np.repeat(0, self.resolution))) # Text input to change the distance of reach when searching for nearest data points self.scatter_distance = TextInput(value="0.1", title="Scatter Distance") self.scatter_distance.on_change('value', self._scatter_input) self.dist_range = float(self.scatter_distance.value) # Grouping all of the sliders and dropdowns into one column sliders = [value for value in self.slider_dict.values()] sliders.extend([ self.x_input_select, self.y_input_select, self.output_select, self.scatter_distance ]) self.sliders_and_selects = row(column(*sliders)) # Layout creation self.doc_layout = row(self._contour_data(), self._right_plot(), self.sliders_and_selects) self.doc_layout2 = row(self._bottom_plot()) if doc is None: doc = curdoc() doc.add_root(self.doc_layout) doc.add_root(self.doc_layout2) doc.title = 'Meta Model Visualization' def _setup_empty_prob_comp(self, metamodel): """ Take data from surrogate ref and pass it into new surrogate model with empty Problem model. Parameters ---------- metamodel : MetaModelComponent Reference to meta model component """ # Check for structured or unstructured if self.is_structured_meta_model: # Loop through the input names for idx, name in enumerate(self.input_names): # Check for no training data try: # Append the input data/titles to a dictionary self.training_inputs[name] = metamodel.params[idx] # Also, append the data as an 'add_input' to the model reference self.meta_model.add_input( name, 0., training_data=metamodel.params[idx]) except TypeError: msg = "No training data present for one or more parameters" raise TypeError(msg) # Add the outputs to the model reference for idx, name in enumerate(self.output_names): self.meta_model.add_output( name, 0., training_data=metamodel.training_outputs[name]) else: for name in self.input_names: try: self.training_inputs[name] = { title for title in metamodel.options['train:' + str(name)] } self.meta_model.add_input( name, 0., training_data=[ title for title in metamodel.options['train:' + str(name)] ]) except TypeError: msg = "No training data present for one or more parameters" raise TypeError(msg) for name in self.output_names: self.meta_model.add_output( name, 0., training_data=[ title for title in metamodel.options['train:' + str(name)] ]) # Add the subsystem and setup self.prob.model.add_subsystem('interp', self.meta_model) self.prob.setup() def _slider_attrs(self): """ Assign data to slider objects and callback functions. Parameters ---------- None """ for name, slider_object in self.slider_dict.items(): # Checks if there is a callback previously assigned and then clears it if len(slider_object._callbacks) == 1: slider_object._callbacks.clear() # Check if the name matches the 'x input' title if name == self.x_input_select.value: # Set the object and add an event handler self.x_input_slider = slider_object self.x_input_slider.on_change('value', self._scatter_plots_update) # Check if the name matches the 'y input' title elif name == self.y_input_select.value: # Set the object and add an event handler self.y_input_slider = slider_object self.y_input_slider.on_change('value', self._scatter_plots_update) else: # If it is not an x or y input then just assign it the event handler slider_object.on_change('value', self._update) def _make_predictions(self, data): """ Run the data parameter through the surrogate model which is given in prob. Parameters ---------- data : dict Dictionary containing training points. Returns ------- array np.stack of predicted points. """ # Create dictionary with an empty list outputs = {name: [] for name in self.output_names} # Parse dict into shape [n**2, number of inputs] list inputs = np.empty([self.resolution**2, self.num_inputs]) for idx, values in enumerate(data.values()): inputs[:, idx] = values.flatten() # Check for structured or unstructured if self.is_structured_meta_model: # Assign each row of the data coming in to a tuple. Loop through the tuple, and append # the name of the input and value. for idx, tup in enumerate(inputs): for name, val in zip(data.keys(), tup): self.prob[self.meta_model.name + '.' + name] = val self.prob.run_model() # Append the predicted value(s) for title in self.output_names: outputs[title].append( np.array(self.prob[self.meta_model.name + '.' + title])) else: for idx, tup in enumerate(inputs): for name, val in zip(data.keys(), tup): self.prob[self.meta_model.name + '.' + name] = val self.prob.run_model() for title in self.output_names: outputs[title].append( float(self.prob[self.meta_model.name + '.' + title])) return stack_outputs(outputs) def _contour_data_calcs(self): """ Parse input data into a dictionary to be predicted at. Parameters ---------- None Returns ------- dict Dictionary of training data to be predicted at. """ # Create initial data array of training points resolution = self.resolution x_data = np.zeros((resolution, resolution, self.num_inputs)) self._slider_attrs() # Broadcast the inputs to every row of x_data array x_data[:, :, :] = np.array(self.input_point_list) # Find the x/y input titles and match their index positions for idx, (title, values) in enumerate(self.slider_source.data.items()): if title == self.x_input_select.value: self.xlins_mesh = values x_index_position = idx if title == self.y_input_select.value: self.ylins_mesh = values y_index_position = idx # Make meshgrid from the x/y inputs to be plotted X, Y = np.meshgrid(self.xlins_mesh, self.ylins_mesh) # Move the x/y inputs to their respective positions in x_data x_data[:, :, x_index_position] = X x_data[:, :, y_index_position] = Y pred_dict = {} for idx, title in enumerate(self.slider_source.data): pred_dict.update({title: x_data[:, :, idx]}) return pred_dict def _contour_data(self): """ Create a contour plot. Parameters ---------- None Returns ------- Bokeh Image Plot """ resolution = self.resolution # Output data array initialization y_data = np.zeros((resolution, resolution, self.num_outputs)) self.input_point_list = [ point.value for point in self.slider_dict.values() ] # Pass the dict to make predictions and then reshape the output to # (resolution, resolution, number of outputs) y_data[:, :, :] = self._make_predictions( self._contour_data_calcs()).reshape( (resolution, resolution, self.num_outputs)) # Use the output variable to pull the correct column of data from the predicted # data (y_data) self.Z = y_data[:, :, self.output_variable] # Reshape it to be 2D self.Z = self.Z.reshape(resolution, resolution) # Update the data source with new data self.contour_plot_source.data = dict(z=[self.Z]) # Min to max of training data self.contour_x_range = xlins = self.xlins_mesh self.contour_y_range = ylins = self.ylins_mesh # Color bar formatting color_mapper = LinearColorMapper(palette="Viridis11", low=np.amin(self.Z), high=np.amax(self.Z)) color_bar = ColorBar(color_mapper=color_mapper, ticker=BasicTicker(), label_standoff=12, location=(0, 0)) # Contour Plot self.contour_plot = contour_plot = figure( match_aspect=False, tooltips=[(self.x_input_select.value, "$x"), (self.y_input_select.value, "$y"), (self.output_select.value, "@z")], tools='') contour_plot.x_range.range_padding = 0 contour_plot.y_range.range_padding = 0 contour_plot.plot_width = 600 contour_plot.plot_height = 500 contour_plot.xaxis.axis_label = self.x_input_select.value contour_plot.yaxis.axis_label = self.y_input_select.value contour_plot.min_border_left = 0 contour_plot.add_layout(color_bar, 'right') contour_plot.x_range = Range1d(min(xlins), max(xlins)) contour_plot.y_range = Range1d(min(ylins), max(ylins)) contour_plot.image(image='z', source=self.contour_plot_source, x=min(xlins), y=min(ylins), dh=(max(ylins) - min(ylins)), dw=(max(xlins) - min(xlins)), palette="Viridis11") # Adding training data points overlay to contour plot if self.is_structured_meta_model: data = self._structured_training_points() else: data = self._unstructured_training_points() if len(data): # Add training data points overlay to contour plot data = np.array(data) if self.is_structured_meta_model: self.contour_training_data_source.data = dict( x=data[:, 0], y=data[:, 1], z=self.meta_model.training_outputs[ self.output_select.value].flatten()) else: self.contour_training_data_source.data = dict( x=data[:, 0], y=data[:, 1], z=self.meta_model._training_output[ self.output_select.value]) training_data_renderer = self.contour_plot.circle( x='x', y='y', source=self.contour_training_data_source, size=5, color='white', alpha=0.50) self.contour_plot.add_tools( HoverTool(renderers=[training_data_renderer], tooltips=[ (self.x_input_select.value + " (train)", '@x'), (self.y_input_select.value + " (train)", '@y'), (self.output_select.value + " (train)", '@z'), ])) return self.contour_plot def _right_plot(self): """ Create the right side subplot to view the projected slice. Parameters ---------- None Returns ------- Bokeh figure """ # List of the current positions of the sliders self.input_point_list = [ point.value for point in self.slider_dict.values() ] # Find the title of the y input and match it with the data y_idx = self.y_input_select.value y_data = self.predict_inputs[y_idx] # Find the position of the x_input slider x_value = self.x_input_slider.value # Rounds the x_data to match the predict_inputs value subplot_value_index = np.where( np.around(self.predict_inputs[self.x_input_select.value], 5) == np.around(x_value, 5))[0] # Make slice in Z data at the point calculated before and add it to the data source z_data = self.Z[:, subplot_value_index].flatten() x = z_data y = self.slider_source.data[y_idx] # Update the data source with new data self.right_plot_source.data = dict(x=x, y=y) # Create and format figure self.right_plot_fig = right_plot_fig = figure( plot_width=250, plot_height=500, title="{} vs {}".format(y_idx, self.output_select.value), tools="pan") right_plot_fig.xaxis.axis_label = self.output_select.value right_plot_fig.yaxis.axis_label = y_idx right_plot_fig.xaxis.major_label_orientation = math.pi / 9 right_plot_fig.line(x='x', y='y', source=self.right_plot_source) right_plot_fig.x_range.range_padding = 0.1 right_plot_fig.y_range.range_padding = 0.02 # Determine distance and alpha opacity of training points if self.is_structured_meta_model: data = self._structured_training_points(compute_distance=True, source='right') else: data = self._unstructured_training_points(compute_distance=True, source='right') self.right_alphas = 1.0 - data[:, 2] / self.dist_range # Training data scatter plot scatter_renderer = right_plot_fig.scatter( x=data[:, 3], y=data[:, 1], line_color=None, fill_color='#000000', fill_alpha=self.right_alphas.tolist()) right_plot_fig.add_tools( HoverTool(renderers=[scatter_renderer], tooltips=[ (self.output_select.value + " (train)", '@x'), (y_idx + " (train)", '@y'), ])) right_plot_fig.scatter(x=data[:, 3], y=data[:, 1], line_color=None, fill_color='#000000', fill_alpha=self.right_alphas.tolist()) # Set the right_plot data source to new values self.right_plot_scatter_source.data = dict(right_slice_x=np.repeat( x_value, self.resolution), right_slice_y=y_data) self.contour_plot.line('right_slice_x', 'right_slice_y', source=self.right_plot_scatter_source, color='black', line_width=2) return self.right_plot_fig def _bottom_plot(self): """ Create the bottom subplot to view the projected slice. Parameters ---------- None Returns ------- Bokeh figure """ # List of the current positions of the sliders self.input_point_list = [ point.value for point in self.slider_dict.values() ] # Find the title of the x input and match it with the data x_idx = self.x_input_select.value x_data = self.predict_inputs[x_idx] # Find the position of the y_input slider y_value = self.y_input_slider.value # Rounds the y_data to match the predict_inputs value subplot_value_index = np.where( np.around(self.predict_inputs[self.y_input_select.value], 5) == np.around(y_value, 5))[0] # Make slice in Z data at the point calculated before and add it to the data source z_data = self.Z[subplot_value_index, :].flatten() x = self.slider_source.data[x_idx] y = z_data # Update the data source with new data self.bottom_plot_source.data = dict(x=x, y=y) # Create and format figure self.bottom_plot_fig = bottom_plot_fig = figure( plot_width=550, plot_height=250, title="{} vs {}".format(x_idx, self.output_select.value), tools="") bottom_plot_fig.xaxis.axis_label = x_idx bottom_plot_fig.yaxis.axis_label = self.output_select.value bottom_plot_fig.line(x='x', y='y', source=self.bottom_plot_source) bottom_plot_fig.x_range.range_padding = 0.02 bottom_plot_fig.y_range.range_padding = 0.1 # Determine distance and alpha opacity of training points if self.is_structured_meta_model: data = self._structured_training_points(compute_distance=True) else: data = self._unstructured_training_points(compute_distance=True) self.bottom_alphas = 1.0 - data[:, 2] / self.dist_range # Training data scatter plot scatter_renderer = bottom_plot_fig.scatter( x=data[:, 0], y=data[:, 3], line_color=None, fill_color='#000000', fill_alpha=self.bottom_alphas.tolist()) bottom_plot_fig.add_tools( HoverTool(renderers=[scatter_renderer], tooltips=[ (x_idx + " (train)", '@x'), (self.output_select.value + " (train)", '@y'), ])) # Set the right_plot data source to new values self.bottom_plot_scatter_source.data = dict(bot_slice_x=x_data, bot_slice_y=np.repeat( y_value, self.resolution)) self.contour_plot.line('bot_slice_x', 'bot_slice_y', source=self.bottom_plot_scatter_source, color='black', line_width=2) return self.bottom_plot_fig def _unstructured_training_points(self, compute_distance=False, source='bottom'): """ Calculate the training points and returns and array containing the position and alpha. Parameters ---------- compute_distance : bool If true, compute the distance of training points from surrogate line. source : str Which subplot the method is being called from. Returns ------- array The array of training points and their alpha opacity with respect to the surrogate line """ # Input training data and output training data x_training = self.meta_model._training_input training_output = np.squeeze(stack_outputs( self.meta_model._training_output), axis=1) # Index of input/output variables x_index = self.x_input_select.options.index(self.x_input_select.value) y_index = self.y_input_select.options.index(self.y_input_select.value) output_variable = self.output_names.index(self.output_select.value) # Vertically stack the x/y inputs and then transpose them infos = np.vstack( (x_training[:, x_index], x_training[:, y_index])).transpose() if not compute_distance: return infos points = x_training.copy() # Normalize so each dimension spans [0, 1] points = np.divide(points, self.limit_range) dist_limit = np.linalg.norm(self.dist_range * self.limit_range) scaled_x0 = np.divide(self.input_point_list, self.limit_range) # Query the nearest neighbors tree for the closest points to the scaled x0 array # Nearest points to x slice if x_training.shape[1] < 3: tree = cKDTree(points) # Query the nearest neighbors tree for the closest points to the scaled x0 array dists, idxs = tree.query(scaled_x0, k=len(x_training), distance_upper_bound=self.dist_range) # kdtree query always returns requested k even if there are not enough valid points idx_finite = np.where(np.isfinite(dists)) dists = dists[idx_finite] idxs = idxs[idx_finite] else: dists, idxs = self._multidimension_input(scaled_x0, points, source=source) # data contains: # [x_value, y_value, ND-distance, func_value] data = np.zeros((len(idxs), 4)) for dist_index, j in enumerate(idxs): data[dist_index, 0:2] = infos[j, :] data[dist_index, 2] = dists[dist_index] data[dist_index, 3] = training_output[j, output_variable] return data def _structured_training_points(self, compute_distance=False, source='bottom'): """ Calculate the training points and return an array containing the position and alpha. Parameters ---------- compute_distance : bool If true, compute the distance of training points from surrogate line. source : str Which subplot the method is being called from. Returns ------- array The array of training points and their alpha opacity with respect to the surrogate line """ # Create tuple of the input parameters input_dimensions = tuple(self.meta_model.params) # Input training data and output training data x_training = np.array([z for z in product(*input_dimensions)]) training_output = self.meta_model.training_outputs[ self.output_select.value].flatten() # Index of input/output variables x_index = self.x_input_select.options.index(self.x_input_select.value) y_index = self.y_input_select.options.index(self.y_input_select.value) # Vertically stack the x/y inputs and then transpose them infos = np.vstack( (x_training[:, x_index], x_training[:, y_index])).transpose() if not compute_distance: return infos points = x_training.copy() # Normalize so each dimension spans [0, 1] points = np.divide(points, self.limit_range) self.dist_limit = np.linalg.norm(self.dist_range * self.limit_range) scaled_x0 = np.divide(self.input_point_list, self.limit_range) # Query the nearest neighbors tree for the closest points to the scaled x0 array # Nearest points to x slice if x_training.shape[1] < 3: x_tree, x_idx = self._two_dimension_input(scaled_x0, points, source=source) else: x_tree, x_idx = self._multidimension_input(scaled_x0, points, source=source) # format for 'data' # [x_value, y_value, ND-distance_(x or y), func_value] n = len(x_tree) data = np.zeros((n, 4)) for dist_index, j in enumerate(x_idx): data[dist_index, 0:2] = infos[j, :] data[dist_index, 2] = x_tree[dist_index] data[dist_index, 3] = training_output[j] return data def _two_dimension_input(self, scaled_points, training_points, source='bottom'): """ Calculate the distance of training points to the surrogate line. Parameters ---------- scaled_points : array Array of normalized slider positions. training_points : array Array of input training data. source : str Which subplot the method is being called from. Returns ------- idxs : array Index of closest points that are within the dist range. x_tree : array One dimentional array of points that are within the dist range. """ # Column of the input if source == 'right': col_idx = self.y_input_select.options.index( self.y_input_select.value) else: col_idx = self.x_input_select.options.index( self.x_input_select.value) # Delete the axis of input from source to predicted 1D distance x = np.delete(scaled_points, col_idx, axis=0) x_training_points = np.delete(training_points, col_idx, axis=1).flatten() # Tree of point distances x_tree = np.abs(x - x_training_points) # Only return points that are within our distance-viewing paramter. idx = np.where(x_tree <= self.dist_range) x_tree = x_tree[idx] return x_tree, idx[0] def _multidimension_input(self, scaled_points, training_points, source='bottom'): """ Calculate the distance of training points to the surrogate line. Parameters ---------- scaled_points : array Array of normalized slider positions. training_points : array Array of input training data. source : str Which subplot the method is being called from. Returns ------- idxs : array Index of closest points that are within the dist range. x_tree : array Array of points that are within the dist range. """ # Column of the input if source == 'right': col_idx = self.y_input_select.options.index( self.y_input_select.value) else: col_idx = self.x_input_select.options.index( self.x_input_select.value) # Delete the axis of input from source to predicted distance x = np.delete(scaled_points, col_idx, axis=0) x_training_points = np.delete(training_points, col_idx, axis=1) # Tree of point distances x_tree = cKDTree(x_training_points) # Query the nearest neighbors tree for the closest points to the scaled array dists, idx = x_tree.query(x, k=len(x_training_points), distance_upper_bound=self.dist_range) # kdtree query always returns requested k even if there are not enough valid points idx_finite = np.where(np.isfinite(dists)) dists_finite = dists[idx_finite] idx = idx[idx_finite] return dists_finite, idx # Event handler functions def _update_all_plots(self): self.doc_layout.children[0] = self._contour_data() self.doc_layout.children[1] = self._right_plot() self.doc_layout2.children[0] = self._bottom_plot() def _update_subplots(self): self.doc_layout.children[1] = self._right_plot() self.doc_layout2.children[0] = self._bottom_plot() def _update(self, attr, old, new): self._update_all_plots() def _scatter_plots_update(self, attr, old, new): self._update_subplots() def _scatter_input(self, attr, old, new): # Text input update function of dist range value self.dist_range = float(new) self._update_all_plots() def _x_input_update(self, attr, old, new): # Checks that x and y inputs are not equal to each other if new == self.y_input_select.value: raise ValueError("Inputs should not equal each other") else: self.x_input_select.value = new self._update_all_plots() def _y_input_update(self, attr, old, new): # Checks that x and y inputs are not equal to each other if new == self.x_input_select.value: raise ValueError("Inputs should not equal each other") else: self.y_input_select.value = new self._update_all_plots() def _output_value_update(self, attr, old, new): self.output_variable = self.output_names.index(new) self._update_all_plots()
ric_50_layout = ric50_simu().layout temp = layout([model_display, simu_sele], *ric_50_layout) select_layout.children = temp.children model_display.text = """ <div style="text-align:center;"> <img src="simuojo/static/ric_50.png" height='75' width="485" "></div>""" elif new == 'Dose-Response 5 Para Logistic': dr5pl_layout = DR_5PL().layout temp = layout([model_display, simu_sele], *dr5pl_layout) select_layout.children = temp.children model_display.text = """ <div style="text-align:center;"> <img src="simuojo/static/DR_5PL.png" height='60' width="503" "></div>""" elif new == 'ric_50_coop simulation': ric_50_coop_layout = ri50_coop_simu().layout temp = layout([model_display, simu_sele], *ric_50_coop_layout) select_layout.children = temp.children model_display.text = """<div style="text-align:center;"> <img src="simuojo/static/ric_50_co.png" height='60' width="286" "></div>""" simu_sele.on_change('value', simu_sele_cb) select_layout = layout([row(model_display, simu_sele)], [ Div(text=""" <div class="jumbotron col-md-12"> <h1>Select a model to start</h1> </div>""", width=900, height=875) ]) curdoc().add_root(select_layout)
def modify_doc(doc): Q_API_key = '2QQxWV_Ycg2ULirbUMxB' # Quandl AV_API_key = '567TRV8RTL728INO' # Alpha Vantage # Download WIKI metadata from Quandl via API url_0 = 'https://www.quandl.com/api/v3/databases/WIKI/metadata?api_key=' + Q_API_key response_0 = requests.get(url_0) # Unzip the bytes and extract the csv file into memory myzip = ZipFile(BytesIO(response_0.content)).extract('WIKI_metadata.csv') # Read the csv into pandas dataframe df_0 = pd.read_csv(myzip) # Clean up the name fields df_0['name'] = df_0['name'].apply(lambda s: s[:s.find(')') + 1].rstrip()) # Drop extraneous fields and reorder df_0 = df_0.reindex(columns=['name', 'code']) # Make widgets stock_picker = Select(title="Select a Stock", value=df_0['name'][0], options=df_0['name'].tolist()) year_picker = Select(title="Select a Year", value="2018", options=[str(i) for i in range(2008, 2019)], width=100) months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] month_picker = Select(title="Select a Month", value="January", options=months, width=150) widgets = row(stock_picker, year_picker, month_picker) # Get data def get_data(AV_API_key, ticker): from alpha_vantage.timeseries import TimeSeries ts = TimeSeries(key=AV_API_key) data, metadata = ts.get_daily(ticker, 'full') data_dict = {} for sub in data.values(): for key, value in sub.items(): data_dict.setdefault(key[3:], []).append(float(value)) data_dict['date'] = list(data.keys()) df = pd.DataFrame.from_dict(data_dict) df['date'] = pd.to_datetime(df['date']) df = df.iloc[::-1].reset_index(drop=True) # do some finance things df['inc'] = df.close > df.open df['inc'] = df['inc'].apply(lambda bool: str(bool)) def SMA(n, s): return [s[0]] * n + [np.mean(s[i - n:i]) for i in range(n, len(s))] def EMA(n, s): k = 2 / (n + 1) ema = np.zeros(len(s)) ema[0] = s[0] for i in range(1, len(s) - 1): ema[i] = k * s[i] + (1 - k) * ema[i - 1] return ema df['ema12'] = EMA(12, df['open']) df['ema26'] = EMA(26, df['open']) df['macd'] = df['ema12'] - df['ema26'] df['signal'] = EMA(9, df['macd']) df['zero'] = df['volume'].apply(lambda x: x * 0) df['hist'] = df.macd - df.signal df['histc'] = df.macd > df.signal df['histc'] = df['histc'].apply(lambda bool: str(bool)) return df # Make figure df = get_data(AV_API_key, 'A') data_dict = df.to_dict('series') source = ColumnDataSource(data=data_dict) # create a new plot with a datetime axis type p1 = figure(plot_height=400, x_axis_type="datetime", tools="xwheel_pan,xwheel_zoom,pan,box_zoom", active_scroll='xwheel_zoom') p2 = figure(plot_height=150, x_axis_type="datetime", x_range=p1.x_range, tools="xwheel_pan,xwheel_zoom,pan,box_zoom", active_scroll='xwheel_pan') p3 = figure(plot_height=250, x_axis_type="datetime", x_range=p1.x_range, tools="xwheel_pan,xwheel_zoom,pan,box_zoom", active_scroll='xwheel_pan') # create price glyphs and volume glyph p1O = p1.line(x='date', y='open', source=source, color=Spectral5[0], alpha=0.8, legend="OPEN") p1C = p1.line(x='date', y='close', source=source, color=Spectral5[1], alpha=0.8, legend="CLOSE") p1L = p1.line(x='date', y='low', source=source, color=Spectral5[4], alpha=0.8, legend="LOW") p1H = p1.line(x='date', y='high', source=source, color=Spectral5[3], alpha=0.8, legend="HIGH") p1.line(x='date', y='ema12', source=source, color="magenta", legend="EMA-12") p1.line(x='date', y='ema26', source=source, color="black", legend="EMA-26") color_mapper = CategoricalColorMapper(factors=["True", "False"], palette=["green", "red"]) p1.segment(x0='date', y0='high', x1='date', y1='low', color={ 'field': 'inc', 'transform': color_mapper }, source=source) width_ms = 12 * 60 * 60 * 1000 # half day in ms p1.vbar(x='date', width=width_ms, top='open', bottom='close', color={ 'field': 'inc', 'transform': color_mapper }, source=source) p2V = p2.varea(x='date', y1='volume', y2='zero', source=source, color="black", alpha=0.8) p3.line(x='date', y='macd', source=source, color="green", legend="MACD") p3.line(x='date', y='signal', source=source, color="red", legend="Signal") p3.vbar(x='date', top='hist', source=source, width=width_ms, color={ 'field': 'histc', 'transform': color_mapper }, alpha=0.5) # Add HoverTools to each line p1.add_tools( HoverTool(tooltips=[('Date', '@date{%F}'), ('Open', '@open{($ 0.00)}'), ('Close', '@close{($ 0.00)}'), ('Low', '@low{($ 0.00)}'), ('High', '@high{($ 0.00)}'), ('Volume', '@volume{(0.00 a)}')], formatters={'date': 'datetime'}, mode='mouse')) p2.add_tools( HoverTool(tooltips=[('Date', '@date{%F}'), ('Open', '@open{($ 0.00)}'), ('Close', '@close{($ 0.00)}'), ('Low', '@low{($ 0.00)}'), ('High', '@high{($ 0.00)}'), ('Volume', '@volume{(0.00 a)}')], formatters={'date': 'datetime'}, mode='mouse')) p3.add_tools( HoverTool(tooltips=[('Date', '@date{%F}'), ('EMA-12', '@ema12{($ 0.00)}'), ('EMA-26', '@ema26{($ 0.00)}'), ('MACD', '@macd{($ 0.00)}'), ('Signal', '@signal{($ 0.00)}')], formatters={'date': 'datetime'}, mode='mouse')) p1.toolbar.logo = None p2.toolbar.logo = None p3.toolbar.logo = None # Add legend p1.legend.orientation = 'horizontal' p1.legend.title = 'Daily Stock Price' p1.legend.click_policy = "hide" p1.legend.location = "top_left" p3.legend.orientation = 'horizontal' p3.legend.location = "top_left" p3.legend.orientation = 'horizontal' p3.legend.title = 'Moving Average Convergence Divergence' p3.legend.location = "top_left" # Add axis labels #p1.xaxis.axis_label = 'Date' #p3.xaxis.axis_label = 'Date' p2.xaxis.axis_label = 'Date' p1.yaxis.axis_label = 'Price ($USD/share)' p2.yaxis.axis_label = 'Volume (shares)' p3.yaxis.axis_label = 'Indicator ($USD)' # Add tick formatting p1.yaxis[0].formatter = NumeralTickFormatter(format="$0.00") p2.yaxis[0].formatter = NumeralTickFormatter(format="0.0a") p3.yaxis[0].formatter = NumeralTickFormatter(format="$0.00") p1.outline_line_width = 1 p2.outline_line_width = 1 p3.outline_line_width = 1 # Activate tools #p1.toolbar.active_scroll = 'xwheel_zoom' #p2.toolbar.active_scrool = 'xwheel_pan' # Set up callbacks def update_data(attrname, old, new): # Get the current Select value ticker = df_0.loc[df_0['name'] == stock_picker.value, 'code'].iloc[0] print('ticker:', ticker) # Get the new data df = get_data(AV_API_key, ticker) dfi = df.set_index(['date']) data_dict = df.to_dict('series') data_dict = {k: data_dict[k][::-1] for k in data_dict.keys()} source.data = ColumnDataSource(data=data_dict).data def update_axis(attrname, old, new): # Get the current Select values source.data = ColumnDataSource(data=data_dict).data year = year_picker.value month = f'{months.index(month_picker.value) + 1:02d}' start = datetime.strptime(f'{year}-{month}-01', "%Y-%m-%d") if month == '12': end = datetime.strptime(f'{str(int(year)+1)}-01-01', "%Y-%m-%d") else: end = datetime.strptime(f'{year}-{int(month)+1:02d}-01', "%Y-%m-%d") p1.x_range.start = start p1.x_range.end = end dfi = df.set_index(['date']) p1.y_range.start = dfi.loc[end:start]['low'].min() * 0.95 p1.y_range.end = dfi.loc[end:start]['high'].max() * 1.05 p2.y_range.start = dfi.loc[end:start]['volume'].min() * 0.95 p2.y_range.end = dfi.loc[end:start]['volume'].max() * 1.05 p3.y_range.start = dfi.loc[end:start]['macd'].min() * 0.75 p3.y_range.end = dfi.loc[end:start]['macd'].max() * 1.25 # setup JScallback JS = ''' clearTimeout(window._autoscale_timeout); var date = source.data.date, low = source.data.low, high = source.data.high, volume = source.data.volume, macd = source.data.macd, start = cb_obj.start, end = cb_obj.end, min1 = Infinity, max1 = -Infinity, min2 = Infinity, max2 = -Infinity, min3 = Infinity, max3 = -Infinity; for (var i=0; i < date.length; ++i) { if (start <= date[i] && date[i] <= end) { max1 = Math.max(high[i], max1); min1 = Math.min(low[i], min1); max2 = Math.max(volume[i], max2); min2 = Math.min(volume[i], min2); max3 = Math.max(macd[i], max3); min3 = Math.min(macd[i], min3); } } var pad1 = (max1 - min1) * .05; var pad2 = (max2 - min2) * .05; var pad3 = (max3 - min3) * .05; window._autoscale_timeout = setTimeout(function() { y1_range.start = min1 - pad1; y1_range.end = max1 + pad1; y2_range.start = min2 - pad2; y2_range.end = max2 + pad2; y3d = Math.max(Math.abs(min3 - pad3), Math.abs(max3 + pad3)) y3_range.start = -y3d; y3_range.end = y3d; }); ''' callbackJS = CustomJS(args={ 'y1_range': p1.y_range, 'y2_range': p2.y_range, 'y3_range': p3.y_range, 'source': source }, code=JS) p1.x_range.js_on_change('start', callbackJS) p1.x_range.js_on_change('end', callbackJS) stock_picker.on_change('value', update_data) year_picker.on_change('value', update_axis) month_picker.on_change('value', update_axis) b = Button(label='Full History') b.js_on_click( CustomJS(args=dict(p1=p1, p2=p2), code=""" p1.reset.emit() p2.reset.emit() """)) c = column(Div(text="", height=8), b, width=100) # Set up layouts and add to document row1 = row(stock_picker, year_picker, month_picker, c, height=65, width=800, sizing_mode='stretch_width') row2 = row(p1, width=800, height=400, sizing_mode='stretch_width') row3 = row(p2, width=800, height=150, sizing_mode='stretch_width') row4 = row(p3, width=800, height=250, sizing_mode='stretch_width') layout = column(row1, row2, row4, row3, width=800, height=800, sizing_mode='scale_both') doc.add_root(layout)
width=120) file_selection_button.on_click(load_files_group) files_selector_spacer = Spacer(width=10) group_selection_button = Button(label="Select Directory", button_type="primary", width=140) group_selection_button.on_click(load_directory_group) unload_file_button = Button(label="Unload", button_type="danger", width=50) unload_file_button.on_click(unload_file) # files selection box files_selector = Select(title="Files:", options=[]) files_selector.on_change('value', change_data_selector) # data selection box data_selector = MultiSelect(title="Data:", options=[], size=12) data_selector.on_change('value', select_data) # x axis selection box x_axis_selector_title = Div(text="""X Axis:""") x_axis_selector = RadioButtonGroup(labels=x_axis_options, active=0) x_axis_selector.on_click(change_x_axis) # toggle second axis button toggle_second_axis_button = Button(label="Toggle Second Axis", button_type="success") toggle_second_axis_button.on_click(toggle_second_axis)
def modify_doc(doc): def change_categorical(): ''' bokeh plot application for categorical variables ''' def update_bars(attr, old, new): ''' callback for reindexing x-axis with slider ''' data = df[select.value].value_counts() if radio_button_group.active == 1: data = data.sort_index() start = int(round(new[0], 0)) end = int(round(new[1], 0)) + 1 data = data.iloc[start:end] keys = data.keys().tolist() vals = data.values p.x_range.factors = keys datasource.data = {'x': keys, 'top': vals} def update_barsort(attr, old, new): ''' callback for changing sort method of bars ''' data = df[select.value].value_counts() range_slider.value = (range_slider.start, range_slider.end) if new == 1: data = data.sort_index() keys = data.keys().tolist() vals = data.values p.x_range.factors = keys datasource.data = {'x': keys, 'top': vals} # ============================ # Plot Setup (Categorical) # ============================ # fetch data data = df[select.value].value_counts() categories = len(data) - 1 keys = data.keys().tolist() vals = data.values datasource = ColumnDataSource({'x': keys, 'top': vals}) # create plot p = figure(x_range=keys, plot_height=600, plot_width=680, min_border_bottom=200, min_border_left=80) p.vbar(x='x', top='top', width=0.9, source=datasource) # format plot p.xaxis.major_label_orientation = math.pi / 2 p.yaxis.axis_label = 'count' p.title.text = 'Barchart of {}'.format(select.value) p.xgrid.visible = False # create interactive tools range_slider = RangeSlider(start=0, end=categories, value=(0, categories), step=1, title="Index Selector") radio_button_group = RadioButtonGroup( labels=["Sort by y-axis", "Sort by x-axis"], active=0) range_slider.on_change('value', update_bars) radio_button_group.on_change('active', update_barsort) # add to application root = column( row( column(widgetbox(radio_button_group), widgetbox(range_slider)), Spacer(height=150)), p) doc.add_root(root) if len(doc.roots) == 3: # remove plots for previous column variable doc.remove_root(doc.roots[1]) def change_numeric(): ''' bokeh plot application for numeric variables ''' def make_title(label, minval, maxval): ''' adds title to plot with minimum and maximum limits if specified ''' title = 'Histogram' if label is not None: title += ' of {}'.format(label) if minval != '': title += '; Minimum={}'.format(minval) if maxval != '': title += '; Maximum={}'.format(maxval) return title def update_data(low, high): ''' recalculates histograms ''' hist, edges = np.histogram(data[(data >= low) & (data <= high)], bins=bins.value) datasource.data = { 'top': hist, 'left': edges[:-1], 'right': edges[1:] } p.title.text = make_title(label, minval.value, maxval.value) if low > -1 * np.inf: p.x_range.start = low if high < np.inf: p.x_range.end = high def update_bins(attr, old, new): ''' callback for changing number of bins ''' if minval.value == '': low = -1 * np.inf else: low = float(minval.value) if maxval.value == '': high = np.inf else: high = float(maxval.value) update_data(low, high) def update_min(attr, old, new): ''' callback for setting minimum value limit ''' if new == '': low = -1 * np.inf else: low = float(new) if maxval.value == '': high = np.inf else: high = float(maxval.value) update_data(low, high) def update_max(attr, old, new): ''' callback for setting maximum value limit ''' if minval.value == '': low = -1 * np.inf else: low = float(minval.value) if new == '': high = np.inf else: high = float(new) update_data(low, high) # ============================ # Plot Setup (Numeric) # ============================ # fetch data label = select.value data = df[label] data = data[~data.isna()] datasource = ColumnDataSource({'top': [], 'left': [], 'right': []}) # create plot p = figure(plot_height=600, plot_width=680, min_border_bottom=200, min_border_left=80) p.quad(top='top', bottom=0, left='left', right='right', alpha=0.4, source=datasource) # format plot p.xaxis.major_label_orientation = math.pi / 2 p.yaxis.axis_label = 'count' p.below[0].formatter.use_scientific = False # create interactive tools bins = Slider(start=10, end=100, value=default_bins, step=1, title="Bins") minval = TextInput(value=default_min, title="Min Value:") maxval = TextInput(value=default_max, title="Max Value:") bins.on_change('value', update_bins) minval.on_change('value', update_min) maxval.on_change('value', update_max) update_bins(None, None, default_bins) # add to application root = column( row(column(bins, row(minval, maxval)), Spacer(height=150)), p) doc.add_root(root) if len(doc.roots) == 3: # remove plots for previous column variable doc.remove_root(doc.roots[1]) def update_column(attr, old, new): ''' callback for changing data to column specified in dropdown ''' if df[new].dtype in [int, float]: change_numeric() else: change_categorical() # crette interactive dropdown for column selection select = Select(title="Column:", value=default_col, options=cols) select.on_change('value', update_column) doc.add_root(widgetbox(select)) doc.title = "Histoviewer" update_column(None, None, select.value)
with SocketIO(server) as socketIO: socketIO.emit('submitOrder', NewOrder) socketIO.on('onOrderMessage', order_response) socketIO.wait() buyButton = Button(label="BUY", button_type="success") buyButton.on_click(buyThreadFunc) sellButton = Button(label="SELL", button_type="warning") sellButton.on_click(sellThreadFunc) select = Select(title="Ticker:", value=stocks_list[0], options=stocks_list) select.on_change("value", ticker_handler) quantity_input = TextInput(value="100", title="quantity:") quantity_input.on_change("value", quantity_handler) if currentPNL == 0 : PNLbutton = Button(label="PNL : " + str(currentPNL), button_type="warning") elif currentPNL >0 : PNLbutton = Button(label="PNL : " + str(currentPNL), button_type="success") else: PNLbutton = Button(label="PNL : " + str(currentPNL), button_type="danger") disp_buttons = dict(AAPL = Button(label= 'AAPL', button_type = "success"), AMD = Button(label= 'AMD', button_type = "success"),
class HotelApp(VBox): extra_generated_classes = [["HotelApp", "HotelApp", "VBox"]] jsmodel = "VBox" # input selectr = Instance(Select) #check_group = Instance(RadioGroup) check_group = Instance(CheckboxGroup) # plots plot = Instance(GMapPlot) filler = Instance(Plot) filler2 = Instance(Plot) bar_plot = Instance(Plot) legend_plot = Instance(Plot) legend_filler = Instance(Plot) # data source source = Instance(ColumnDataSource) county_source = Instance(ColumnDataSource) # layout boxes checkbox = Instance(VBox) mainrow = Instance(HBox) statsbox = Instance(VBox) mapbox = Instance(VBox) legendbox = Instance(HBox) totalbox = Instance(VBox) # inputs #ticker1_select = Instance(Select) #ticker2_select = Instance(Select) #input_box = Instance(VBoxForm) def make_inputs(self): with open("states.csv") as f: states = [line.strip().split(',') for line in f.readlines()] self.selectr = Select( name='states', value='Choose A State', options=[s[1] for s in states] + ['Choose A State'], ) labels = ["County Averages", "Hotels"] self.check_group = CheckboxGroup(labels=labels, active=[0,1], inline=True) ##Filler plot x_range = Range1d(0, 300) y_range = Range1d(0, 12) self.filler = Plot( x_range=x_range, y_range=y_range, title="", plot_width=300, plot_height=12, min_border=0, **PLOT_FORMATS ) x_range = Range1d(0, 300) y_range = Range1d(0, 18) self.filler2 = Plot( x_range=x_range, y_range=y_range, title="", plot_width=300, plot_height=14, min_border=0, **PLOT_FORMATS ) def make_outputs(self): pass #self.pretext = Paragraph(text="", width=800) def __init__(self, *args, **kwargs): super(HotelApp, self).__init__(*args, **kwargs) self._show_counties = True self._show_hotels = True @classmethod def create(cls): """ This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ # create layout widgets obj = cls() obj.mainrow = HBox() obj.checkbox = VBox(height=50) obj.mapbox = VBox() #obj.bottomrow = HBox() obj.statsbox = VBox( width=500) obj.totalbox = VBox() obj.legendbox = HBox() labels = ["County Average Ratings", "Hotel Locations"] obj.make_inputs() obj.make_outputs() # outputs #obj.pretext = Paragraph(text="", width=500) obj.make_source() obj.make_county_source() lat=39.8282 lng=-98.5795 zoom=6 xr = Range1d() yr = Range1d() #obj.make_plots(lat, lng, zoom, xr, yr) obj.make_plots() # layout obj.set_children() return obj @property def selected_df(self): pandas_df = self.df selected = self.source.selected print "seeing if selected!" if selected: idxs = selected['1d']['indices'] pandas_df = pandas_df.iloc[idxs, :] else: pandas_df = pandas_df.iloc[0:0, :] return pandas_df def make_source(self): self.source = ColumnDataSource(data=self.df) self.source.callback = Callback(args=dict(), code=""" var inds = cb_obj.get('selected')['1d'].indices; var theidx = inds[0]; console.log("yep"); console.log(theidx); $.get( "reviews", {id: theidx}, function( response ) { $( "#section2" ).html( response ); }, "html"); console.log("done"); """) def update_source(self): if self.selectr.value is None or self.selectr.value == 'Choose A State': df = hdata else: df = hdata[hdata['state'] == self.selectr.value] new_data = {} for col in df: new_data[col] = df[col] self.source.data = new_data def make_county_source(self): self.county_source = ColumnDataSource(data=self.countydf) def update_county_source(self): if self.selectr.value is None or self.selectr.value == 'Choose A State': df = county_data else: df = county_data[county_data['state'] == self.selectr.value] new_data = {} for col in df: new_data[col] = df[col] self.county_source.data = new_data #for col in df: # self.county_source.data[col] = df[col] def make_plots(self): self.create_map_plot() self.create_legend() self.populate_glyphs() self.make_bar_plot() def create_legend(self): x_range = Range1d(0, 185) y_range = Range1d(0, 130) text_box = Plot( x_range=x_range, y_range=y_range, title="", plot_width=185, plot_height=130, min_border=0, **PLOT_FORMATS ) FONT_PROPS_SM['text_font_size'] = '11pt' text_box.add_glyph( Text(x=35, y=9, text=['Low Average Rating'], **FONT_PROPS_SM) ) text_box.add_glyph( Rect(x=18, y=18, width=25, height=25, fill_color='#ef4e4d', line_color=None) ) text_box.add_glyph( Text(x=35, y=49, text=['Medium Average Rating'], **FONT_PROPS_SM) ) text_box.add_glyph( Rect(x=18, y=58, width=25, height=25, fill_color='#14a1af', line_color=None) ) text_box.add_glyph( Text(x=35, y=89, text=['High Average Rating'], **FONT_PROPS_SM) ) text_box.add_glyph( Rect(x=18, y=98, width=25, height=25, fill_color='#743184', line_color=None) ) self.legend_plot = text_box ##Filler plot x_range = Range1d(0, 40) y_range = Range1d(0, 100) self.legend_filler = Plot( x_range=x_range, y_range=y_range, title="", plot_width=40, plot_height=100, min_border=0, **PLOT_FORMATS ) def create_map_plot(self): lat=39.8282 lng=-98.5795 zoom=6 xr = Range1d() yr = Range1d() x_range = xr y_range = yr #map_options = GMapOptions(lat=39.8282, lng=-98.5795, zoom=6) map_options = GMapOptions(lat=lat, lng=lng, zoom=zoom) #map_options = GMapOptions(lat=30.2861, lng=-97.7394, zoom=15) plot = GMapPlot( x_range=x_range, y_range=y_range, map_options=map_options, plot_width=680, plot_height=600, title=" " ) plot.map_options.map_type="hybrid" xaxis = LinearAxis(axis_label="lon", major_tick_in=0, formatter=NumeralTickFormatter(format="0.000")) plot.add_layout(xaxis, 'below') yaxis = LinearAxis(axis_label="lat", major_tick_in=0, formatter=PrintfTickFormatter(format="%.3f")) plot.add_layout(yaxis, 'left') self.plot = plot def populate_glyphs(self): self.plot.renderers=[] self.plot.tools=[] if self._show_counties: print "showing you the counties" #datasource = ColumnDataSource(county_data) #apatch = Patches(xs=county_xs, ys=county_ys, fill_color='white') #apatch = Patches(xs='xs', ys='ys', fill_color='colors', fill_alpha="alpha") apatch = Patches(xs='xs', ys='ys', fill_color='thecolors', fill_alpha='alpha') self.plot.add_glyph(self.county_source, apatch, name='counties') if self._show_hotels: print "showing you the hotels" circle2 = Circle(x="lon", y="lat", size=10, fill_color="fill2", fill_alpha=1.0, line_color="black") circle = Circle(x="lon", y="lat", size=10, fill_color="fill", fill_alpha=1.0, line_color="black") #print "source is ", self.source['lon'], self.source['lat'], self.source['f1ll'] self.plot.add_glyph(self.source, circle2, nonselection_glyph=circle, name='hotels') #county_xs, county_ys = get_some_counties() rndr = self.plot.renderers[-1] pan = PanTool() wheel_zoom = WheelZoomTool() box_select = BoxSelectTool() box_select.renderers = [rndr] tooltips = "@name" tooltips = "<span class='tooltip-text'>@names</span>\n<br>" tooltips += "<span class='tooltip-text'>Reviews: @num_reviews</span>" hover = HoverTool(tooltips=tooltips, names=['hotels']) tap = TapTool(names=['hotels']) self.plot.add_tools(pan, wheel_zoom, box_select, hover, tap) overlay = BoxSelectionOverlay(tool=box_select) self.plot.add_layout(overlay) def make_bar_plot(self): # create a new plot y_rr = Range1d(start=0.0, end=5.0) TOOLS = "box_select,lasso_select" #x's and y's based on selected_df sdf = self.selected_df[['names', 'ratings']] xvals = [1.0*i + 0.5 for i in range(0, len(sdf['names']))] rightvals = [1.0*i + 0.85 for i in range(0, len(sdf['names']))] ratings = [r for r in sdf['ratings']] centers = [0.5*r for r in ratings] bottoms = [0]*len(ratings) y_text = [y + 1.0 for y in ratings] width = [1.0] * len(ratings) all_names = [] for n in sdf['names']: short_name = n[:20] idx = short_name.rfind(" ") all_names.append(short_name[:idx]) while len(all_names) > 0 and len(all_names) < 5: all_names.append(" ") bar_plot = figure(tools=TOOLS, width=400, height=350, x_range=all_names, y_range=y_rr, title="Average Rating") bar_plot.title_text_color = "black" bar_plot.title_text_font_size='15pt' bar_plot.title_text_font='Avenir' bar_plot.title_text_align = "right" print "all_names ", all_names bar_colors = [] for r in ratings: if r >= 4.0: bar_colors.append("#743184") elif r >= 3.0: bar_colors.append("#14a1af") else: bar_colors.append("#ef4e4d") bar_plot.xaxis.major_label_orientation = pi/2.3 bar_plot.rect(x=all_names, y=centers, width=width, height=ratings, color=bar_colors, line_color="black") #glyph = Text(x=xvals, y=y_text, text=sdf['names'], angle=pi/4, #text_align="left", text_baseline="middle") #glyphs = [Text(x=x, y=y, text=[n], angle=pi/4, text_align="left", text_baseline="middle") #for x, y, n in zip(xvals, y_text, all_names)] bar_plot.xaxis.major_tick_line_color = None bar_plot.xaxis.minor_tick_line_color = None bar_plot.yaxis.minor_tick_line_color = None bar_plot.xgrid.grid_line_color = None bar_plot.ygrid.grid_line_color = None self.bar_plot = bar_plot def set_children(self): self.children = [self.totalbox] self.totalbox.children = [self.mainrow] self.mainrow.children = [self.statsbox, self.mapbox] self.mapbox.children = [self.plot] #self.checkbox.children = [self.filler, self.check_group, self.filler2] self.statsbox.children = [self.bar_plot, self.legendbox] self.legendbox.children = [self.legend_filler, self.legend_plot] #self.bottomrow.children = [self.pretext] def setup_events(self): super(HotelApp, self).setup_events() if self.source: self.source.on_change('selected', self, 'selection_change') if self.selectr: self.selectr.on_change('value', self, 'input_change') if self.check_group: self.check_group.on_change('active', self, 'check_change') @property def df(self): thedf = return_hotel_data() if self.selectr.value is None or self.selectr.value == 'Choose A State': return thedf else: newdf = thedf[thedf['state'] == self.selectr.value] return newdf @property def countydf(self): thedf = county_data if self.selectr.value is None or self.selectr.value == 'Choose A State': return thedf else: newdf = thedf[thedf['state'] == self.selectr.value] return newdf def selection_change(self, obj, attrname, old, new): #self.make_source() self.update_source() self.make_bar_plot() self.set_children() curdoc().add(self) def check_change(self, obj, attrname, old, new): #Turn on/off the counties/hotel data print "what the heck ", obj, attrname, old, new if 0 in new: self._show_counties = True else: self._show_counties = False if 1 in new: self._show_hotels = True else: self._show_hotels = False self.populate_glyphs() self.set_children() curdoc().add(self) def input_change(self, obj, attrname, old, new): #import pdb;pdb.set_trace() print "source len: ", len(self.source.data['state']) print "county len: ", len(self.county_source.data['names']) self.update_source() self.update_county_source() print "source len: ", len(self.source.data['state']) print "county len: ", len(self.county_source.data['names']) if self.selectr.value is None or self.selectr.value == 'Choose A State': pass else: self.plot.title = self.selectr.value
size=3), width=1000) text_input = TextInput(value=" ", title="Name", width=width_number) text_input.js_on_change( "value", CustomJS( code= """console.log('text_input: value=' + this.value, this.toString())""")) select_property = Select( title='What type of property are you most interested in?', value='Land', options=sorted(['Land', 'Detached', "Townhome", "Condo"]), width=width_number) select_property.on_change('value', update_property) select_time = Select(title='What is your ideal time horizon to own?', value='1-2 years', options=[ '1-2 years', '3-5 years', '5-10 years', "10+ years", ], width=width_number) select_time.on_change('value', update_time) select_time_buy = Select(title='When do you want to buy the first property?', value='2 years', options=[
def sw_industry_analysis(): def nix(val, lst): return [x for x in lst if x != val] def get_data(ticker_1, ticker_2, start='20180101', end=datetime.today().date()): df = get_price([ticker_1, ticker_2], start, end, fields='close') df['t1_returns'] = np.log(df[ticker_1]).diff() df['t2_returns'] = np.log(df[ticker_2]).diff() return df.dropna().reset_index() def get_hhist_data(data): hhist, hedges = np.histogram(data['t1_returns'], bins=20) hzeros = np.zeros_like(hhist) hhist_data = {'left': hedges[:-1], 'right': hedges[1:], 'bottom': hzeros, 'top': hhist, 'top_1': hzeros, 'top_2': hzeros} return hhist_data def get_vhist_data(data): vhist, vedges = np.histogram(data['t2_returns'], bins=20) vzeros = np.zeros_like(vhist) vhist_data = {'left': vzeros, 'right': vhist, 'bottom': vedges[:-1], 'top': vedges[1:], 'right_1': vzeros, 'right_2': vzeros} return vhist_data def ticker1_change(attr, old, new): ticker_2.options = nix(new, DEFAULT_TICKERS) update() def ticker2_change(attr, old, new): ticker_1.options = nix(new, DEFAULT_TICKERS) update() def update(): global df ticker_1_name, ticker_2_name = SHENWAN_INDUSTRY_MAP_[ticker_1.value], SHENWAN_INDUSTRY_MAP_[ticker_2.value] df = get_data(ticker_1_name, ticker_2_name) source.data.update(dict(x=df['t1_returns'], y=df['t2_returns'], x_p=df[ticker_1_name], y_p=df[ticker_2_name], date=df['date'])) hhist_data_dict = get_hhist_data(df) source_hhist.data.update(hhist_data_dict) hmax = max(source_hhist.data['top']) * 1.1 ph.y_range.update(start=-hmax, end=hmax) print('ph.y_range', ph.y_range.end) vhist_data_dict = get_vhist_data(df) source_vhist.data.update(vhist_data_dict) vmax = max(source_vhist.data['right']) * 1.1 pv.x_range.update(start=vmax, end=-vmax) print('pv.x_range', pv.x_range.end) print(20 * '=') update_stats(df, ticker_1_name, ticker_2_name) corr.title.text = "{} vs. {}".format(ticker_1.value, ticker_2.value) ts1.title.text = ticker_1.value ts2.title.text = ticker_2.value def udpate_selection(attr, old, new): inds = new # 选定的数据对应的索引 length = len(df) if 0 < len(inds) < length: neg_inds = [s for s in range(length) if s not in inds] # 未选定数据点的对应索引 _, hedges = np.histogram(df['t1_returns'], bins=20) _, vedges = np.histogram(df['t2_returns'], bins=20) new_hhist_df = df['t1_returns'] new_vhist_df = df['t2_returns'] hhist1, _ = np.histogram(new_hhist_df.iloc[inds], bins=hedges) hhist2, _ = np.histogram(new_hhist_df.iloc[neg_inds], bins=hedges) vhist1, _ = np.histogram(new_vhist_df.iloc[inds], bins=vedges) vhist2, _ = np.histogram(new_vhist_df.iloc[neg_inds], bins=vedges) source_hhist.patch({'top_1': [(slice(None), hhist1)], 'top_2': [(slice(None), -hhist2)]}) source_vhist.patch({'right_1': [(slice(None), vhist1)], 'right_2': [(slice(None), -vhist2)]}) def update_stats(data, t1, t2): stats_indicator = data[[t1, t2, 't1_returns', 't2_returns']].describe() ticker_1_name, ticker_2_name = ticker_1.value, ticker_2.value stats_indicator.columns = [ticker_1_name, ticker_2_name, ticker_1_name + '收益率', ticker_2_name + '收益率'] stats.text = str(stats_indicator) # Set Up Widgets stats = PreText(text='', width=700) ticker_1 = Select(value='非银金融', options=nix('食品饮料', DEFAULT_TICKERS)) ticker_2 = Select(value='食品饮料', options=nix('非银金融', DEFAULT_TICKERS)) # Callback ticker_1.on_change('value', ticker1_change) ticker_2.on_change('value', ticker2_change) # Construct DataSource source = ColumnDataSource(data=dict(x=[], y=[], x_p=[], y_p=[], date=[])) source_hhist = ColumnDataSource(data=dict(left=[], right=[], bottom=[], top=[], top_1=[], top_2=[])) source_vhist = ColumnDataSource(data=dict(left=[], right=[], bottom=[], top=[], right_1=[], right_2=[])) # 收益率散点图 corr = figure(plot_width=500, plot_height=500, tools=TOOLS) r = corr.scatter(x='x', y='y', size=2, source=source, selection_color='orange', alpha=0.6, nonselection_alpha=0.1, selection_alpha=0.4) # 添加横轴直方图 hmax = 40 ph = figure(toolbar_location=None, plot_width=corr.plot_width, plot_height=200, y_range=(-hmax, hmax), min_border=10, min_border_left=None, y_axis_location='left', x_axis_location='above') ph.quad(bottom='bottom', top='top', left='left', right='right', color='white', line_color="#3A5785", source=source_hhist) ph.quad(bottom='bottom', top='top_1', left='left', right='right', alpha=0.5, source=source_hhist, **LINE_ARGS) ph.quad(bottom='bottom', top='top_2', left='left', right='right', alpha=0.1, source=source_hhist, **LINE_ARGS) ph.xgrid.grid_line_color = None ph.yaxis.major_label_orientation = np.pi / 4 ph.background_fill_color = '#fafafa' # 添加纵轴直方图 vmax = 40 pv = figure(toolbar_location=None, plot_height=corr.plot_height, plot_width=200, x_range=(vmax, -vmax), min_border=10, min_border_left=None, y_axis_location='left') pv.quad(bottom='bottom', top='top', left='left', right='right', color='white', line_color="#3A5785", source=source_vhist) pv.quad(bottom='bottom', top='top', left='left', right='right_1', alpha=0.5, source=source_vhist, **LINE_ARGS) pv.quad(bottom='bottom', top='top', left='left', right='right_2', alpha=0.1, source=source_vhist, **LINE_ARGS) # 股价时间序列图 ts1 = figure(plot_width=900, plot_height=200, tools=TOOLS, x_axis_type='datetime', active_drag='box_select', toolbar_location='above') ts1.line('date', 'x_p', source=source) ts1.circle('date', 'x_p', size=1, source=source, color=None, selection_color='orange') ts2 = figure(plot_width=ts1.plot_width, plot_height=ts1.plot_height, tools=TOOLS, x_axis_type='datetime', active_drag='box_select', toolbar_location='above') ts2.x_range = ts1.x_range ts2.line('date', 'y_p', source=source) ts2.circle('date', 'y_p', size=1, source=source, color=None, selection_color='orange') # 初始化数据 update() r.data_source.selected.on_change('indices', udpate_selection) widgets = column(ticker_1, ticker_2, widgetbox(stats)) layout_1 = column(row(Spacer(width=200, height=200), ph), row(pv, corr, widgets)) layout_2 = column(layout_1, ts1, ts2) tab = Panel(child=layout_2, title='IndustryAnalysis') return tab
def create(self): manufacturers = sorted(mpg["manufacturer"].unique()) models = sorted(mpg["model"].unique()) transmissions = sorted(mpg["trans"].unique()) drives = sorted(mpg["drv"].unique()) classes = sorted(mpg["class"].unique()) manufacturer_select = Select(title="Manufacturer:", value="All", options=["All"] + manufacturers) manufacturer_select.on_change('value', self.on_manufacturer_change) model_select = Select(title="Model:", value="All", options=["All"] + models) model_select.on_change('value', self.on_model_change) transmission_select = Select(title="Transmission:", value="All", options=["All"] + transmissions) transmission_select.on_change('value', self.on_transmission_change) drive_select = Select(title="Drive:", value="All", options=["All"] + drives) drive_select.on_change('value', self.on_drive_change) class_select = Select(title="Class:", value="All", options=["All"] + classes) class_select.on_change('value', self.on_class_change) columns = [ TableColumn(field="manufacturer", title="Manufacturer", editor=SelectEditor(options=manufacturers), formatter=StringFormatter(font_style="bold")), TableColumn(field="model", title="Model", editor=StringEditor(completions=models)), TableColumn(field="displ", title="Displacement", editor=NumberEditor(step=0.1), formatter=NumberFormatter(format="0.0")), TableColumn(field="year", title="Year", editor=IntEditor()), TableColumn(field="cyl", title="Cylinders", editor=IntEditor()), TableColumn(field="trans", title="Transmission", editor=SelectEditor(options=transmissions)), TableColumn(field="drv", title="Drive", editor=SelectEditor(options=drives)), TableColumn(field="class", title="Class", editor=SelectEditor(options=classes)), TableColumn(field="cty", title="City MPG", editor=IntEditor()), TableColumn(field="hwy", title="Highway MPG", editor=IntEditor()), ] data_table = DataTable(source=self.source, columns=columns, editable=True) plot = Plot(title=None, x_range= DataRange1d(), y_range=DataRange1d(), plot_width=1000, plot_height=300) # Set up x & y axis plot.add_layout(LinearAxis(), 'below') yaxis = LinearAxis() plot.add_layout(yaxis, 'left') plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) # Add Glyphs cty_glyph = Circle(x="index", y="cty", fill_color="#396285", size=8, fill_alpha=0.5, line_alpha=0.5) hwy_glyph = Circle(x="index", y="hwy", fill_color="#CE603D", size=8, fill_alpha=0.5, line_alpha=0.5) cty = plot.add_glyph(self.source, cty_glyph) hwy = plot.add_glyph(self.source, hwy_glyph) # Add the tools tooltips = [ ("Manufacturer", "@manufacturer"), ("Model", "@model"), ("Displacement", "@displ"), ("Year", "@year"), ("Cylinders", "@cyl"), ("Transmission", "@trans"), ("Drive", "@drv"), ("Class", "@class"), ] cty_hover_tool = HoverTool(renderers=[cty], tooltips=tooltips + [("City MPG", "@cty")]) hwy_hover_tool = HoverTool(renderers=[hwy], tooltips=tooltips + [("Highway MPG", "@hwy")]) select_tool = BoxSelectTool(renderers=[cty, hwy], dimensions=['width']) plot.add_tools(cty_hover_tool, hwy_hover_tool, select_tool) controls = VBox(children=[ manufacturer_select, model_select, transmission_select, drive_select, class_select]) top_panel = HBox(children=[controls, plot]) layout = VBox(children=[top_panel, data_table]) return layout
def line_tab(df): cluster_indicators = df.columns[2:-1] clusters = df['Country'].unique() #define function to create data set for plotting def create_dataset(data, indicator, selected_clusters): color_palette = Category20_12 #set color dictionary mapping regions to colors colormap = { cluster: color_palette[i] for i, cluster in enumerate(data['Country'].unique()) } #subset data by selected clusters subset = data[data['Country'].isin(selected_clusters)] #create datasource for plotting points source_point = ColumnDataSource({ 'year': subset['Year'], 'cluster': subset['Country'], 'value': subset[indicator], #values for selected indicator 'colors': [colormap[cluster] for cluster in subset['Country']] }) #create datasource for plotting lines. for multiple line plotting, data source has to be a list of lists, each list being data points for each group xs = [] ys = [] colors = [] for cluster in subset['Country'].unique(): df_cluster = subset[subset['Country'] == cluster] xs.append(list(df_cluster['Year'])) ys.append(list(df_cluster[indicator])) colors.append(colormap[cluster]) source_line = ColumnDataSource({ 'year': xs, 'value': ys, 'cluster': list(subset['Country'].unique()), 'colors': colors }) return source_point, source_line #define function to plot interactive line charts def create_plot(source_pt, source_line, y): #create plot figure p = figure(plot_width=800, plot_height=500, title=y, x_axis_label='Year', y_axis_label=y, sizing_mode='scale_both') #plot lines p.multi_line('year', 'value', line_width=1, color='colors', source=source_line, legend='cluster') #plot points p.circle('year', 'value', size=3, fill_color='white', line_color='colors', source=source_pt) #set plot aesthetics p.legend.label_text_font_size = '8pt' p.x_range = Range1d(2001, 2030) p.xaxis.minor_tick_line_color = None p.xgrid.grid_line_color = None p.title.text_font_size = '12pt' p.xaxis.axis_label_text_font_style = 'normal' p.yaxis.axis_label_text_font_style = 'normal' #add hovertool to show details for each data point hover = HoverTool(tooltips=[ ("Cluster: ", "@cluster"), ("Value:", "$y{1.1}"), ]) p.add_tools(hover) return p #update plot on user input def update(attr, old, new): #get current values of inputs y = y_select.value selected_clusters = [ cluster_selection.labels[i] for i in cluster_selection.active ] #update sources new_source_pt, new_source_line = create_dataset( df, y, selected_clusters) source_pt.data = new_source_pt.data source_line.data = new_source_line.data #update labels and titles p.title.text = y p.yaxis.axis_label = y #add selection widget y_select = Select(title="Select indicator", value=cluster_indicators[3], options=list(cluster_indicators)) y_select.on_change('value', update) #add explanatory text for checkbox group text = Div(text="""Select cluster""") #add selection widget cluster_selection = CheckboxGroup(labels=list(clusters), active=[11]) cluster_selection.on_change('active', update) #set initial values to current widget values y = y_select.value selected_clusters = [ cluster_selection.labels[i] for i in cluster_selection.active ] #get initial dataset and plot source_pt, source_line = create_dataset(df, y, selected_clusters) p = create_plot(source_pt, source_line, y) #layout widgets and plot controls = WidgetBox(y_select, text, cluster_selection, width=400, sizing_mode='scale_both') layout = row(controls, p) tab = Panel(child=layout, title='Trend in gender indicators') return tab
tools="pan,wheel_zoom,box_zoom,reset,resize") barchart.title = "Formula SAE Michigan " + str(year) + " Total Scores by Place" barchart._xaxis.axis_label = "Teams" barchart._xaxis.axis_line_color = None barchart._xaxis.major_tick_line_color = None barchart._xaxis.minor_tick_line_color = None barchart._xaxis.major_label_text_font_size = '0.6em' barchart._yaxis.axis_label = "Total Score" barchart._yaxis.axis_line_color = None barchart._yaxis.major_tick_line_color = None barchart._yaxis.minor_tick_line_color = None barchart.outline_line_color = None barchart.toolbar_location = 'right' barchart.logo = None return barchart select_year.on_change('value', on_year_change) # Bokeh plotting output layout = HBox(children=[select_year, generate_chart(int(selectable_years[-1]))]) curdoc().add_root(layout)
class Errorsviewer: def __init__(self, resdir): self.config = {} self.fig = None self.contr = {} self.currparams = {} self.var = 'sensorsnum' self.resdir = resdir self.cols = [ '#b3de69', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#8dd3c7', '#fccde5', '#d9d9d9', '#bc80bd', '#ffffb3'] if os.path.exists(os.path.join(resdir, 'config.json')): with open(os.path.join(resdir, 'config.json'), 'r') as fh: self.config = json.load(fh) else: for ff in os.listdir(resdir): if not ff.endswith(".json"): continue config = json.load(open(os.path.join(resdir, ff))) if self.config: for k, v in config.items(): if type(v) != list: continue self.config[k] += v else: self.config = config for k in self.config.keys(): if type(self.config[k]) == list: self.config[k] = sorted(list(set(self.config[k]))) self.create_gui() self.scaling = 'linear' self.add_controllers() self.update_plot() self.blocked = False self.scalingwidget = [] ########################################################## def create_gui(self): self.guirow = Row(widgetbox(), widgetbox()) bp.curdoc().add_root(self.guirow) bp.curdoc().title = 'Simulation results of {}'.format(self.resdir) ########################################################## def add_controllers(self): titles = {'npeople': 'Number of people', 'sensorinterval': 'Interval', 'sensortpr': 'True positive rate', 'sensorexfp': 'Expected num of FP', 'sensorrange': 'Sensor range', 'sensorsnum': 'Fleet size', 'sensorspeed': 'Fleet speed'} idx0 = 1 stacked = [] #Create a controller for the scaling def on_scaling_changed(_, _old, _new): self.scaling = _new self.update_plot() self.scalingwidget = Select(title='Scaling', value='linear', options=['linear', 'log']) self.scalingwidget.on_change('value', on_scaling_changed) stacked.append(self.scalingwidget) # Create a controller for each param for k in titles.keys(): def on_radio_changed(attr, old, new, kk): if self.blocked: return newvalue = self.config[kk][new-1] if new != FIXEDIDX else -1 print('Changed ' + str(kk) + ' to ' + str(newvalue)) self.currparams[kk] = newvalue if new == FIXEDIDX: self.blocked = True for param in self.contr.keys(): if param == kk or self.contr[param].active != FIXEDIDX: continue self.contr[param].active = 1 self.currparams[param] = self.config[param][0] self.var = kk varyingparam = False for kkk, vvv in self.currparams.items(): if vvv == -1: varyingparam = True break if not varyingparam: self.var = None self.update_plot() if self.blocked: self.blocked = False my_radio_changed = partial(on_radio_changed, kk=k) params = ['varying'] + list(map(str, self.config[k])) buttonisactive = FIXEDIDX if self.var == k else idx0 self.contr[k] = RadioButtonGroup(labels=params, active=buttonisactive) self.contr[k].on_change('active', my_radio_changed) self.currparams[k] = params[idx0] r = Row(widgetbox(Div(text='{}:'.format(titles[k]))), self.contr[k]) stacked.append(r) self.currparams[self.var] = -1 adjwidget = Column(*stacked) self.guirow.children[0] = adjwidget ########################################################## def update_plot(self): #attr = 'fleetsize' attr = self.var titletxt = 'Densities error ' if attr: titletxt += 'according to {}'.format(attr) yaxistitle = 'Error' if self.scaling == 'log': yaxistitle = 'Log-' + yaxistitle self.fig = bp.figure(plot_width=800, plot_height=600, x_axis_label='Ticks', y_axis_label=yaxistitle, title=titletxt) nrepeats = int(self.config['nrepeats']) nticks = int(self.config['nticks']) deltax = 10 if not self.var: p = self.currparams err = np.ndarray((nticks, nrepeats)) acc = 0 for r in range(nrepeats): filename = 'npeople{}_sensorsnum{}_sensorrange{}_' \ 'sensorinterval{}_sensortpr{}_sensorexfp{}_' \ 'sensorspeed{}_repeat{}.npy'. \ format(p['npeople'], p['sensorsnum'], p['sensorrange'], p['sensorinterval'], p['sensortpr'], p['sensorexfp'], p['sensorspeed'], r) fullfile = os.path.join(self.resdir, filename) if not os.path.exists(fullfile): continue aux = np.load(fullfile) err[:, acc] = aux[:, 2] acc += 1 err = err[:, :acc-1] _means = np.mean(err, axis=1) if self.scaling == 'log': _means = np.log(_means) _stds = np.std(err, axis=1) if attr: legendtxt = '{} {} ({} runs)'. \ format(attr, self.currparams[attr], acc) else: legendtxt = '' self.plot_errorbar(range(0, _means.shape[0], deltax), _means[0::deltax], _stds[0::deltax], legendtxt, self.cols[0]) else: p = self.currparams.copy() i = 0 for v in self.config[self.var]: p[self.var] = v err = np.ndarray((nticks, nrepeats)) acc = 0 for r in range(nrepeats): filename = 'npeople{}_sensorsnum{}_sensorrange{}_' \ 'sensorinterval{}_sensortpr{}_sensorexfp{}_' \ 'sensorspeed{}_repeat{}.npy'. \ format(p['npeople'], p['sensorsnum'], p['sensorrange'], p['sensorinterval'], p['sensortpr'], p['sensorexfp'], p['sensorspeed'], r) fullfile = os.path.join(self.resdir, filename) if not os.path.exists(fullfile): continue aux = np.load(fullfile) err[:, acc] = aux[:, 2] acc += 1 if acc == 0: continue err = err[:, :acc-1] _means = np.mean(err, axis=1) if self.scaling == 'log': _means = np.log(_means) _stds = np.std(err, axis=1) legendtxt = '{} {} ({} runs)'.format(attr, v, acc) _ticks = range(0, _means.shape[0], deltax) #_xaxis = _ticks _xaxis = np.array(_ticks) * int(p['sensorsnum']) * int(p['sensorinterval']) self.plot_errorbar(_xaxis, _means[0::deltax], _stds[0::deltax], legendtxt, self.cols[i]) i += 1 self.guirow.children[1] = self.fig ########################################################## def plot_errorbar(self, x, y, errors, datatitle='', col='gray'): self.figline = self.fig.line(x, y, line_width=2, color=col, legend=datatitle) xflipped = np.flip(x, 0) yerrorupper = y + errors yerrorlower = np.flip(y, 0) - np.flip(errors, 0) yerrorbounds = np.append(yerrorupper, yerrorlower) self.fig.patch(x=np.append(x,xflipped), y=yerrorbounds, color=col, alpha=0.1)
class widgetDIMS(object): column_names_rocks = [ 'kclay', 'muclay', 'rhoclay', 'knonclay', 'munonclay', 'rhononclay', 'vclay', 'phi', 'dryEk', 'dryPk', 'dryEg', 'dryPg' ] column_names_fluids = [ 'Name', 'ko', 'rhoo', 'kw', 'rhow', 'kg', 'rhog', 'so', 'sw', 'sg' ] column_names_pres = ['Name', 'OB_Grad', 'init_Pres', 'curr_Pres'] column_names_output = ['rock', 'fluid', 'Vp', 'Vs', 'rho', 'other'] def __init__(self, init_depth, file_rocks, file_fluids, file_prespfs, fdi=None): ''' :param init_depth: Initial depth to model (TVDSS). :param file_rocks: File with input mineral parameters. :param file_fluids: File with input fluid parameters. :param file_prespfs: File with input pressure profiles. :keyword dependents: A list of geoPy widgets which need to be updated when widgetDIMS is changed. ''' # Initial Data self.df_rocks = pd.read_csv(file_rocks, skipinitialspace=True) self.df_fluids = pd.read_csv(file_fluids, skipinitialspace=True) self.df_pres = pd.read_csv(file_prespfs, skipinitialspace=True) self.init_depth = init_depth # mTVDSS self.pagewidth = 1000 # pixels self.fdi = fdi # Setup Sources self.CDS_rocks = ColumnDataSource(self.df_rocks) self.CDS_fluids = ColumnDataSource(self.df_fluids) self.CDS_pres = ColumnDataSource(self.df_pres) self.CDS_out = ColumnDataSource(data=dict()) # Extract Names self.odict_rocks = self.__odictIndex(self.df_rocks.Name.tolist()) self.odict_fluids = self.__odictIndex(self.df_fluids.Name.tolist()) self.odict_pres = self.__odictIndex(self.df_pres.Name.tolist()) # Setup widgets self.createTableWidgets() self.createControls() self.createLayout() self.on_selection_change('value', 1, 1) def __odictIndex(self, keys): out = ExtOrderedDict() for ind, key in enumerate(keys): out[key] = ind return out def createTableWidgets(self): self.col_rocks = [ TableColumn(field=Ci, title=Ci) for Ci in self.column_names_rocks ] self.col_fluids = [ TableColumn(field=Ci, title=Ci) for Ci in self.column_names_fluids ] self.col_pres = [ TableColumn(field=Ci, title=Ci) for Ci in self.column_names_pres ] self.col_out = [ TableColumn(field=Ci, title=Ci) for Ci in self.column_names_output ] #Setup table widgets tablekwargs = {'width': self.pagewidth, 'editable': True} self.TW_rocks = DataTable(source=self.CDS_rocks, columns=self.col_rocks, **tablekwargs) self.TW_fluids = DataTable(source=self.CDS_fluids, columns=self.col_fluids, **tablekwargs) self.TW_pres = DataTable(source=self.CDS_pres, columns=self.col_pres, **tablekwargs) self.TW_out = DataTable(source=self.CDS_out, columns=self.col_out, **tablekwargs) def createControls(self): # Setup Select Panes and Input Widgets #Obr - Overburden rock #ResR - Reservoir rock #Obf - Oberburden fluid #Resf - Reservoir fluid self.selectObr = Select(value=self.odict_rocks.keyslist()[0], options=self.odict_rocks.keyslist(), title="Rock Model") self.selectResR = Select(value=self.odict_rocks.keyslist()[0], options=self.odict_rocks.keyslist(), title="Rock Model") self.selectObf = Select(value=self.odict_fluids.keyslist()[0], options=self.odict_fluids.keyslist(), title="Fluid Model") self.selectResf = Select(value=self.odict_fluids.keyslist()[0], options=self.odict_fluids.keyslist(), title="Fluid Model") self.selectPres = Select(value=self.odict_pres.keyslist()[0], options=self.odict_pres.keyslist(), title="Pressure Scenario") self.slideDepth = Slider(start=0, end=10000, value=self.init_depth, step=10, title='Depth (TVDSS)', callback_policy='mouseup') self.selectObr.on_change('value', self.on_selection_change) self.selectResR.on_change('value', self.on_selection_change) self.selectObf.on_change('value', self.on_selection_change) self.selectResf.on_change('value', self.on_selection_change) self.selectPres.on_change('value', self.on_selection_change) self.slideDepth.on_change('value', self.on_selection_change) def createLayout(self): # Layout of Page self.inputTab1 = Panel(child=self.TW_rocks, title='Rock Models') self.inputTab2 = Panel(child=self.TW_fluids, title='Fluid Mixes') self.inputTab3 = Panel(child=self.TW_pres, title='Pressure Scenarios') self.inputTab4 = Panel(child=self.TW_out, title='Model Calculations') self.inputTabs = Tabs(tabs=[ self.inputTab1, self.inputTab2, self.inputTab3, self.inputTab4 ], width=self.pagewidth, height=200) textrowob = Div(text="<h1> Overburden: </h1>") selectrowob = row(self.selectObr, self.selectObf, width=500, height=50, sizing_mode="scale_both") textrowres = Div(text="<h1> Reservoir: </h1>") selectrowres = row(self.selectResR, self.selectResf, width=500, height=50, sizing_mode="scale_both") selectrowpres = row(self.selectPres, self.slideDepth, width=500, height=50, sizing_mode="scale_both") self.layout = column(self.inputTabs, textrowob, selectrowob, textrowres, selectrowres, selectrowpres, width=self.pagewidth) def on_selection_change(self, attribute, old, new): # update active selections self.activeObr = self.df_rocks.loc[self.odict_rocks[ self.selectObr.value]] #Overburden Rock and Fluid self.activeObf = self.df_fluids.loc[self.odict_fluids[ self.selectObf.value]] self.activeResR = self.df_rocks.loc[self.odict_rocks[ self.selectResR.value]] #Reservoir Rock and Fluid self.activeResF = self.df_fluids.loc[self.odict_fluids[ self.selectResf.value]] self.activePresPf = self.df_pres.loc[self.odict_pres[ self.selectPres.value]] #Pressure Profile self.cur_depth = self.slideDepth.value self.updateRocks() self.updateFluids() self.updateRockModel() if self.fdi != None: self.fdi.updateModel(self.activeResR_dry, self.activeResF_mix, self.fdi.min_pres, self.fdi.max_pres, init_imp=self.activeResRM.pimp) def updateRocks(self): #update rock models based upon selections parnonclay = ['knonclay', 'munonclay', 'rhononclay'] parclay = ['kclay', 'muclay', 'rhoclay'] obnonshale = structMineral( 'nonshale', *[self.activeObr[par] for par in parnonclay]) obshale = structMineral('shale', *[self.activeObr[par] for par in parclay]) nonshale = structMineral('nonshale', *[self.activeResR[par] for par in parnonclay]) shale = structMineral('shale', *[self.activeResR[par] for par in parclay]) # output rock names to table self.CDS_out.data['rock'] = [ self.activeObr['Name'], self.activeResR['Name'] ] #update dryrock properties self.activeObr_dry = structDryFrame(self.activeObr['Name'], obnonshale, obshale, self.activeObr['vclay'], self.activeObr['phi']) self.activeResR_dry = structDryFrame(self.activeResR['Name'], nonshale, shale, self.activeResR['vclay'], self.activeResR['phi']) self.activeObr_dry.calcRockMatrix() self.activeResR_dry.calcRockMatrix() parp = ['init_Pres', 'curr_Pres'] pardry = ['dryEk', 'dryPk', 'dryEg', 'dryEk'] self.activeObr_dry.calcDryFrame( self.activePresPf['OB_Grad'], self.cur_depth, *[self.activePresPf[par] for par in parp], *[self.activeObr[par] for par in pardry]) self.activeResR_dry.calcDryFrame( self.activePresPf['OB_Grad'], self.cur_depth, *[self.activePresPf[par] for par in parp], *[self.activeResR[par] for par in pardry]) def updateFluids(self): # oil, water, gas, setup and mixing parw = ['kw', 'rhow', 'sw'] paro = ['ko', 'rhoo', 'so'] parg = ['kg', 'rhog', 'sg'] self.activeObf_mix = structFluid( self.activeObf['Name'], water=[self.activeObf[ind] for ind in parw], oil=[self.activeObf[ind] for ind in paro], gas=[self.activeObf[ind] for ind in parg]) self.activeResF_mix = structFluid( self.activeResF['Name'], water=[self.activeResF[ind] for ind in parw], oil=[self.activeResF[ind] for ind in paro], gas=[self.activeResF[ind] for ind in parg]) # output fluid names to table self.CDS_out.data['fluid'] = [ self.activeObf['Name'], self.activeResF['Name'] ] def updateRockModel(self): # calculate rock models and properties self.activeObrM = structRock(self.activeObr_dry, self.activeObf_mix) self.activeObrM.calcGassmann() self.activeObrM.calcDensity() self.activeObrM.calcElastic() self.activeResRM = structRock(self.activeResR_dry, self.activeResF_mix) self.activeResRM.calcGassmann() self.activeResRM.calcDensity() self.activeResRM.calcElastic() # output rockproperties to table self.CDS_out.data['Vp'] = [self.activeObrM.velp, self.activeResRM.velp] self.CDS_out.data['Vs'] = [self.activeObrM.vels, self.activeResRM.vels] self.CDS_out.data['rho'] = [self.activeObrM.den, self.activeResRM.den] self.CDS_out.data['other'] = [ self.activeObrM.pimp, self.activeResRM.pimp ]
arrow_data["ys"] = [[y_start] for y_start in arrow_data["y_start"]] for i in range(len(arrow_data["y_end"])): arrow_data["ys"][i] += [arrow_data["y_end"][i]] arrow_source.data = arrow_data apply_changes(ANN.layers) def change_learning_rate(_attr, _old, new): ANN.update(new, ANN.activation_func, ANN.layers, ANN.epoch) apply_changes(ANN.layers) learning_rate_select.on_change("value", change_learning_rate) def change_activation_func(_attr, _old, new): ANN.update(ANN.learning_rate, new, ANN.layers, ANN.epoch) activation_func_select.on_change("value", change_activation_func) def add_layer(): global layer_num, current_layer if len(ANN.layers) == 10: return layer = ANN.layers[:-1] layer += [3]
if item.title == 'X-Axis Value': item.value = 'corresponding_wt_score' elif item.title == 'Y-Axis Value': item.value = 'best_mt_score' except AttributeError: continue if presets.labels[presets.active] == "Tumor Clonality and Expression": for item in widgets: try: if item.title == 'X-Axis Value': item.value = 'tumor_dna_vaf' elif item.title == 'Y-Axis Value': item.value = 'tumor_rna_vaf' except AttributeError: continue #Add callbacks to the 3 widgets manually created back at the start x_field.on_change('value', lambda a, r, g: update()) y_field.on_change('value', lambda a, r, g: update()) presets.on_change('active', lambda a, r, g: change_preset()) hide_null.on_click(lambda arg: update()) #Add all models and widgets to the document box = widgetbox(*widgets, sizing_mode='stretch_both') fig = column(row(box, p), table, sizing_mode='scale_width') update() #initial update curdoc().add_root(fig) curdoc().title = sample
source_static.data = source.data update_stats(data, t1, t2) corr.title.text = '%s vs. %s' % (t1, t2) ts1.title.text, ts2.title.text = t1, t2 def update_stats(data, t1, t2): stats.text = str(data[['t1', 't2']].rename(columns={ 't1': t1, 't2': t2 }).describe()) ticker1.on_change('value', ticker1_change) ticker2.on_change('value', ticker2_change) sensor.on_change('value', sensor_change) def selection_change(attrname, old, new): t1, t2, s = ticker1.value, ticker2.value, sensor.value data = get_data(t1, t2, s) selected = source.selected.indices if selected: data = data.iloc[selected, :] update_stats(data, t1, t2) source.on_change('selected', selection_change)
class Display(object): def __init__(self): self.page_width = 1200 # The width of the display in the browser self.page_height = 620 # The height of the display # The temperature and humidity data used by default and if the # user selects none in the read file menu self.default_data = \ pd.DataFrame.from_dict({ 'Timestamp': ['2018-07-01 08:00:00', '2018-07-01 08:00:01', '2018-07-02 08:00:00', '2018-07-03 08:00:00', '2018-07-03 08:00:01', '2018-07-04 08:00:00', '2018-07-04 08:00:01', '2018-07-04 08:00:02', '2018-07-05 08:00:00', '2018-07-06 08:00:00', '2018-07-06 08:00:01'], 'Temperature (C)': [0, 20.0, 15.0, 20.0, 10.0, 10.0, 20.0, 10.0, 15.0, 10.0, 40.0], 'Relative humidity (%)': [0.0, 36.0, 31.0, 36.0, 26.0, 26.0, 36.0, 26.0, 31.0, 25.0, 40.0], 'Pressure (Pa)': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}) self.default_data['Timestamp'] = \ pd.to_datetime(self.default_data['Timestamp']) # We start with the default data self.data = self.default_data self.source = ColumnDataSource(data=self.data) # UT330 device self.ut330 = UT330() # Whether the UT330 device is connected or not. self.device_connected = False # Text used in dropdown menu if no file selected self.data_file_none = "No data file selected" # The Bokeh display is tabbed self.tabs = Tabs(tabs=[self.intro_tab(), self.read_file_tab(), self.h_t_tab(), self.config_tab(), self.offset_tab(), self.time_tab(), self.device_data_tab()]) # Intro tab # ========= def intro_tab(self): """Intro tab - explains the application""" html = ("<h1>UT330 UI</h1>" "<p>" "This UI controls a UT330 device from any operating " "system. It displays the temperature and humidity from " "pre-existing data files downloaded from a UT330 and it " "enables new data files to be read from a UT330 device " "connected to the computer. For full details of how the " "software works (and for licensing), read the " "<a href='https://github.com/MikeWoodward/UT330B'>" "Github page</a>." "</p>" "<p>" "Mike Woodward, 2017" "</p>") intro_text = Div(text=html, width=self.page_width, height=self.page_height) return Panel(child=widgetbox(intro_text), title="UT330 UI") # Read tab # ======== def file_changed(self, attrname, old, new): """Helper functions for read_tab - called when user selects new data file to display """ if new == self.data_file_none: self.data = self.default_data else: self.data = pd.read_csv(new, parse_dates=['Timestamp']) self.h_t_update() def scan_folder(self): """Helper function for scanning the data files folder""" pattern = os.path.join('Data', 'UT330_data_*.csv') files = glob.glob(pattern) length = len(files) if 0 == length: status_text = ("<strong>Error!</strong> There are no data " "files in the Data folder. ") else: status_text = ("There are {0} file(s) in the " "'Data' folder. ").format(length) status_text += ("Click <strong>Rescan folder</strong> to rescan the " "data folder.") # Ensure we have a 'None' option and that it's the default files.insert(0, self.data_file_none) # Update the control self.file_select.options = files self.file_select.value = files[0] self.file_status.text = status_text def read_file_tab(self): """Lets the user choose a data file to read""" # Drop down list self.file_select = Select(name='Data files', value='', options=[], title='Data files') # Status text self.file_status = Div(text='', width=self.page_width) # Update the file_select and file_status controls with scan data self.scan_folder() # This line is here deliberately. The scan_folder would trigger # the on-change function and we don't want that first time around. self.file_select.on_change('value', self.file_changed) # Re-scan button file_rescan = Button(label="Rescan folder", button_type="success") file_rescan.on_click(self.scan_folder) # Layout c = column(self.file_select, self.file_status, file_rescan) return Panel(child=c, title="Read from file") # Config tab # ========== def config_read(self): """Reads config data to disk""" if not self.device_connected: self.config_status.text = ("Cannot read the UT330 device " "config data " "because no UT330 device connected.") return # Get the config data if self.config_connected(): # The device has been read OK self.config_device_read = True else: self.config_device_read = False def config_write(self): """Writes config data to disk""" # Some error checking if not self.device_connected: self.config_status.text = ("Cannot write the UT330 config data " "to disk " "because there is no UT330 device " "connected.") return if not self.config_device_read: self.config_status.text = ("You must read the UT330 configuration " "before before " "writng different configuration data.") return try: # Get the config data config = {'device name': self.config_device_name.value, 'sampling interval': int(self.config_sampling.value), 'overwrite records': self.config_overwrite_records.value == 'True', 'delay timing': int(self.config_delay.value), 'delay start': self.config_delay_start.value == 'Delay', 'high temperature alarm': int(self.config_t_high.value), 'low temperature alarm': int(self.config_t_low.value), 'high humidity alarm': int(self.config_h_high.value), 'low humidity alarm': int(self.config_h_low.value)} # Write it self.ut330.write_config(config) self.config_status.text = ("Wrote configuration data to UT3330 " "device.") except ValueError as error: self.config_status.text = error.args[0] except: self.config_status.text = "Error in config_write function." def config_connect(self): """Attempts to connect to device""" # Look to see if the device already connected if self.device_connected: self.config_status.text = ("Cannot connect the UT330 device " "because the UT330 device is already " "connected.") return # Now try and connect try: self.ut330.connect() self.config_status.text = ("Connected to the UT330 device.") self.device_connected = True return except IOError as error: self.config_status.text = error.args[0] self.device_connected = False return def config_disconnect(self): """Attempts to disconnect from device""" if not self.device_connected: self.config_status.text = ("Cannot disconnect the UT330 device " "because no UT330 device connected.") return # Now try and disconnect try: self.ut330.disconnect() self.config_status.text = "Disconnected the UT330 device." self.config_device_read = False self.device_connected = False return except IOError as error: self.config_status.text = error.args[0] return def config_not_connected(self): """UT330 not connected - so update config controls appropriately""" self.config_status.text = "UT330 device not connected." self.config_device_name.value = "No device" self.config_device_time.value = "No device" self.config_computer_time.value = "No device" self.config_t_high.value = "No device" self.config_t_low.value = "No device" self.config_h_high.value = "No device" self.config_h_low.value = "No device" self.config_p_high.value = "No device" self.config_p_low.value = "No device" self.config_sampling.value = "No device" self.config_delay.value = "No device" self.config_power.value = "No device" self.config_readings.value = "No device" def config_connected(self): """UT330 connected - so update config controls appropriately""" try: now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") config = self.ut330.read_config() self.config_status.text = "UT330 device connected." # Populate the widgets self.config_device_name.value = config['device name'] self.config_device_time.value = config['timestamp'].strftime( "%Y-%m-%d %H:%M:%S") self.config_computer_time.value = now self.config_t_high.value = str(config['high temperature alarm']) self.config_t_low.value = str(config['low temperature alarm']) self.config_h_high.value = str(config['high humidity alarm']) self.config_h_low.value = str(config['low humidity alarm']) self.config_p_high.value = 'None' self.config_p_low.value = 'None' self.config_sampling.value = str(config['sampling interval']) self.config_overwrite_records.value = \ 'True' if config['overwrite records'] else 'False' self.config_delay_start.value = \ 'Delay' if config['delay start'] else 'No delay' self.config_delay.value = str(config['delay timing']) self.config_power.value = str(config['battery power']) self.config_readings.value = \ "{0} of {1}".format(config['readings count'], config['readings limit']) return True except: self.config_status.text = "Exception raised in config_connected." return False def config_tab(self): """Reading/writing device configuration""" # True if the config device data has been read, false otherwise self.config_device_read = False # Device connectivity # =================== config_conn_head = Div(text="<strong>Connectivity</strong>") self.config_status = Div(text="", width=self.page_width) config_connect = Button(label='Connect to UT330', button_type="success") config_read = Button(label='Read config', button_type="success") config_write = Button(label='Write config', button_type="success") config_disconnect = Button(label='Disconnect from UT330', button_type="success") config_connect.on_click(self.config_connect) config_read.on_click(self.config_read) config_write.on_click(self.config_write) config_disconnect.on_click(self.config_disconnect) # Show the configuration data # =========================== # Set up the widgets config_device_head = Div(text="<strong>Configuration</strong>") self.config_device_name = TextInput(title="Device name") self.config_device_time = TextInput(title="Device time") self.config_computer_time = TextInput(title="Computer time") self.config_t_high = TextInput(title="High temperature alarm (C)") self.config_t_low = TextInput(title="Low temperature alarm (C)") self.config_h_high = TextInput(title="High humidity alarm (%RH)") self.config_h_low = TextInput(title="Low humidity alarm (%RH)") self.config_p_high = TextInput(title="High pressure alarm") self.config_p_low = TextInput(title="Low pressure alarm") self.config_sampling = TextInput(title="Sampling interval (s)") self.config_overwrite_records = Select(title="Overwrite records", options=['False', 'True']) self.config_delay_start = Select(title="Delay start", options=['No delay', 'Delay']) self.config_delay = TextInput(title="Delay (s)") # Status data # =========== config_status_head = Div(text="<strong>Status</strong>") self.config_power = TextInput(title="Battery power (%)") self.config_readings = TextInput(title="Readings") # Disable user input for these widgets self.config_power.disabled = True self.config_readings.disabled = True # Values to widgets # ================= if self.device_connected: self.config_connected() else: self.config_not_connected() # Set up the display layout = column(row(config_conn_head), row(self.config_status), row(config_connect, config_read, config_write, config_disconnect), row(config_device_head), row(self.config_device_name, self.config_device_time, self.config_computer_time), row(self.config_t_low, self.config_h_low, self.config_p_low), row(self.config_t_high, self.config_h_high, self.config_p_high), row(self.config_sampling), row(self.config_overwrite_records, self.config_delay_start, self.config_delay), row(config_status_head), row(self.config_power, self.config_readings)) return Panel(child=layout, title="Read/write configuration") # Offset tab # ========== def offset_connect(self): """Connect the UT330 device""" # Look to see if the device already connected if self.device_connected: self.offset_status.text = ("Cannot connect the UT330 device " "because the UT330 device is already " "connected.") return # Now try and connect try: self.ut330.connect() self.offset_status.text = ("Connected to the UT330 device.") self.device_connected = True except IOError as error: self.offset_status.text = error.args[0] self.device_connected = False except: self.offset_status.text = "Exception raised in offset_connect." self.device_connected = False def offset_disconnect(self): """Disconnect the UT330 device""" if not self.device_connected: self.offset_status.text = ("Cannot disconnect the UT330 device " "because no UT330 device connected.") return # Now try and disconnect try: self.ut330.disconnect() self.offset_status.text = "Disconnected the UT330 device." self.offset_device_read = False self.device_connected = False except IOError as error: self.offset_status.text = error.args[0] except: self.offset_status.text = "Exception raised in offset_disconnect." def offset_read(self): """Reads offset data to disk""" if not self.device_connected: self.offset_status.text = ("Cannot read the UT330 device " "offset data " "because no UT330 device connected.") return # Get the config data if self.offset_connected(): # The device has been read OK self.offset_device_read = True else: self.offset_device_read = False def offset_write(self): """Writes offset data to disk""" if not self.device_connected: self.offset_status.text = ("Cannot write the UT330 offset data " "to disk " "because there is no UT330 device " "connected.") return if not self.offset_device_read: self.offset_status.text = ("You must read the UT330 offset " "before before " "writng different offset data.") return try: # Get the offset data offset = {'temperature offset': float(self.offset_t.value), 'humidity offset': float(self.offset_h.value), 'pressure offset': float(self.offset_p.value)} # Write it self.ut330.write_offsets(offset) self.offset_status.text = ("Wrote offset data to UT3330 " "device.") except ValueError as error: self.offset_status.text = error.args[0] except: self.offset_status.text = "Exception in offset_write function." def offset_not_connected(self): """UT330 not connected - so update offset controls appropriately""" self.config_status.text = "UT330 device not connected." self.offset_t_current.value = "No device" self.offset_h_current.value = "No device" self.offset_p_current.value = "No device" self.offset_t.value = "No device" self.offset_h.value = "No device" self.offset_p.value = "No device" def offset_connected(self): """UT330 connected - so update offset controls appropriately""" try: self.config_status.text = ("UT330 device connected and offsets " "read.") offsets = self.ut330.read_offsets() self.offset_t_current.value = str(offsets['temperature']) self.offset_h_current.value = str(offsets['humidity']) self.offset_p_current.value = str(offsets['pressure']) self.offset_t.value = str(offsets['temperature offset']) self.offset_h.value = str(offsets['humidity offset']) self.offset_p.value = str(offsets['pressure offset']) return True except: self.config_status.text = "UT330 device not connected." return False def offset_tab(self): """Reading/writing device offsets""" # True if the offset device data has been read, false otherwise self.offset_device_read = False offset_status_h = Div(text="<strong>Status</strong>") self.offset_status = Div(text="", width=self.page_width) # Connect to device button # ======================== offset_controls_h = Div(text="<strong>Device controls</strong>") offset_connect = Button(label='Connect to UT330', button_type="success") offset_read = Button(label='Read offset', button_type="success") offset_write = Button(label='Write offset', button_type="success") offset_disconnect = Button(label='Disconnect from UT330', button_type="success") offset_connect.on_click(self.offset_connect) offset_read.on_click(self.offset_read) offset_write.on_click(self.offset_write) offset_disconnect.on_click(self.offset_disconnect) # Offsets # ======= offset_offsets_h = Div(text="<strong>Offsets</strong>") self.offset_t_current = TextInput(title="Temperature current") self.offset_h_current = TextInput(title="Humidity current") self.offset_p_current = TextInput(title="Pressure current") self.offset_t = TextInput(title="Temperature offset") self.offset_h = TextInput(title="Humidity offset") self.offset_p = TextInput(title="Pressure offset") # Values to widgets # ================= if self.device_connected: self.offset_connected() else: self.offset_not_connected() if self.device_connected: self.offset_status.text = ('UT330 device connected. The Read, ' 'Write, and Disconnect buttons ' 'will work.') else: self.offset_status.text = ('UT330 device is <strong>NOT</strong> ' 'connected. The ' 'Read, Write, and Disconnect buttons ' 'will <strong>not work</strong>. ' 'Click the ' 'Connect button if the UT330 is ' 'connected on a USB port.') # Layout # ====== l = layout([[offset_status_h], [self.offset_status], [offset_controls_h], [offset_connect, offset_read, offset_write, offset_disconnect], [offset_offsets_h], [self.offset_t_current, self.offset_h_current, self.offset_p_current], [self.offset_t, self.offset_h, self.offset_p]], width=self.page_width) return Panel(child=l, title="Read/write offset") # Data tab # ======== def data_connect(self): """Connects to the device""" if self.device_connected: self.data_status.text = ("Cannot connect the UT330 device " "because UT330 device already connected.") return # Now try and connect try: self.ut330.connect() self.data_status.text = "Connected to the UT330 device." self.device_connected = True except IOError as error: self.data_status.text = error.args[0] self.device_connected = False except: self.data_status.text = "Exception raised in data_connect." self.device_connected = False def data_disconnect(self): """Disconnects from the device""" if not self.device_connected: self.data_status.text = ("Cannot disconnect the UT330 device " "because no UT330 device connected.") return # Now try and disconnect try: self.ut330.disconnect() self.data_status.text = "Disconnected the UT330 device." self.device_connected = False except IOError as error: self.data_status.text = error.args[0] except: self.data_status.text = "Exception raised in data_disconnect." def data_read(self): """Reads data from device""" if not self.device_connected: self.data_status.text = ("Cannot read the UT330 device " "because no UT330 device connected.") return try: self.data_status.text = "Reading in data from UT330..." data = self.ut330.read_data() count = len(data) if 0 == count: self.data_status.text = "No data to read on device." return self.data = pd.DataFrame(data) self.h_t_update() self.data_status.text = \ "{0} lines of data read in from UT330.".format(count) except: self.data_status.text = "Exception in data_read." def data_write(self): """Writes data to disk""" if not self.device_connected: self.data_status.text = ("Cannot write the UT330 device data " "to disk " "because there is no UT330 device " "connected.") return try: data = self.ut330.read_data() self.data = pd.DataFrame(data) self.h_t_update() timestamp = data[0]['Timestamp'] data_file = \ os.path.join('Data', 'UT330_data_{0}.csv'. format(timestamp.strftime("%Y%m%d_%H%M%S"))) self.data.to_csv(data_file) self.data_status.text = "Wrote data to file {0}.".format(data_file) except: self.data_status.text = "Exception in data_write." def data_erase(self): """Erases device data""" if not self.device_connected: self.data_status.text = ("Cannot erase the UT330 device data " "because no UT330 device connected.") return try: self.ut330.delete_data() self.data_status.text = "UT330 data erased." except: self.data_status.text = "Exception in data_erase." def device_data_tab(self): """Reading device data""" self.data_status = Div(text="", width=self.page_width) data_connect = Button(label='Connect to UT330', button_type="success") data_read = Button(label='Read data', button_type="success") data_write = Button(label='Write data to disk', button_type="success") data_erase = Button(label='Erase data', button_type="success") data_disconnect = Button(label='Disconnect from UT330', button_type="success") data_connect.on_click(self.data_connect) data_read.on_click(self.data_read) data_write.on_click(self.data_write) data_erase.on_click(self.data_erase) data_disconnect.on_click(self.data_disconnect) if self.device_connected: self.data_status.text = ('UT330 device connected. The Read, ' 'Write, Erase, and Disconnect buttons ' 'will work.') else: self.data_status.text = ('UT330 device is <strong>NOT</strong> ' 'connected. The ' 'Read, Write, Erase, and Disconnect ' 'buttons will <strong>not work</strong>. ' 'Press the ' 'Connect button if the UT330 is ' 'connected on a USB port.') # Layout l = layout([[self.data_status], [data_connect, data_disconnect], [data_read, data_write, data_erase]], width=self.page_width) return Panel(child=l, title="Read from device") # Humidity and temperature # ======================== # Helper function to update the Humidity and Temperature chart def h_t_update(self): """Updates Humidity/Temperature chart""" self.source.data = {'Timestamp': self.data['Timestamp'], 'Temperature (C)': self.data['Temperature (C)'], 'Relative humidity (%)': self.data['Relative humidity (%)'], 'Pressure (Pa)': self.data['Pressure (Pa)']} # Reset the y axis ranges for temperature and humidity ymin = round(self.data['Temperature (C)'].min() - 2) ymax = ceil(self.data['Temperature (C)'].max() + 2) self.h_t_fig.y_range.start = ymin self.h_t_fig.y_range.end = ymax ymin = round(self.data['Relative humidity (%)'].min() - 2) ymax = ceil(self.data['Relative humidity (%)'].max() + 2) self.h_t_fig.extra_y_ranges['humidity'].start = ymin self.h_t_fig.extra_y_ranges['humidity'].end = ymax def h_t_lines_changed(self, active): """Helper function for h_t_tab - turns lines on and off""" for index in range(len(self.h_t_line)): self.h_t_line[index].visible = index in active def h_t_tab(self): """Plots the humidity and temperature""" self.h_t_fig = figure(plot_width=int(self.page_width*0.9), plot_height=self.page_height, title="Temperature and humidity", toolbar_location="above", x_axis_type="datetime") self.h_t_fig.xaxis.axis_label = "Timestamp" self.h_t_fig.yaxis.axis_label = "Temperature (C)" # Ranges need to be defined here - causes update issues if this # doesn't happen here self.h_t_fig.y_range = Range1d(start=0, end=100) self.h_t_fig.extra_y_ranges = {'humidity': Range1d(start=0, end=100)} self.h_t_fig.add_layout(LinearAxis(y_range_name='humidity', axis_label="Relative humidity (%)"), 'right') # Add the lines self.h_t_line = 2*[None] # Plot the humidity/pressure self.h_t_line[0] = self.h_t_fig.line(x='Timestamp', y='Temperature (C)', source=self.source, color="blue", legend="Temperature", line_width=2) self.h_t_line[1] = self.h_t_fig.line(x="Timestamp", y="Relative humidity (%)", source=self.source, y_range_name="humidity", color="green", legend="Humidity", line_width=2) # Update the data and the plot ranges self.h_t_update() # Checkboxes to show lines resp_b = [0, 1] h_t_check_head = Div(text="Responses") h_t_check = CheckboxGroup(labels=["Temperature", "Humidity"], active=resp_b, name="Lines") h_t_check.on_click(self.h_t_lines_changed) # Lay out the page w = widgetbox(h_t_check_head, h_t_check, width=int(self.page_width*0.1)) l = row(w, self.h_t_fig) return Panel(child=l, title="Temperature and humidity") # Time tab # ======= def time_connect(self): """Connects to the device""" if self.device_connected: self.time_status.text = ("Cannot connect the UT330 device " "because UT330 device already connected.") return # Now try and connect try: self.ut330.connect() self.time_status.text = "Connected to the UT330 device." self.device_connected = True except IOError as error: self.time_status.text = error.args[0] self.device_connected = False except: self.time_status.text = "Exception raised in data_connect." self.device_connected = False def time_disconnect(self): """Disconnects from the device""" if not self.device_connected: self.time_status.text = ("Cannot disconnect the UT330 device " "because no UT330 device connected.") return # Now try and disconnect try: self.ut330.disconnect() self.time_status.text = "Disconnected the UT330 device." self.device_connected = False except IOError as error: self.time_status.text = error.args[0] except: self.time_status.text = "Exception raised in data_disconnect." def time_get(self): """Gets the time on the device.""" if not self.device_connected: self.time_status.text = ("Cannot get time from the UT330 device " "because no UT330 device connected.") return try: before = datetime.datetime.now() config = self.ut330.read_config() device = config['timestamp'] after = datetime.datetime.now() self.time_compare.text = "Date/time on computer before "\ "device call: {0}<br>"\ "Date/time from device: {1}<br>" \ "Date/time on computer after "\ "device call: {2}".format(before, device, after) self.time_status.text = "Got the UT330 date and time." except: self.time_status.text = "Exception in time_get." def time_set(self): """Sets the time on the device.""" if not self.device_connected: self.time_status.text = ("Cannot set time from the UT330 device " "because no UT330 device connected.") return try: now = datetime.datetime.now() self.ut330.write_date_time(now) self.time_status.text = ("Set the UT330 date and time from the " "computer.") except: self.time_status.text = "Exception in time_set." def time_tab(self): """The date and time setting and getting tab""" self.time_status = Div(text="", width=self.page_width) time_connect = Button(label='Connect to UT330', button_type="success") time_disconnect = Button(label='Disconnect from UT330', button_type="success") time_get = Button(label='Get UT330 date and time', button_type="success") self.time_compare = Div(text="", width=self.page_width) time_set = Button(label='Set the UT330 date and time', button_type="success") time_connect.on_click(self.time_connect) time_disconnect.on_click(self.time_disconnect) time_get.on_click(self.time_get) time_set.on_click(self.time_set) l = layout([self.time_status], [time_connect, time_disconnect], [time_get, self.time_compare], [time_set]) return Panel(child=l, title="Date and time setting") def go(self): """Displays the application""" document = Document() document.title = "UT330 UI" document.add_root(self.tabs) session = push_session(document) session.show() session.loop_until_closed()
def graphs_change(): """Callback on change of selected graph type""" d = curdoc() _remove_fig(d) _remove_selection(d) graph_val = d.get_model_by_name(GRAPH_SELECTION).value model_id, message_name, model_type = run_handlers.get_modelid_messagename_type( d) props = run_handlers.get_model_properties(model_id, message_name, model_type) if graph_val in ["line", "scatter", "step"]: # never want to plot this special string field field_options = [ "{0} : {1}".format(k, props[k]) for k in props if not any(apv in k for apv in [APV_MODEL]) ] xselect = Select(title="X Axis", value=DEFAULT_UNSELECTED, options=field_options + [DEFAULT_UNSELECTED], name=X_AXIS_SELECTION) yselect = Select(title="Y Axis", value=DEFAULT_UNSELECTED, options=field_options + [DEFAULT_UNSELECTED], name=Y_AXIS_SELECTION) xselect.on_change('value', lambda attr, old, new: make_2axis_graph()) yselect.on_change('value', lambda attr, old, new: make_2axis_graph()) d.add_root( column(Div(text=""), row(widgetbox([xselect]), widgetbox([yselect])), name=FIELD_SELECTION)) if graph_val in ["image"]: # alter the field options for known non-image fields field_options = [ "{0} : {1}".format(k, props[k]) for k in props if not any(apv in k for apv in [APV_RECVD, APV_SEQNO, APV_MODEL]) ] imageselect = Select(title="Image Field", value=DEFAULT_UNSELECTED, options=[DEFAULT_UNSELECTED] + field_options, name=IMAGE_SELECTION) mimeselect = Select(title="MIME Type", value=DEFAULT_UNSELECTED, options=[DEFAULT_UNSELECTED] + SUPPORTED_MIME_TYPES, name=MIME_SELECTION) imageselect.on_change('value', lambda attr, old, new: image_selection_change()) mimeselect.on_change('value', lambda attr, old, new: image_selection_change()) d.add_root( column(Div(text=""), widgetbox([imageselect, mimeselect]), name=IMAGE_MIME_SELECTION)) if graph_val in ["table"]: # TODO: limit selectable columns to whose of the same size (table height) # use just the field name; don't show properties in the multi-select box col_options = [ k for k in props if not any(apv in k for apv in [APV_RECVD, APV_SEQNO, APV_MODEL]) ] columnmultiselect = MultiSelect(title="Columns:", value=[], options=col_options, name=COLUMN_MULTISELECT) columnmultiselect.on_change( 'value', lambda attr, old, new: column_selection_change()) d.add_root( column(Div(text=""), widgetbox([columnmultiselect]), name=COLUMN_SELECTION)) if graph_val in ["raw"]: p = figure(plot_width=500, plot_height=500, background_fill_color="white", y_range=(-40, 0), title="", name=FIGURE_MODEL) p.xaxis.visible = False p.yaxis.visible = False sind = run_handlers.get_source_index(d.session_context.id, model_id, message_name) _install_callback_and_cds(sind, model_id, message_name, stream_limit=1) p.text(x='apv_sequence_number', y=0, text='apv_model_as_string', source=d.get_model_by_name(sind), text_font_size="10pt", text_line_height=0.7, text_baseline="top", text_align="left") p.x_range.follow = "end" # don't jam all the data into the graph; "window" it p.x_range.follow_interval = 1 # don't jam all the data into the graph; "window" it p.x_range.range_padding = 0 d.add_root(p)
vis_name = PROBE_LABELS[each2][1] break for each2 in vis_glyphs: if each2 == vis_name: vis_glyphs[each2].append(each) # TODO: Set visibility programatically legend = plot.legend[0].legends legend = [] for each in visible_d: # Set visibility of all plots for each2 in vis_glyphs[each]: each2.glyph.line_alpha = visible_d[each][1] try: each2.glyph.fill_alpha = visible_d[each][1] except: continue if visible_d[each] == OFF: continue else: legend.append((visible_d[each][0], vis_glyphs[each])) plot.legend[0].legends = legend #[orp_line.legend, orp_line.alpha] = visible_d['orp'] cycle.on_change('value', update_date) # Set up layouts and add to document inputs = widgetbox(cycle, probes, measure) curdoc().add_root(row(inputs, plot, width=1200)) curdoc().title = "Reactor 1 Cycle Test Visualization"
#callback def change_tiles_callback(attr, old, new): #removing the renderer corresponding to the tile layer p.renderers = [ x for x in p.renderers if not str(x).startswith('TileRenderer') ] #inserting the new tile renderer tile_renderer = TileRenderer(tile_source=tiles[new]) p.renderers.insert(0, tile_renderer) tile_prov_select = Select(title="Tile Provider", value="Light", options=['Light', 'Open Street', 'Satellite']) tile_prov_select.on_change('value', change_tiles_callback) """ HOVERTOOL """ display_columns1 = df.columns from bokeh.models import HoverTool TOOLTIP1 = HoverTool() TOOLTIP_list1 = [ '<b style="color:MediumSeaGreen;">' + name_cols + ':' + '</b><b>' + ' @{' + name_cols + '}</b>' for name_cols in display_columns1 ] #TOOLTIP=[(name_cols,'@{'+name_cols+'}') for name_cols in display_columns] TOOLTIP_end1 = "<br>".join(TOOLTIP_list1)
class BenchmarkApp(HBox): """An example of a browser-based, interactive plot with slider controls.""" extra_generated_classes = [["BenchmarkApp", "BenchmarkApp", "HBox"]] inputs = Instance(VBoxForm) # widgets benchmarks = Instance(Select) x_axis_options = Instance(Select) y_axis_options = Instance(Select) # TODO: Convert this to a MultiSelect once it is fixed # https://github.com/bokeh/bokeh/issues/2495 device_names = Instance(CheckboxGroup) platform_names = Instance(CheckboxButtonGroup) # data displays, not enabled by default data_display0 = Instance(DataTable) data_display1 = Instance(DataTable) # plot and interaction plot = Instance(Plot) hover = Instance(HoverTool) # data source0 = Instance(ColumnDataSource) source1 = Instance(ColumnDataSource) source2 = Instance(ColumnDataSource) source3 = Instance(ColumnDataSource) source4 = Instance(ColumnDataSource) source5 = Instance(ColumnDataSource) source6 = Instance(ColumnDataSource) source7 = Instance(ColumnDataSource) source8 = Instance(ColumnDataSource) source9 = Instance(ColumnDataSource) def make_source(self): # set up the data source self.source0 = ColumnDataSource(data=dict()) self.source1 = ColumnDataSource(data=dict()) self.source2 = ColumnDataSource(data=dict()) self.source3 = ColumnDataSource(data=dict()) self.source4 = ColumnDataSource(data=dict()) self.source5 = ColumnDataSource(data=dict()) self.source6 = ColumnDataSource(data=dict()) self.source7 = ColumnDataSource(data=dict()) self.source8 = ColumnDataSource(data=dict()) self.source9 = ColumnDataSource(data=dict()) def make_inputs(self): columns = [ TableColumn(field='x', title='x'), TableColumn(field='y', title='y'), TableColumn(field='device', title='device'), TableColumn(field='platform', title='platform') ] # obj.data_display0 = DataTable(source=obj.source2, columns=columns) # obj.data_display1 = DataTable(source=obj.source3, columns=columns) # setup user input self.x_axis_options = Select(title="X:", value='size', options=axis_options) self.y_axis_options = Select(title="Y:", value='throughput [1/sec]', options=axis_options) self.benchmarks = Select(title="Benchmark:", value=benchmark_names[0], options=benchmark_names) self.device_names = CheckboxGroup(labels=device_names, active=[0]) self.platform_names = CheckboxButtonGroup(labels=platform_names, active=[0]) @classmethod def create(cls): """One-time creation of app's objects. This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ obj = cls() obj.make_source() obj.make_inputs() obj.make_plot() obj.update_data() obj.set_children() return obj def plot_data(self, source, linecolor, symbolfill): self.plot.line( 'x', 'y', source=source, line_color=linecolor, line_width=3, line_alpha=0.6) self.plot.scatter('x', 'y', source=source, fill_color=symbolfill, size=8) def make_plot(self): # configure the toolset toolset = ['wheel_zoom,save,box_zoom,resize,reset'] self.hover = BenchmarkApp.make_hovertool() toolset.append(self.hover) title = self.benchmarks.value + " " + \ "(" + self.y_axis_options.value + " vs." + self.x_axis_options.value + ")" self.plot = figure(title_text_font_size="12pt", plot_height=400, plot_width=400, tools=toolset, title=title, ) # remove the logo self.plot.logo = None # Generate a figure container # Plot the line by the x,y values in the source property self.plot_data(self.source0, "#F0A3FF", "white") self.plot_data(self.source1, "#0075DC", "white") self.plot_data(self.source2, "#993F00", "white") self.plot_data(self.source3, "#4C005C", "white") self.plot_data(self.source4, "#191919", "white") self.plot_data(self.source5, "#005C31", "white") self.plot_data(self.source6, "#2BCE48", "white") self.plot_data(self.source7, "#FFCC99", "white") self.plot_data(self.source8, "#808080", "white") self.plot_data(self.source9, "#94FFB5", "white") # set the x/y axis labels # plot.xaxis.axis_label = self.x_axis_options.value # plot.yaxis.axis_label = self.y_axis_options.value def set_children(self): self.inputs = VBoxForm( children=[self.benchmarks, self.device_names, self.platform_names, self.x_axis_options, self.y_axis_options, # self.data_display0, self.data_display1 ] ) self.children.append(self.inputs) self.children.append(self.plot) @classmethod def make_hovertool(self): hover = HoverTool( tooltips = [ ("Device", "@device"), ("Backend", "@platform"), ("(x,y)", "(@x,@y)") ] ) return hover def setup_events(self): """Attaches the on_change event to the value property of the widget. The callback is set to the input_change method of this app. """ super(BenchmarkApp, self).setup_events() if not self.benchmarks: return # Event registration for everything except checkboxes self.benchmarks.on_change('value', self, 'benchmark_changed') self.x_axis_options.on_change('value', self, 'input_change') self.y_axis_options.on_change('value', self, 'input_change') # Event registration for checkboxes self.device_names.on_click(self.checkbox_handler) self.platform_names.on_click(self.checkbox_handler) def checkbox_handler(self, active): self.update_data() def benchmark_changed(self, obj, attrname, old, new): self.update_data() self.make_plot() curdoc().add(self) def input_change(self, obj, attrname, old, new): """Executes whenever the input form changes. It is responsible for updating the plot, or anything else you want. Args: obj : the object that changed attrname : the attr that changed old : old value of attr new : new value of attr """ self.update_data() self.make_plot() curdoc().add(self) def getXY(self, celero_result, axis_filter): """Returns the X or Y value as specified by axis_filter""" # TODO: Remove the baseline measurement from the timing results if axis_filter == 'size': return celero_result['data_sizes'] elif axis_filter == 'log2(size)': return np.log2(celero_result['data_sizes']) elif axis_filter == 'log10(size)': return np.log10(celero_result['data_sizes']) elif axis_filter == 'time [ms]': return celero_result['times'] * 1E-3 elif axis_filter == 'throughput [1/sec]': return 1.0 / (celero_result['times'] * 1E-6) elif axis_filter == 'throughput [log2(1/sec)]': return np.log2(1.0 / (celero_result['times'] * 1E-6)) elif axis_filter == 'throughput [log10(1/sec)]': return np.log10(1.0 / (celero_result['times'] * 1E-6)) @classmethod def make_field_ids(self, id_number): """Creates a unique set of named fields for the y, device, and platform""" i = str(id_number) y_id = 'y' + i device_id = 'device' + i platform_id = 'platform' + i return [y_id, device_id, platform_id] def update_data(self): """Called each time that any watched property changes. This updates the sin wave data with the most recent values of the sliders. This is stored as two numpy arrays in a dict into the app's data source property. """ # extract the user's input benchmark = self.benchmarks.value devices = list(device_names[i] for i in self.device_names.active) platforms = list(platform_names[i] for i in self.platform_names.active) x_axis_label = self.x_axis_options.value y_axis_label = self.y_axis_options.value # extract only the results which match this group filtered_results = filter(lambda x: x['benchmark_name'] == benchmark, celero_results) # remove the baseline measurements from the plots filtered_results = filter(lambda x: x['benchmark_name'] != "Baseline", filtered_results) # select the desired devices filtered_results = filter(lambda x: x['extra_data']['AF_DEVICE'] in devices, filtered_results) filtered_results = filter(lambda x: x['extra_data']['AF_PLATFORM'] in platforms, filtered_results) # extract the data sources = dict() result_number = 0 for result in filtered_results: # ensure we don't plot too many results if result_number > MAX_PLOTS: break y_id, device_id, platform_id = self.make_field_ids(result_number) # Extract the results from the benchmark platform = result['extra_data']['AF_PLATFORM'] device = result['extra_data']['AF_DEVICE'] x = self.getXY(result, x_axis_label) y = self.getXY(result, y_axis_label) # store the benchmark results in the self.source object # NOTE: we replicate the device and platform data here so that # it works correctly with the mouseover/hover sources['x'] = x sources[y_id] = y sources[device_id] = [device] * len(x) sources[platform_id] = [platform] * len(x) # increment the counter result_number += 1 # assign the data self.assign_source(sources, self.source0, 0) self.assign_source(sources, self.source1, 1) self.assign_source(sources, self.source2, 2) self.assign_source(sources, self.source3, 3) self.assign_source(sources, self.source4, 4) self.assign_source(sources, self.source5, 5) self.assign_source(sources, self.source6, 6) self.assign_source(sources, self.source7, 7) self.assign_source(sources, self.source8, 8) self.assign_source(sources, self.source9, 9) def assign_source(self, src, dest, index): """Assigns the data from src to the dictionary in dest if the corresponding data exists in src.""" y_id, device_id, platform_id = self.make_field_ids(index) dest.data = dict() if y_id in src: dest.data['x'] = src['x'] dest.data['y'] = src[y_id] dest.data['device'] = src[device_id] dest.data['platform'] = src[platform_id] dest._dirty = True
fig.legend.location = "top_left" fig.legend.click_policy="hide" return fig fig=plotAvgTrend() #the first dropdown with choice of commune def commune1Change(attr,old,new): global commune1 print(new) commune1=new updatePlot() selectCommune1 = Select(title="Commune 1:", value=commune1, options=communeList) selectCommune1.on_change("value",commune1Change) #the second dropdown with choice of commune def commune2Change(attr,old,new): global commune2 print(new) commune2=new updatePlot() selectCommune2 = Select(title="Commune 2:", value=commune2, options=communeList) selectCommune2.on_change("value",commune2Change) #set the Y-axis def YaxisChange(attr,old,new): global Yaxis print(new)
colors = [spectral[i] for i in y_pred] source.data['x'] = X[:, 0] source.data['y'] = X[:, 1] source.data['colors'] = colors def update_clusters(attrname, old, new): algorithm = algorithm_select.value n_clusters = int(clusters_slider.value) n_samples = int(samples_slider.value) global X X, y_pred = clustering(X, algorithm, n_clusters) colors = [spectral[i] for i in y_pred] source.data['x'] = X[:, 0] source.data['y'] = X[:, 1] source.data['colors'] = colors algorithm_select.on_change('value', update_algorithm) dataset_select.on_change('value', update_dataset) clusters_slider.on_change('value', update_clusters) samples_slider.on_change('value', update_samples) # SET UP LAYOUT sliders = VBox(children=[samples_slider, clusters_slider]) selects = HBox(children=[dataset_select, algorithm_select]) inputs = VBox(children=[sliders, selects]) plots = HBox(children=[plot]) # add to document curdoc().add_root(HBox(children=[inputs, plots]))
def animate(): global callback_id if button.label == '► Play': button.label = '❚❚ Pause' callback_id = curdoc().add_periodic_callback(animate_update, 400) else: button.label = '► Play' curdoc().remove_periodic_callback(callback_id) # drop down hour selector hour_interval_selector = Select(title='Hour interval', options=list(time_interval_dict.keys()), value='00:00') hour_interval_selector.on_change('value', lambda attr, old, new: update()) # minimum traffic flux slider flux_slider = Slider(start=0, end=30, value=0, step=1, width=1, align='start', title='Lower limit of total traffic flux') # allows scaling before update flux_slider.value = flux_slider.value flux_slider.on_change('value', lambda attr, old, new: update()) # hourly drop down and minimum flux selector hour_inputs = widgetbox(hour_interval_selector, sizing_mode='scale_width')
barchart.outline_line_color = None barchart.toolbar_location = 'right' barchart.logo = None # Hacky tooltips for renderer in barchart.select(GlyphRenderer): if renderer.data_source.data['height'] != [0]: year = renderer.data_source.data['Year'] place = data['Place'].loc[data['Year'] == year] score = data['Total Score'].loc[data['Year'] == year] hover = HoverTool(renderers=[renderer], tooltips=[("Year", '@Year'), ("Selection", '@event'), ("Event Score", '@height'), ("Total Score", '%.2f' % score.values[0]), ("Overall Place", '%d' % place.values[0])]) barchart.add_tools(hover) return barchart # init sources select_team.on_change('value', on_team_change) layout = VBox(children=[generate_chart(selectable_teams[rand]), select_team]) curdoc().add_root(layout)
class HotelApp(VBox): extra_generated_classes = [["HotelApp", "HotelApp", "VBox"]] jsmodel = "VBox" # input selectr = Instance(Select) #check_group = Instance(RadioGroup) check_group = Instance(CheckboxGroup) # plots plot = Instance(GMapPlot) bar_plot = Instance(Plot) # data source source = Instance(ColumnDataSource) county_source = Instance(ColumnDataSource) # layout boxes mainrow = Instance(HBox) #bottomrow = Instance(HBox) statsbox = Instance(VBox) totalbox = Instance(VBox) # inputs #ticker1_select = Instance(Select) #ticker2_select = Instance(Select) #input_box = Instance(VBoxForm) def make_inputs(self): with open("states.csv") as f: states = [line.strip().split(',') for line in f.readlines()] self.selectr = Select( name='states', value='Choose A State', options=[s[1] for s in states] + ['Choose A State'] ) labels = ["County Averages", "Hotels"] self.check_group = CheckboxGroup(labels=labels, active=[0,1]) def make_outputs(self): pass #self.pretext = Paragraph(text="", width=800) def __init__(self, *args, **kwargs): super(HotelApp, self).__init__(*args, **kwargs) self._show_counties = True self._show_hotels = True @classmethod def create(cls): """ This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ # create layout widgets obj = cls() obj.mainrow = HBox() #obj.bottomrow = HBox() obj.statsbox = VBox() obj.totalbox = VBox() labels = ["County Average Ratings", "Hotel Locations"] obj.make_inputs() obj.make_outputs() # outputs #obj.pretext = Paragraph(text="", width=500) obj.make_source() obj.make_county_source() lat=39.8282 lng=-98.5795 zoom=6 xr = Range1d() yr = Range1d() #obj.make_plots(lat, lng, zoom, xr, yr) obj.make_plots() # layout obj.set_children() return obj @property def selected_df(self): pandas_df = self.df selected = self.source.selected print "seeing if selected!" if selected: idxs = selected['1d']['indices'] pandas_df = pandas_df.iloc[idxs, :] else: pandas_df = pandas_df.iloc[0:0, :] return pandas_df def make_source(self): self.source = ColumnDataSource(data=self.df) self.source.callback = Callback(args=dict(), code=""" var inds = cb_obj.get('selected')['1d'].indices; var theidx = inds[0]; console.log("yep"); console.log(theidx); $.get( "reviews", {id: theidx}, function( response ) { $( "#section2" ).html( response ); }, "html"); console.log("done"); """) def update_source(self): if self.selectr.value is None or self.selectr.value == 'Choose A State': df = hdata else: df = hdata[hdata['state'] == self.selectr.value] for col in df: self.source.data[col] = df[col] def make_county_source(self): self.county_source = ColumnDataSource(data=self.countydf) def update_county_source(self): if self.selectr.value is None or self.selectr.value == 'Choose A State': df = county_data else: df = county_data[county_data['state'] == self.selectr.value] for col in df: self.county_source.data[col] = df[col] """def init_check_group(self): print "initing radio group" self.check_group.on_click(self.check_group_handler) def check_group_handler(self, active): print "radio group handler %s" % active""" def make_plots(self): self.create_map_plot() self.populate_glyphs() self.make_bar_plot() #def make_plots(self): def create_map_plot(self): lat=39.8282 lng=-98.5795 zoom=6 xr = Range1d() yr = Range1d() x_range = xr y_range = yr #map_options = GMapOptions(lat=39.8282, lng=-98.5795, zoom=6) map_options = GMapOptions(lat=lat, lng=lng, zoom=zoom) #map_options = GMapOptions(lat=30.2861, lng=-97.7394, zoom=15) plot = GMapPlot( x_range=x_range, y_range=y_range, map_options=map_options, title = "Hotel Review Explorer", plot_width=680, plot_height=600 ) plot.map_options.map_type="hybrid" xaxis = LinearAxis(axis_label="lon", major_tick_in=0, formatter=NumeralTickFormatter(format="0.000")) plot.add_layout(xaxis, 'below') yaxis = LinearAxis(axis_label="lat", major_tick_in=0, formatter=PrintfTickFormatter(format="%.3f")) plot.add_layout(yaxis, 'left') #pan = PanTool() #wheel_zoom = WheelZoomTool() #box_select = BoxSelectTool() #box_select.renderers = [rndr] #tooltips = "@name" #tooltips = "<span class='tooltip-text'>@names</span>\n<br>" #tooltips += "<span class='tooltip-text'>Reviews: @num_reviews</span>" #hover = HoverTool(tooltips="@num_reviews") #hover = HoverTool(tooltips="@names") #hover = HoverTool(tooltips=tooltips) #tap = TapTool() #plot.add_tools(pan, wheel_zoom, box_select, hover, tap) #plot.add_tools(hover, tap) #overlay = BoxSelectionOverlay(tool=box_select) #plot.add_layout(overlay) #plot.add_glyph(self.source, circle) #county_xs, county_ys = get_some_counties() #apatch = Patch(x=county_xs, y=county_ys, fill_color=['white']*len(county_xs)) #plot.add_glyph(apatch) self.plot = plot def populate_glyphs(self): self.plot.renderers=[] self.plot.tools=[] if self._show_counties: print "showing you the counties" #datasource = ColumnDataSource(county_data) #apatch = Patches(xs=county_xs, ys=county_ys, fill_color='white') #apatch = Patches(xs='xs', ys='ys', fill_color='colors', fill_alpha="alpha") apatch = Patches(xs='xs', ys='ys', fill_color='thecolors', fill_alpha='alpha') self.plot.add_glyph(self.county_source, apatch, name='counties') if self._show_hotels: print "showing you the hotels" circle2 = Circle(x="lon", y="lat", size=10, fill_color="fill2", fill_alpha=1.0, line_alpha=0.0) circle = Circle(x="lon", y="lat", size=10, fill_color="fill", fill_alpha=1.0, line_color="black") #print "source is ", self.source['lon'], self.source['lat'], self.source['f1ll'] self.plot.add_glyph(self.source, circle, nonselection_glyph=circle2, name='hotels') #county_xs, county_ys = get_some_counties() rndr = self.plot.renderers[-1] pan = PanTool() wheel_zoom = WheelZoomTool() box_select = BoxSelectTool() box_select.renderers = [rndr] tooltips = "@name" tooltips = "<span class='tooltip-text'>@names</span>\n<br>" tooltips += "<span class='tooltip-text'>Reviews: @num_reviews</span>" hover = HoverTool(tooltips=tooltips, names=['hotels']) tap = TapTool(names=['hotels']) self.plot.add_tools(pan, wheel_zoom, box_select, hover, tap) overlay = BoxSelectionOverlay(tool=box_select) self.plot.add_layout(overlay) def make_bar_plot(self): # create a new plot x_rr = Range1d(start=0.0, end=6.0) y_rr = Range1d(start=0.0, end=10.0) TOOLS = "box_select,lasso_select" bar_plot = figure(tools=TOOLS, width=400, height=350, x_range=x_rr, y_range=y_rr, title="Average Rating") #x's and y's based on selected_df sdf = self.selected_df[['names', 'ratings']] xvals = [1.0*i + 0.5 for i in range(0, len(sdf['names']))] rightvals = [1.0*i + 0.85 for i in range(0, len(sdf['names']))] ratings = [r for r in sdf['ratings']] bottoms = [0]*len(ratings) y_text = [y + 1.0 for y in ratings] all_names = [n for n in sdf['names']] print "all_names ", all_names #bar_plot.circle(xvals, ratings, size=12) bar_plot.quad(xvals, rightvals, ratings, bottoms, fill="teal") #glyph = Text(x=xvals, y=y_text, text=sdf['names'], angle=pi/4, #text_align="left", text_baseline="middle") glyphs = [Text(x=x, y=y, text=[n], angle=pi/4, text_align="left", text_baseline="middle") for x, y, n in zip(xvals, y_text, all_names)] for g in glyphs: bar_plot.add_glyph(g) bar_plot.xaxis.major_tick_line_color = None bar_plot.xaxis.minor_tick_line_color = None #bar_plot.xaxis.major_tick_line_width = 3 #bar_plot.xaxis.minor_tick_line_color = "orange" bar_plot.yaxis.minor_tick_line_color = None bar_plot.xgrid.grid_line_color = None bar_plot.ygrid.grid_line_color = None self.bar_plot = bar_plot def set_children(self): self.children = [self.totalbox] self.totalbox.children = [self.mainrow] self.mainrow.children = [self.statsbox, self.plot] self.statsbox.children = [self.selectr, self.check_group, self.bar_plot] #self.bottomrow.children = [self.pretext] def setup_events(self): super(HotelApp, self).setup_events() if self.source: self.source.on_change('selected', self, 'selection_change') if self.selectr: self.selectr.on_change('value', self, 'input_change') if self.check_group: self.check_group.on_change('active', self, 'check_change') @property def df(self): thedf = return_hotel_data() if self.selectr.value is None or self.selectr.value == 'Choose A State': return thedf else: newdf = thedf[thedf['state'] == self.selectr.value] return newdf @property def countydf(self): thedf = county_data if self.selectr.value is None or self.selectr.value == 'Choose A State': return thedf else: newdf = thedf[thedf['state'] == self.selectr.value] return newdf def selection_change(self, obj, attrname, old, new): #self.make_source() self.update_source() self.make_bar_plot() self.set_children() curdoc().add(self) def check_change(self, obj, attrname, old, new): #Turn on/off the counties/hotel data print "what the heck ", obj, attrname, old, new if 0 in new: self._show_counties = True else: self._show_counties = False if 1 in new: self._show_hotels = True else: self._show_hotels = False self.populate_glyphs() self.set_children() curdoc().add(self) def input_change(self, obj, attrname, old, new): self.make_source() self.make_county_source() print "source len: ", len(self.source.data['state']) print "county len: ", len(self.county_source.data['names']) if self.selectr.value is None or self.selectr.value == 'Choose A State': pass else: self.plot.title = self.selectr.value self.populate_glyphs() self.set_children() curdoc().add(self)
fig.xaxis.minor_tick_line_color = None fig.yaxis.minor_tick_line_color = None fig.background_fill_color = "whitesmoke" fig.line(x='date', y="y", source=linesource) fig.circle(x='date', y='y', size=5, source=pointsource) fig.text(x='date', y='y', text='text', x_offset=5, y_offset=10, text_font_size='7pt', source=pointsource) fig.title.align = 'left' fig.title.text_font_style = 'normal' plots.append(fig) i+=1 return plots abs_arrangement = make_plots(abs_sources, abs_point_sources) rel_arrangement = make_plots(rel_sources, rel_point_sources) dictchooser.on_change("value", update) timegroup.on_change('active', update) inputs = row(dictchooser, timegroup) update(None, None, None) # initial load of the data ### LAYOUT layout = column(inputs, row(column(abs_arrangement), column(rel_arrangement))) curdoc().add_root(layout) curdoc.title = "Exploring most frequent and uptrending facts"
class ShoeApp(VBox): extra_generated_classes = [["ShoeApp", "ShoeApp", "VBox"]] jsmodel = "VBox" # plots plot = Instance(Plot) brand_plot = Instance(Plot) # data source source = Instance(ColumnDataSource) brand_source = Instance(ColumnDataSource) # select selectr = Instance(Select) # layout boxes totalbox = Instance(HBox) brandbox = Instance(VBox) def __init__(self, *args, **kwargs): super(ShoeApp, self).__init__(*args, **kwargs) @classmethod def create(cls): """ This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ # create layout widgets obj = cls() obj.totalbox = HBox() obj.brandbox = VBox() obj.make_source() # outputs obj.make_better_plots() obj.make_inputs() # layout obj.set_children() return obj def make_inputs(self): self.selectr = Select( name='brands', value='Most Popular Brands', options=pop_brands + ['Most Popular Brands'], ) def make_source(self): self.source = ColumnDataSource(data=self.df) self.source.callback = Callback(args=dict(), code=""" var inds = cb_obj.get('selected')['1d'].indices; var theidx = inds[0]; var d1 = cb_obj.get("data"); var brand = d1["brand"][theidx]; console.log("yep"); console.log(theidx); $.get( "shoes", {id: brand}, function( response ) { console.log("logging rep"); console.log(response); console.log("done logging rep"); $( "#child" ).html( response ); }, "html"); console.log("done"); """) self.make_brand_source() def make_brand_source(self): self.brand_source = ColumnDataSource(data=self.brand_df) def configure_brand_source(self, min_idx=0, max_idx=MAX_IDX): bdf = self.brand_df #min_idx, max_idx = shoes_func.min_max_range(ranges, bdf['price']) min_idx, max_idx = shoes_func.min_max_range(orig_order, bdf['price']) counts = [0] * (max_idx - min_idx + 1) for i in bdf.index: ans = bdf.ix[i] #idx = int(ans['price'] + 100)//100 + 1 idx = int(ans['price']//100) print "idx is ", idx print "price is ", ans['price'] #Categorical stuff #xcat.append(ranges[idx-2]) #_shoedf.loc[i, 'brand_y'] = (counts[idx - min_idx] - 0.5*counts[idx - min_idx]) _shoedf.loc[i, 'brand_y'] = (counts[idx - min_idx]) + 0.5 counts[idx - min_idx] = counts[idx - min_idx] + 1 #quad stuff #xvals.append(idx - 0.25) #rightvals.append(idx + 0.25) #bottoms.append(counts[idx]/2) #tops.append(counts[idx] + 0.5) #fills.append(brand_to_color[ans['brand']]) return None def make_better_plots(self): TOOLS = "box_select,lasso_select" tooltips = "<span class='tooltip-text'>Name: @name</span>\n<br>" tooltips += "<span class='tooltip-text'>Brand: @brand</span>\n<br>" tooltips += "<span class='tooltip-text'>Price: @price</span>\n<br>" #hover = HoverTool(tooltips="@num_reviews") #hover = HoverTool(tooltips="@names") hover = HoverTool(tooltips=tooltips) tap = TapTool() #p = figure(tools=TOOLS, width=1100, height=700, x_range=x_rr, y_range=y_rr, title="Price Distribution") #p = figure(tools=TOOLS, width=1100, height=700, title="Price Distribution") #p = figure(tools=TOOLS, width=1100, height=700, x_range=ranges, title="Price Distribution", angle=pi/4) #p = figure(tools=TOOLS, width=1100, height=700, x_range=ranges, title="Price Distribution") p = figure(tools=TOOLS, width=580, height=1000, y_range=ranges, title="Price Distribution", x_axis_location="above", toolbar_location=None) p.yaxis.major_label_orientation = pi/4 #p.quad(left='xvals', right='rightvals', top='tops', bottom='bottoms', color='fills', source=self.dfsource) #p.rect(x='xcat', y='yvals', width='width', height='height', color='fills', source=self.source) p.rect(x='yvals', y='xcat', width='width', height='height', color='fills', source=self.source) p.add_tools(hover, tap) self.plot = p self.make_brand_plot() def make_brand_plot(self, min_idx=0, max_idx=MAX_IDX): TOOLS = "box_select,lasso_select" tooltips = "<span class='tooltip-text'>Name: @name</span>\n<br>" tooltips += "<span class='tooltip-text'>Brand: @brand</span>\n<br>" tooltips += "<span class='tooltip-text'>Price: @price</span>\n<br>" #hover = HoverTool(tooltips="@num_reviews") #hover = HoverTool(tooltips="@names") hover = HoverTool(tooltips=tooltips) #p = figure(tools=TOOLS, width=1100, height=700, x_range=x_rr, y_range=y_rr, title="Price Distribution") #p = figure(tools=TOOLS, width=1100, height=700, title="Price Distribution") #p = figure(tools=TOOLS, width=1100, height=700, x_range=ranges, title="Price Distribution", angle=pi/4) bdf = self.brand_df if len(bdf) > 0: title = "Brand: " + self.brand_df['brand'].values[0] else: title = "" brand_ranges = orig_order[min_idx:max_idx+1] p = figure(tools=TOOLS, width=400, height=400, x_range=brand_ranges, title=title, toolbar_location=None) p.xaxis.major_label_orientation = pi/4 #p.quad(left='xvals', right='rightvals', top='tops', bottom='bottoms', color='fills', source=self.dfsource) p.rect(x='xcat', y='brand_y', line_color='black', width='width', height='brand_height', color='fills', source=self.brand_source) p.add_tools(hover) self.brand_plot = p def set_children(self): self.children = [self.totalbox] self.totalbox.children = [self.plot, self.brandbox] self.brandbox.children = [self.brand_plot, self.selectr] #self.totalbox.children = [self.mainrow, self.bottomrow] #self.mainrow.children = [self.plot] #self.bottomrow.children = [self.hist_plot, self.selectr] #self.mainrow.children = [self.selectr] #self.bottomrow.children = [self.plot] def input_change(self, obj, attrname, old, new): self.make_source() self.make_better_plots() self.set_children() curdoc().add(self) def setup_events(self): super(ShoeApp, self).setup_events() if self.source: self.source.on_change('selected', self, 'selection_change') if self.selectr: self.selectr.on_change('value', self, 'brand_change') def selection_change(self, obj, attrname, old, new): #self.make_brand_plot #self.set_children() #curdoc().add(self) bdf = self.brand_df min_idx, max_idx = shoes_func.min_max_range(ranges, bdf['price']) self.configure_brand_source(min_idx, max_idx) self.make_brand_source() self.make_brand_plot(min_idx, max_idx) self.set_children() curdoc().add(self) def brand_change(self, obj, attrname, old, new): bdf = self.brand_df if self.selectr.value is None or self.selectr.value == 'Most Popular Brands': return self.update_selected_on_source(self.selectr.value) self.set_children() curdoc().add(self) def update_selected_on_source(self, brand): # {'2d': {'indices': []}, '1d': {'indices': []}, '0d': {'indices': [], 'flag': False}} brand_df = _shoedf[ _shoedf['brand'] == brand ] new_indices = {'2d': {'indices': []}, '1d': {'indices': []}, '0d': {'indices': [], 'flag': False}} for _id in brand_df.index: new_indices['1d']['indices'].append(_id) self.source.selected = new_indices @property def df(self): return _shoedf @property def brand_df(self): pandas_df = self.df selected = self.source.selected if selected['1d']['indices']: idxs = selected['1d']['indices'] sel_brand = pandas_df.iloc[idxs[0], :]['brand'] #pandas_df = pandas_df.iloc[idxs, :] #return _shoedf[_shoedf['brand'] =='manolo blahnik'] return _shoedf[_shoedf['brand'] == sel_brand] else: return pandas_df.iloc[0:0, :]
def update(selected=None): t1, t2 = ticker1.value, ticker2.value data = get_data(t1, t2) source.data = source.from_df(data[['t1', 't2', 't1_returns', 't2_returns']]) source_static.data = source.data update_stats(data, t1, t2) corr.title.text = '%s returns vs. %s returns' % (t1, t2) ts1.title.text, ts2.title.text = t1, t2 def update_stats(data, t1, t2): stats.text = str(data[[t1, t2, t1+'_returns', t2+'_returns']].describe()) ticker1.on_change('value', ticker1_change) ticker2.on_change('value', ticker2_change) def selection_change(attrname, old, new): t1, t2 = ticker1.value, ticker2.value data = get_data(t1, t2) selected = source.selected['1d']['indices'] if selected: data = data.iloc[selected, :] update_stats(data, t1, t2) source.on_change('selected', selection_change) # set up layout widgets = column(ticker1, ticker2, stats) main_row = row(corr, widgets)
PS3C1Voltage.line(x='x', y='voltages7', source=source) PS3C2Current.line(x='x', y='currents8', source=source) PS3C2Voltage.line(x='x', y='voltages8', source=source) PS3C3Current.line(x='x', y='currents9', source=source) PS3C3Voltage.line(x='x', y='voltages9', source=source) file_control.on_change('value', file_handler) apply_button.on_click(apply_settings) current_control.on_change('value', current_handler) voltage_control.on_change('value', voltage_handler) power_control.on_change('value', power_handler) ocp_control.on_change('value', ocp_handler) file_control.on_change('value', file_handler) directory_control.on_change('value', file_handler) comment_box.on_change('value', comment_handler) channel_dropdown.on_change('value', channel_handler) start_button.on_click(start_button_handler) connect_button.on_click(connect_button_handler) supply_dropdown.on_change('value', multiselect_handler) t0 = time.time() curdoc().add_root( row( column(supply_textbox, supply_dropdown, connect_button, current_control, voltage_control, power_control, ocp_control, channel_dropdown, apply_button, directory_control, file_control, start_button, comment_box), column(PS1C1Current, PS1C1Voltage, PS1C2Current, PS1C2Voltage, PS1C3Current, PS1C3Voltage), column(PS2C1Current, PS2C1Voltage, PS2C2Current, PS2C2Voltage, PS2C3Current, PS2C3Voltage), column(PS3C1Current, PS3C1Voltage, PS3C2Current, PS3C2Voltage,
def graph_tab(data): def f(data, year, month): recent = data[(data['year'] == year) & (data['month'] == month)] recent_by_day = recent.groupby('day') sales_by_year = recent_by_day['Sales'].agg(np.sum) sales = [sales for sales in sales_by_year] return sales recent = data[(data['year'] == 2017) & (data['month'] == 12)] group_by_day = recent.groupby('day') x = group_by_day['Sales'].agg(np.sum) sales = [sale for sale in x] source = ColumnDataSource(data={ 'days': [x for x in range(len(sales))], 'sales': sales }) p = figure(plot_width=800, plot_height=600, title="Day wise Total Sales for a given Year and Month", x_axis_label="Days of Month", y_axis_label="Total Sales") p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' p.line(x='days', y='sales', source=source, line_width=1.5) p.circle(x='days', y='sales', source=source) menu1 = Select(title="Year", value="2017", options=['2017', '2016', '2015', '2014']) menu2 = Select(title="Month", value="Dec", options=[ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]) def callback(attr, old, new): month_num = { 'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12 } year = int(menu1.value) month = month_num[menu2.value] source.data = { 'days': [x for x in range(1, 31)], 'sales': f(data, year, month) } menu1.on_change('value', callback) menu2.on_change('value', callback) controls = widgetbox(menu1, menu2) layout = row(controls, p) tab = Panel(child=layout, title='Total Sales') return tab #curdoc().add_root(layout)
def plot(): # FIGURES AND X-AXIS fig1 = Figure(title = 'Dive Profile', plot_width = WIDTH, plot_height = HEIGHT, tools = TOOLS) fig2 = Figure(title = 'Dive Controls', plot_width = WIDTH, plot_height = HEIGHT, tools = TOOLS, x_range=fig1.x_range) fig3 = Figure(title = 'Attitude', plot_width = WIDTH, plot_height = HEIGHT, tools = TOOLS, x_range=fig1.x_range) figs = gridplot([[fig1],[fig2],[fig3]]) # Formatting x-axis timeticks = DatetimeTickFormatter(formats=dict(seconds =["%b%d %H:%M:%S"], minutes =["%b%d %H:%M"], hourmin =["%b%d %H:%M"], hours =["%b%d %H:%M"], days =["%b%d %H:%M"], months=["%b%d %H:%M"], years =["%b%d %H:%M %Y"])) fig1.xaxis.formatter = timeticks fig2.xaxis.formatter = timeticks fig3.xaxis.formatter = timeticks # removing gridlines fig1.xgrid.grid_line_color = None fig1.ygrid.grid_line_color = None fig2.xgrid.grid_line_color = None fig2.ygrid.grid_line_color = None fig3.xgrid.grid_line_color = None fig3.ygrid.grid_line_color = None # INPUT WIDGETS collection_list = CONN[DB].collection_names(include_system_collections=False) gliders = sorted([platformID for platformID in collection_list if len(platformID)>2]) gliders = Select(title = 'PlatformID', value = gliders[0], options = gliders) prev_glider = Button(label = '<') next_glider = Button(label = '>') glider_controlbox = HBox(children = [gliders, prev_glider, next_glider], height=80) chunkations = Select(title = 'Chunkation', value = 'segment', options = ['segment', '24hr', '30days', '-ALL-']) chunk_indicator = TextInput(title = 'index', value = '0') prev_chunk = Button(label = '<') next_chunk = Button(label = '>') chunk_ID = PreText(height=80) chunk_controlbox = HBox(chunkations, HBox(chunk_indicator, width=25), prev_chunk, next_chunk, chunk_ID, height = 80) control_box = HBox(glider_controlbox, chunk_controlbox) # DATA VARS deadby_date = '' depth = ColumnDataSource(dict(x=[],y=[])) vert_vel = ColumnDataSource(dict(x=[],y=[])) mbpump = ColumnDataSource(dict(x=[],y=[])) battpos = ColumnDataSource(dict(x=[],y=[])) pitch = ColumnDataSource(dict(x=[],y=[])) mfin = ColumnDataSource(dict(x=[],y=[])) cfin = ColumnDataSource(dict(x=[],y=[])) mroll = ColumnDataSource(dict(x=[],y=[])) mheading = ColumnDataSource(dict(x=[],y=[])) cheading = ColumnDataSource(dict(x=[],y=[])) # AXIS setup colors = COLORS[:] fig1.y_range.flipped = True fig1.yaxis.axis_label = 'm_depth (m)' fig1.extra_y_ranges = {'vert_vel': Range1d(start=-50, end=50), 'dummy': Range1d(start=0, end=100)} fig1.add_layout(place = 'right', obj = LinearAxis(y_range_name = 'vert_vel', axis_label = 'vertical velocity (cm/s)')) fig1.add_layout(place = 'left', obj = LinearAxis(y_range_name = 'dummy', axis_label = ' ')) fig1.yaxis[1].visible = False fig1.yaxis[1].axis_line_alpha = 0 fig1.yaxis[1].major_label_text_alpha = 0 fig1.yaxis[1].major_tick_line_alpha = 0 fig1.yaxis[1].minor_tick_line_alpha = 0 fig2.yaxis.axis_label = 'pitch (deg)' fig2.y_range.start, fig2.y_range.end = -40,40 fig2.extra_y_ranges = {'battpos': Range1d(start=-1, end = 1), 'bpump': Range1d(start=-275, end=275)} fig2.add_layout(place = 'right', obj = LinearAxis(y_range_name = 'battpos', axis_label = 'battpos (in)')) fig2.add_layout(place = 'left', obj = LinearAxis(y_range_name = 'bpump', axis_label = 'bpump (cc)')) fig2.yaxis[1].visible = False # necessary for spacing. later gets set to true fig3.yaxis.axis_label = 'fin/roll (deg)' fig3.y_range.start, fig3.y_range.end = -30, 30 fig3.extra_y_ranges = {'heading': Range1d(start=0, end=360), #TODO dynamic avg centering 'dummy': Range1d(start=0, end=100)} fig3.add_layout(place = 'right', obj = LinearAxis(y_range_name = 'heading', axis_label = 'headings (deg)')) fig3.add_layout(place = 'left', obj = LinearAxis(y_range_name = 'dummy', axis_label = ' ')) fig3.yaxis[1].visible = False fig3.yaxis[1].axis_line_alpha = 0 fig3.yaxis[1].major_label_text_alpha = 0 fig3.yaxis[1].major_tick_line_alpha = 0 fig3.yaxis[1].minor_tick_line_alpha = 0 # PLOT OBJECTS fig1.line( 'x', 'y', source = depth, legend = 'm_depth', color = 'red') fig1.circle('x', 'y', source = depth, legend = 'm_depth', color = 'red') fig1.line( 'x', 'y', source = vert_vel, legend = 'vert_vel', color = 'green', y_range_name = 'vert_vel') fig1.circle('x', 'y', source = vert_vel, legend = 'vert_vel', color = 'green', y_range_name = 'vert_vel') fig1.renderers.append(Span(location = 0, dimension = 'width', y_range_name = 'vert_vel', line_color= 'green', line_dash='dashed', line_width=1)) fig2.line( 'x', 'y', source = pitch, legend = "m_pitch", color = 'indigo') fig2.circle('x', 'y', source = pitch, legend = "m_pitch", color = 'indigo') fig2.line( 'x', 'y', source = battpos, legend = 'm_battpos', color = 'magenta', y_range_name = 'battpos') fig2.circle('x', 'y', source = battpos, legend = 'm_battpos', color = 'magenta', y_range_name = 'battpos') fig2.line( 'x', 'y', source = mbpump, legend = "m_'bpump'", color = 'blue', y_range_name = 'bpump') fig2.circle('x', 'y', source = mbpump, legend = "m_'bpump'", color = 'blue', y_range_name = 'bpump') fig2.renderers.append(Span(location = 0, dimension = 'width', line_color= 'black', line_dash='dashed', line_width=1)) fig3.line( 'x', 'y', source = mfin, legend = 'm_fin', color = 'cyan') fig3.circle('x', 'y', source = mfin, legend = 'm_fin', color = 'cyan') fig3.line( 'x', 'y', source = cfin, legend = 'c_fin', color = 'orange') fig3.circle('x', 'y', source = cfin, legend = 'c_fin', color = 'orange') fig3.line( 'x', 'y', source = mroll, legend = 'm_roll', color = 'magenta') fig3.circle('x', 'y', source = mroll, legend = 'm_roll', color = 'magenta') fig3.line( 'x', 'y', source = mheading, legend = 'm_heading', color = 'blue', y_range_name = 'heading') fig3.circle('x', 'y', source = mheading, legend = 'm_heading', color = 'blue', y_range_name = 'heading') fig3.line( 'x', 'y', source = cheading, legend = 'c_heading', color = 'indigo', y_range_name = 'heading') fig3.circle('x', 'y', source = cheading, legend = 'c_heading', color = 'indigo', y_range_name = 'heading') fig3.renderers.append(Span(location = 0, dimension = 'width', y_range_name = 'default', line_color= 'black', line_dash='dashed', line_width=1)) # CALLBACK FUNCS def update_data(attrib,old,new): g = gliders.value chnk = chunkations.value chindex = abs(int(chunk_indicator.value)) depth.data = dict(x=[],y=[]) vert_vel.data = dict(x=[],y=[]) mbpump.data = dict(x=[],y=[]) battpos.data = dict(x=[],y=[]) pitch.data = dict(x=[],y=[]) mfin.data = dict(x=[],y=[]) cfin.data = dict(x=[],y=[]) mroll.data = dict(x=[],y=[]) mheading.data = dict(x=[],y=[]) cheading.data = dict(x=[],y=[]) depth.data,startend = load_sensor(g, 'm_depth', chnk, chindex) if chnk == 'segment': xbd = startend[2] chunk_ID.text = '{} {} \n{} ({}) \nSTART: {} \nEND: {}'.format(g, xbd['mission'], xbd['onboard_filename'], xbd['the8x3_filename'], e2ts(xbd['start']), e2ts(xbd['end'])) if len(set(depth.data['x']))<=1 and attrib == 'chunk': if old > new: next_chunk.clicks += 1 else: prev_chunk.clicks += 1 return elif len(set(depth.data['x']))<=1 and chunk_indicator.value == 0: chunk_indicator.value = 1 elif chnk in ['24hr', '30days']: chunk_ID.text = '{} \nSTART: {} \nEND: {}'.format(g, e2ts(startend[0]), e2ts(startend[1])) elif chnk == '-ALL-': chunk_ID.text = '{} \nSTART: {} \nEND: {}'.format(g,e2ts(depth.data['x'][0] /1000), e2ts(depth.data['x'][-1]/1000)) vert_vel.data = calc_vert_vel(depth.data) mbpump.data,_ = load_sensor(g, 'm_de_oil_vol', chnk, chindex) if len(mbpump.data['x']) > 1: #for yax in fig2.select('mbpump'): # yax.legend = 'm_de_oil_vol' pass else: mbpump.data,_ = load_sensor(g, 'm_ballast_pumped', chnk, chindex) #for yax in fig2.select('mbpump'): # yax.legend = 'm_ballast_pumped' battpos.data,_ = load_sensor(g, 'm_battpos', chnk, chindex) pitch.data,_ = load_sensor(g, 'm_pitch', chnk, chindex) pitch.data['y'] = [math.degrees(y) for y in pitch.data['y']] mfin.data,_ = load_sensor(g, 'm_fin', chnk, chindex) cfin.data,_ = load_sensor(g, 'c_fin', chnk, chindex) mroll.data,_ = load_sensor(g, 'm_roll', chnk, chindex) mheading.data,_ = load_sensor(g, 'm_heading', chnk, chindex) cheading.data,_ = load_sensor(g, 'c_heading', chnk, chindex) mfin.data['y'] = [math.degrees(y) for y in mfin.data['y']] cfin.data['y'] = [math.degrees(y) for y in cfin.data['y']] mheading.data['y'] = [math.degrees(y) for y in mheading.data['y']] cheading.data['y'] = [math.degrees(y) for y in cheading.data['y']] mroll.data['y'] = [math.degrees(y) for y in mroll.data['y']] fig1.yaxis[1].visible = True fig2.yaxis[1].visible = True fig3.yaxis[1].visible = True #GLIDER SELECTS def glider_buttons(increment): ops = gliders.options new_index = ops.index(gliders.value) + increment if new_index >= len(ops): new_index = 0 elif new_index < 0: new_index = len(ops)-1 gliders.value = ops[new_index] chunkation_update(None, None, None) #reset chunk indicator and clicks def next_glider_func(): glider_buttons(1) def prev_glider_func(): glider_buttons(-1) def update_glider(attrib,old,new): chunk_indicator.value = '0' #update_data(None,None,None) gliders.on_change('value', update_glider) next_glider.on_click(next_glider_func) prev_glider.on_click(prev_glider_func) #CHUNK SELECTS def chunkation_update(attrib,old,new): chunk_indicator.value = '0' prev_chunk.clicks = 0 next_chunk.clicks = 0 update_data(None,None,None) if new == '-ALL-': chunk_indicator.value = '-' def chunk_func(): chunkdiff = prev_chunk.clicks - next_chunk.clicks if chunkdiff < 0: prev_chunk.clicks = 0 next_chunk.clicks = 0 chunkdiff = 0 print (chunkdiff) chunk_indicator.value = str(chunkdiff) def chunk_indicator_update(attrib,old,new): try: if abs(int(old)-int(new))>1: #manual update, triggers new non-manual indicator update, ie else clause below prev_chunk.clicks = int(new) next_chunk.clicks = 0 else: update_data('chunk',int(old),int(new)) print("UPDATE", old, new) except Exception as e: print(type(e),e, old, new) chunkations.on_change('value', chunkation_update) chunk_indicator.on_change('value', chunk_indicator_update) next_chunk.on_click(chunk_func) prev_chunk.on_click(chunk_func) update_data(None,None,None) return vplot(control_box, figs)
print(slider.value) #create label function def update_labels(attr, old, new): labels.text = select.value # Create options for select widget options = [("average_grades", "Average Grades"), ("exam_grades", "Exam Grades"), ("student_names", "Student Names")] # Create select widget select = Select(title="Attribute", options=options) # Activate the select widget select.on_change("value", update_labels) # Create Slider slider = Slider(start=min(source_original.data["exam_grades"]) - 1, end=max(source_original.data["exam_grades"]) + 1, value=8, step=0.1, title="Exam Grade: ") # Activate slider slider.on_change("value", filter_grades) # Create layout lay_out = layout([[select], [slider]]) # Add layout to curdoc curdoc().add_root(f)
update(attrname=None, old=None, new=None) text_input = TextInput(value="Ivana") button = Button(label="Generate Text") dt_picker_ = DatePicker(min_date='2010-01-01', max_date='2018-03-28', value='2018-03-27') dummy_select = Select(value='select an option', options=['a', 'b']) output = Paragraph() button.on_click(updateBtn) dummy_select.on_change('value', update) dt_picker.on_change('value', update) lay_out = layout([[text_input, button, dt_picker], [output]]) #show(lay_out) #curdoc().add_root(lay_out) # curdoc().add_root( # column( # row(text_input), # row(dummy_select), # row(dt_picker), # row(button), # row(output) # )
class StockApp(VBox): extra_generated_classes = [["StockApp", "StockApp", "VBox"]] jsmodel = "VBox" # text statistics pretext = Instance(PreText) # plots plot = Instance(Plot) line_plot1 = Instance(Plot) line_plot2 = Instance(Plot) hist1 = Instance(Plot) hist2 = Instance(Plot) # data source source = Instance(ColumnDataSource) # layout boxes mainrow = Instance(HBox) histrow = Instance(HBox) statsbox = Instance(VBox) # inputs ticker1 = String(default="AAPL") ticker2 = String(default="GOOG") ticker1_select = Instance(Select) ticker2_select = Instance(Select) input_box = Instance(VBoxForm) def __init__(self, *args, **kwargs): super(StockApp, self).__init__(*args, **kwargs) self._dfs = {} @classmethod def create(cls): """ This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ # create layout widgets obj = cls() obj.mainrow = HBox() obj.histrow = HBox() obj.statsbox = VBox() obj.input_box = VBoxForm() # create input widgets obj.make_inputs() # outputs obj.pretext = PreText(text="", width=500) obj.make_source() obj.make_plots() obj.make_stats() # layout obj.set_children() return obj def make_inputs(self): self.ticker1_select = Select( name='ticker1', value='AAPL', options=['AAPL', 'GOOG', 'INTC', 'BRCM', 'YHOO'] ) self.ticker2_select = Select( name='ticker2', value='GOOG', options=['AAPL', 'GOOG', 'INTC', 'BRCM', 'YHOO'] ) @property def selected_df(self): pandas_df = self.df selected = self.source.selected if selected: pandas_df = pandas_df.iloc[selected, :] return pandas_df def make_source(self): self.source = ColumnDataSource(data=self.df) def line_plot(self, ticker, x_range=None): plot = circle( 'date', ticker, title=ticker, size=2, x_range=x_range, x_axis_type='datetime', source=self.source, title_text_font_size="10pt", plot_width=1000, plot_height=200, nonselection_alpha=0.02, tools="pan,wheel_zoom,select" ) return plot def hist_plot(self, ticker): global_hist, global_bins = np.histogram(self.df[ticker + "_returns"], bins=50) hist, bins = np.histogram(self.selected_df[ticker + "_returns"], bins=50) width = 0.7 * (bins[1] - bins[0]) center = (bins[:-1] + bins[1:]) / 2 start = global_bins.min() end = global_bins.max() top = hist.max() return rect( center, hist/2.0, width, hist, title="%s hist" % ticker, plot_width=500, plot_height=200, tools="", title_text_font_size="10pt", x_range=[start, end], y_range=[0, top], ) def make_plots(self): ticker1 = self.ticker1 ticker2 = self.ticker2 self.plot = circle( ticker1 + "_returns", ticker2 + "_returns", size=2, title="%s vs %s" %(ticker1, ticker2), source=self.source, plot_width=400, plot_height=400, tools="pan,wheel_zoom,select", title_text_font_size="10pt", nonselection_alpha=0.02, ) self.line_plot1 = self.line_plot(ticker1) self.line_plot2 = self.line_plot(ticker2, self.line_plot1.x_range) self.hist_plots() def hist_plots(self): ticker1 = self.ticker1 ticker2 = self.ticker2 self.hist1 = self.hist_plot(ticker1) self.hist2 = self.hist_plot(ticker2) def set_children(self): self.children = [self.mainrow, self.histrow, self.line_plot1, self.line_plot2] self.mainrow.children = [self.input_box, self.plot, self.statsbox] self.input_box.children = [self.ticker1_select, self.ticker2_select] self.histrow.children = [self.hist1, self.hist2] self.statsbox.children = [self.pretext] def input_change(self, obj, attrname, old, new): if obj == self.ticker2_select: self.ticker2 = new if obj == self.ticker1_select: self.ticker1 = new self.make_source() self.make_plots() self.set_children() curdoc().add(self) def setup_events(self): super(StockApp, self).setup_events() if self.source: self.source.on_change('selected', self, 'selection_change') if self.ticker1_select: self.ticker1_select.on_change('value', self, 'input_change') if self.ticker2_select: self.ticker2_select.on_change('value', self, 'input_change') def make_stats(self): stats = self.selected_df.describe() self.pretext.text = str(stats) def selection_change(self, obj, attrname, old, new): self.make_stats() self.hist_plots() self.set_children() curdoc().add(self) @property def df(self): return get_data(self.ticker1, self.ticker2)
def KPI_developer_adoption_tab(page_width,DAYS_TO_LOAD=90): class Thistab(KPI): def __init__(self, table,cols=[]): KPI.__init__(self, table,name='developer',cols=cols) self.table = table self.df = None self.checkboxgroup = {} self.period_to_date_cards = { 'year': self.card('',''), 'quarter': self.card('', ''), 'month': self.card('', ''), 'week': self.card('', '') } self.ptd_startdate = datetime(datetime.today().year,1,1,0,0,0) self.timestamp_col = 'block_timestamp' self.variable = self.menus['developer_adoption_DVs'][0] self.datepicker_pop_start = DatePicker( title="Period start", min_date=self.initial_date, max_date=dashboard_config['dates']['last_date'], value=dashboard_config['dates']['last_date']) # ------- DIVS setup begin self.page_width = page_width self.KPI_card_div = self.initialize_cards(width=self.page_width,height=1000) txt = """<hr/><div style="text-align:center;width:{}px;height:{}px; position:relative;background:black;margin-bottom:200px"> <h1 style="color:#fff;margin-bottom:300px">{}</h1> </div>""".format(self.page_width, 50, 'Welcome') self.notification_div = { 'top': Div(text=txt, width=self.page_width, height=20), 'bottom': Div(text=txt, width=self.page_width, height=10), } self.section_divider = '-----------------------------------' self.section_headers = { 'cards': self.section_header_div( text='Period to date:{}'.format(self.section_divider), width=int(self.page_width*.5), html_header='h2', margin_top=5,margin_bottom=-155), 'pop': self.section_header_div( text='Period over period:{}'.format(self.section_divider), width=int(self.page_width*.5), html_header='h2', margin_top=5, margin_bottom=-155), 'sig_ratio': self.section_header_div( text='Time series of ratio of DV to significant IVs'.format(self.section_divider), width=int(self.page_width*.5), html_header='h2', margin_top=5, margin_bottom=-155), } # ---------------------- DIVS ---------------------------- def section_header_div(self, text, html_header='h2', width=600, margin_top=150, margin_bottom=-150): text = """<div style="margin-top:{}px;margin-bottom:-{}px;"><{} style="color:#4221cc;">{}</{}></div>""" \ .format(margin_top, margin_bottom, html_header, text, html_header) return Div(text=text, width=width, height=15) def information_div(self, width=400, height=300): div_style = """ style='width:350px;margin-right:-800px; border:1px solid #ddd;border-radius:3px;background:#efefef50;' """ txt = """ <div {}> <h4 {}>How to interpret relationships </h4> <ul style='margin-top:-10px;'> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> <li> </li> </ul> </div> """.format(div_style, self.header_style) div = Div(text=txt, width=width, height=height) return div # -------------------- CARDS ----------------------------------------- def initialize_cards(self, width, height=250): try: txt = '' for idx,period in enumerate(['year', 'quarter', 'month', 'week']): design = random.choice(list(KPI_card_css.keys())) txt += self.card(title='', data='', card_design=design) text = """<div style="margin-top:100px;display:flex;flex-direction:column;"> {} </div>""".format(txt) div = Div(text=text, width=width, height=height) return div except Exception: logger.error('initialize cards', exc_info=True) # -------------------- GRAPHS ------------------------------------------- def graph_periods_to_date(self,df1,timestamp_filter_col,variable): try: dct = {} for idx,period in enumerate(['week','month','quarter','year']): all_txt = """<div style="width:{}px;display:flex;flex-direction:row;">"""\ .format(int(self.page_width*.6)) # go to next row df = self.period_to_date(df1, timestamp=dashboard_config['dates']['last_date'], timestamp_filter_col=timestamp_filter_col, period=period) # get unique instances df = df.compute() df = df.drop_duplicates(keep='first') count = len(df) gc.collect() denom = df[variable].sum() if denom != 0: payroll_to_date = self.payroll_to_date(period) cost_per_var = round(payroll_to_date/denom,2) tmp_var = self.variable.split('_') title = "{} to date".format(period) title += "</br>${} per {}".format(cost_per_var,tmp_var[-1]) else: title = "{} to date".format(period) design = random.choice(list(KPI_card_css.keys())) all_txt += self.card(title=title,data=count,card_design=design) # add the statistically significant point estimates all_txt += self.calc_sig_effect_card_data(df,interest_var=self.variable, period=period) all_txt += """</div>""" print(all_txt) dct[period] = all_txt del df self.update_significant_DV_cards(dct) except Exception: logger.error('graph periods to date',exc_info=True) def graph_period_over_period(self,period): try: periods = [period] start_date = self.pop_start_date end_date = self.pop_end_date if isinstance(start_date,date): start_date = datetime.combine(start_date,datetime.min.time()) if isinstance(end_date,date): end_date = datetime.combine(end_date,datetime.min.time()) today = datetime.combine(datetime.today().date(),datetime.min.time()) ''' - if the start day is today (there is no data for today), adjust start date ''' if start_date == today: logger.warning('START DATE of WEEK IS TODAY.!NO DATA DATA') start_date = start_date - timedelta(days=7) self.datepicker_pop_start.value = start_date cols = [self.variable,self.timestamp_col, 'day'] df = self.load_df(start_date=start_date,end_date=end_date,cols=cols,timestamp_col='block_timestamp') if abs(start_date - end_date).days > 7: if 'week' in periods: periods.remove('week') if abs(start_date - end_date).days > 31: if 'month' in periods: periods.remove('month') if abs(start_date - end_date).days > 90: if 'quarter' in periods: periods.remove('quarter') for idx,period in enumerate(periods): df_period = self.period_over_period(df, start_date = start_date, end_date=end_date, period=period, history_periods=self.pop_history_periods, timestamp_col='block_timestamp') groupby_cols = ['dayset', 'period'] if len(df_period) > 0: df_period = df_period.groupby(groupby_cols).agg({self.variable: 'sum'}) df_period = df_period.reset_index() df_period = df_period.compute() else: df_period = df_period.compute() df_period = df_period.rename(index=str, columns={'day': 'dayset'}) prestack_cols = list(df_period.columns) logger.warning('Line 179:%s', df_period.head(10)) df_period = self.split_period_into_columns(df_period, col_to_split='period', value_to_copy=self.variable) # short term fix: filter out the unnecessary first day added by a corrupt quarter functionality if period == 'quarter': min_day = df_period['dayset'].min() logger.warning('LINE 252: MINIUMUM DAY:%s', min_day) df_period = df_period[df_period['dayset'] > min_day] logger.warning('line 180 df_period columns:%s', df_period.head(50)) poststack_cols = list(df_period.columns) title = "{} over {}".format(period, period) plotcols = list(np.setdiff1d(poststack_cols, prestack_cols)) df_period, plotcols = self.pop_include_zeros(df_period=df_period, plotcols=plotcols, period=period) if idx == 0: p = df_period.hvplot.bar('dayset',plotcols,rot=45,title=title, stacked=False,width=int(self.page_width*.8),height=400,value_label='#') else: p += df_period.hvplot.bar('dayset',plotcols,rot=45,title=title, stacked=False,width=int(self.page_width*.8),height=400,value_label='#') return p except Exception: logger.error('period over period to date', exc_info=True) # -------------------------------- PLOT TRENDS FOR SIGNIFICANT RATIOS -------------------------- def graph_significant_ratios_ts(self,launch=-1): try: df = self.make_significant_ratios_df(self.df,resample_period=self.resample_period, interest_var=self.variable, timestamp_col='block_timestamp') # clean if self.variable in df.columns: df = df.drop(self.variable,axis=1) #df = df.compute() # plot return df.hvplot.line(width=int(self.page_width*.8),height=400) except Exception: logger.error('graph significant ratios',exc_info=True) def update_variable(attrname, old, new): thistab.notification_updater("Calculations underway. Please be patient") thistab.variable = variable_select.value thistab.graph_periods_to_date(thistab.df,'block_timestamp',thistab.variable) thistab.section_header_updater('cards',label='') thistab.section_header_updater('pop',label='') thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) stream_launch_sig_ratio.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_period_over_period(): thistab.notification_updater("Calculations underway. Please be patient") thistab.pop_history_periods = pop_number_select.value thistab.pop_start_date = thistab.datepicker_pop_start.value # trigger period over period thistab.pop_end_date = datepicker_pop_end.value thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_resample(attrname, old, new): thistab.notification_updater("Calculations underway. Please be patient") thistab.resample_period = resample_select.value thistab.trigger += 1 stream_launch_sig_ratio.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_history_periods(attrname, old, new): thistab.notification_updater("Calculations underway. Please be patient") thistab.pop_history_periods = pop_number_select.value thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) thistab.notification_updater("ready") try: cols = ['aion_fork','aion_watch','aion_release','aion_issue','aion_push','block_timestamp'] thistab = Thistab(table='account_ext_warehouse', cols=cols) # ------------------------------------- SETUP ---------------------------- # format dates first_date_range = thistab.initial_date last_date_range = datetime.now().date() last_date = dashboard_config['dates']['last_date'] first_date = datetime(last_date.year,1,1,0,0,0) thistab.df = thistab.load_df(first_date, last_date,cols,'block_timestamp') thistab.graph_periods_to_date(thistab.df,timestamp_filter_col='block_timestamp',variable=thistab.variable) thistab.section_header_updater('cards',label='') thistab.section_header_updater('pop',label='') # MANAGE STREAM # date comes out stream in milliseconds # --------------------------------CREATE WIDGETS --------------------------------- thistab.pop_end_date = last_date thistab.pop_start_date = thistab.first_date_in_period(thistab.pop_end_date, 'week') stream_launch = streams.Stream.define('Launch',launch=-1)() stream_launch_sig_ratio = streams.Stream.define('Launch_sigratio',launch=-1)() datepicker_pop_end = DatePicker(title="Period end", min_date=first_date_range, max_date=last_date_range, value=thistab.pop_end_date) pop_number_select = Select(title='Select # of comparative periods', value=str(thistab.pop_history_periods), options=thistab.menus['history_periods']) pop_button = Button(label="Select dates/periods, then click me!",width=15,button_type="success") variable_select = Select(title='Select variable', value=thistab.variable, options=thistab.menus['developer_adoption_DVs']) resample_select = Select(title='Select resample period', value=thistab.resample_period, options=thistab.menus['resample_period']) # --------------------------------- GRAPHS --------------------------- hv_sig_ratios = hv.DynamicMap(thistab.graph_significant_ratios_ts, streams=[stream_launch_sig_ratio]) sig_ratios= renderer.get_plot(hv_sig_ratios) hv_pop_week = hv.DynamicMap(thistab.pop_week,streams=[stream_launch]) pop_week = renderer.get_plot(hv_pop_week) hv_pop_month = hv.DynamicMap(thistab.pop_month,streams=[stream_launch]) pop_month = renderer.get_plot(hv_pop_month) hv_pop_quarter = hv.DynamicMap(thistab.pop_quarter, streams=[stream_launch]) pop_quarter = renderer.get_plot(hv_pop_quarter) # -------------------------------- CALLBACKS ------------------------ variable_select.on_change('value', update_variable) pop_button.on_click(update_period_over_period) # lags array resample_select.on_change('value', update_resample) pop_number_select.on_change('value',update_history_periods) # -----------------------------------LAYOUT ---------------------------- # put the controls in a single element controls_ptd = WidgetBox(variable_select, resample_select) controls_pop = WidgetBox(thistab.datepicker_pop_start, datepicker_pop_end, pop_number_select,pop_button) grid_data = [ [thistab.notification_div['top']], [Spacer(width=20, height=40)], [thistab.section_headers['sig_ratio']], [Spacer(width=20, height=25)], [sig_ratios.state, controls_ptd], [thistab.section_headers['cards']], [Spacer(width=20, height=2)], [thistab.KPI_card_div], [thistab.section_headers['pop']], [Spacer(width=20, height=25)], [pop_week.state,controls_pop], [pop_month.state], [pop_quarter.state], [thistab.notification_div['bottom']] ] grid = gridplot(grid_data) # Make a tab with the layout tab = Panel(child=grid, title='KPI: developer adoption') return tab except Exception: logger.error('rendering err:', exc_info=True) return tab_error_flag('KPI: developer adoption')
# Fast direct read from hdf5 def get_data(f, name): shape = f[name].shape # Empty array data = np.empty(shape, dtype=np.float64) # read_direct to empty arrays f[name].read_direct(data) return data def select_data(): data_val = data_select.value with h5py.File(join(dirname(__file__), 'demo_data.hdf5'), 'r') as f: return get_data(f, data_val) def update(): # hardcoded length of 100 x = list(range(1, 101)) y = select_data() source.data = dict(x=x, y=y) data_select.on_change('value', lambda attr, old, new: update()) inputs = widgetbox(data_select, width=300) update() curdoc().add_root(row(inputs, p, width=1100)) curdoc().title = "Simple HDF5"
convert_to_float(warm_t2.value)], [convert_to_float(warm_n1.value), convert_to_float(warm_n2.value)])) print(raster_info[ls_ret.value]['we_points']) raster_bands[ls_ret.value]['EF'] = src.data['ef'] raster_bands[ls_ret.value]['FR'] = src.data['fr'] raster_bands[ls_ret.value]['tstar'] = src.data['tstar'] pickle.dump(raster_bands, open(open_path + 'raster_bands.p', 'wb')) pickle.dump(raster_info, open(open_path + 'raster_info.p', 'wb')) #Layout inits = widgetbox(ls_ret, ndvio, ndvis, tir_min, tir_max, warm_t1, warm_n1, warm_t2, warm_n2, save_button) layout = row(inits, p1, p2) #Link callbacks to widgets ls_ret.on_change('value', update_date) for w in [ndvio, ndvis, tir_max, tir_min, warm_t1, warm_n1, warm_t2, warm_n2]: w.on_change('value', update_all) save_button.on_click(save_all) #Update document curdoc().add_root(layout) curdoc().title = 'Triangle Method'
def get_data(f, name): shape = f[name].shape # Empty array data = np.empty(shape, dtype=np.float64) # read_direct to empty arrays f[name].read_direct(data) return data def select_data(): data_val = data_select.value with h5py.File('demo_data.hdf5', 'r') as f: return get_data(f, data_val) def update_data(attrname, old, new): # hardcoded length of 100 x = list(range(1, 101)) y = select_data() source.data = dict(x=x, y=y) data_select.on_change('value', update_data) inputs = VBoxForm(data_select, width=300) update_data(None, None, None) curdoc().add_root(HBox(inputs, p, width=1100))
class DatabaseEditor: def __init__(self, roi_manager): column_width = 600 self.roi_manager = roi_manager # allows ROI Name manager updates after importing data self.source = ColumnDataSource(data=dict()) self.source_csv = ColumnDataSource(data=dict(text=[])) self.import_inbox_button = Button(label='Import all from inbox', button_type='success', width=200) self.import_inbox_button.on_click(self.import_inbox) self.import_inbox_force = CheckboxGroup( labels=['Force Update', 'Import Latest Only', 'Move Files'], active=[1, 2]) self.rebuild_db_button = Button(label='Rebuild database', button_type='warning', width=200) self.rebuild_db_button.on_click(self.rebuild_db_button_click) self.query_table = Select( value='Plans', options=['DVHs', 'Plans', 'Rxs', 'Beams', 'DICOM_Files'], width=200, title='Table:') self.query_columns = MultiSelect( title="Columns (Ctrl or Shift Click enabled):", width=250, options=[tuple(['', ''])], size=10) self.query_condition = TextInput(value='', title="Condition:", width=450) self.query_button = Button(label='Query', button_type='primary', width=100) self.query_table.on_change('value', self.update_query_columns_ticker) self.query_button.on_click(self.update_query_source) self.update_db_title = Div(text="<b>Update Database</b>", width=column_width) self.update_db_table = Select( value='DVHs', options=['DVHs', 'Plans', 'Rxs', 'Beams'], width=80, title='Table:') self.update_db_column = Select(value='', options=[''], width=175, title='Column') self.update_db_value = TextInput(value='', title="Value:", width=200) self.update_db_condition = TextInput(value='', title="Condition:", width=350) self.update_db_button = Button(label='Update DB', button_type='warning', width=100) self.update_db_table.on_change('value', self.update_update_db_columns_ticker) self.update_db_button.on_click(self.update_db) self.update_query_columns() self.update_update_db_column() self.reimport_title = Div(text="<b>Reimport from DICOM</b>", width=column_width) self.reimport_mrn_text = TextInput(value='', width=200, title='MRN:') self.reimport_study_date_select = Select(value='', options=[''], width=200, title='Sim Study Date:') self.reimport_uid_select = Select(value='', options=[''], width=425, title='Study Instance UID:') self.reimport_old_data_select = Select( value='Delete from DB', options=['Delete from DB', 'Keep in DB'], width=150, title='Current Data:') self.reimport_button = Button(label='Reimport', button_type='warning', width=100) self.reimport_mrn_text.on_change('value', self.reimport_mrn_ticker) self.reimport_study_date_select.on_change( 'value', self.reimport_study_date_ticker) self.reimport_button.on_click(self.reimport_button_click) self.query_data_table = DataTable(source=self.source, columns=[], width=column_width, editable=True, height=600) self.delete_from_db_title = Div( text="<b>Delete all data with mrn or study_instance_uid</b>", width=column_width) self.delete_from_db_column = Select( value='mrn', options=['mrn', 'study_instance_uid'], width=200, title='Patient Identifier:') self.delete_from_db_value = TextInput(value='', title="Value (required):", width=300) self.delete_from_db_button = Button(label='Delete', button_type='warning', width=100) self.delete_auth_text = TextInput( value='', title="Type 'delete' here to authorize:", width=300) self.delete_auth_text.on_change('value', self.delete_auth_text_ticker) self.delete_from_db_button.on_click(self.delete_from_db) self.change_mrn_uid_title = Div( text="<b>Change mrn or study_instance_uid in all tables</b>", width=column_width) self.change_mrn_uid_column = Select( value='mrn', options=['mrn', 'study_instance_uid'], width=200, title='Patient Identifier:') self.change_mrn_uid_old_value = TextInput(value='', title="Old:", width=300) self.change_mrn_uid_new_value = TextInput(value='', title="New:", width=300) self.change_mrn_uid_button = Button(label='Rename', button_type='warning', width=100) self.change_mrn_uid_button.on_click(self.change_mrn_uid) self.calculations_title = Div(text="<b>Post Import Calculations</b>", width=column_width) self.calculate_condition = TextInput(value='', title="Condition:", width=350) self.calculate_options = [ 'Default Post-Import', 'PTV Distances', 'PTV Overlap', 'ROI Centroid', 'ROI Spread', 'ROI Cross-Section', 'OAR-PTV Centroid Dist', 'Beam Complexities', 'Plan Complexities', 'All (except age)', 'Patient Ages' ] self.calculate_select = Select(value=self.calculate_options[0], options=self.calculate_options, title='Calculate:', width=150) self.calculate_missing_only = CheckboxGroup( labels=['Only Calculate Missing Values'], active=[0], width=280) self.calculate_exec_button = Button(label='Perform Calc', button_type='primary', width=150) self.calculate_exec_button.on_click(self.calculate_exec) self.download = Button(label="Download Table", button_type="default", width=150) self.download.callback = CustomJS(args=dict(source=self.source_csv), code=open( join(dirname(dirname(__file__)), 'download_new.js')).read()) self.layout = row( column( row(self.import_inbox_button, Spacer(width=20), self.rebuild_db_button, Spacer(width=50), self.import_inbox_force), self.calculations_title, row(self.calculate_select, Spacer(width=20), self.calculate_missing_only, self.calculate_exec_button), self.calculate_condition, Div(text="<hr>", width=column_width), self.update_db_title, row(self.update_db_table, self.update_db_column, self.update_db_value, Spacer(width=45), self.update_db_button), self.update_db_condition, Div(text="<hr>", width=column_width), self.reimport_title, row(self.reimport_mrn_text, Spacer(width=10), self.reimport_old_data_select, Spacer(width=140), self.reimport_button), row(self.reimport_study_date_select, self.reimport_uid_select), Div(text="<hr>", width=column_width), row(self.delete_from_db_title), row(self.delete_from_db_column, Spacer(width=300), self.delete_from_db_button), row(self.delete_from_db_value, self.delete_auth_text), Div(text="<hr>", width=column_width), row(self.change_mrn_uid_title), row(self.change_mrn_uid_column, Spacer(width=300), self.change_mrn_uid_button), row(self.change_mrn_uid_old_value, self.change_mrn_uid_new_value)), column(Div(text="<b>Query Database</b>", width=column_width), row(self.query_table, self.query_columns), self.query_condition, row(self.query_button, Spacer(width=25), self.download), self.query_data_table)) def update_query_columns_ticker(self, attr, old, new): self.update_query_columns() def update_query_columns(self): new_options = DVH_SQL().get_column_names( self.query_table.value.lower()) if self.query_table.value.lower() == 'dvhs': new_options.pop(new_options.index('dvh_string')) new_options.pop(new_options.index('roi_coord_string')) new_options.pop(new_options.index('dth_string')) options_tuples = [tuple([option, option]) for option in new_options] self.query_columns.options = options_tuples self.query_columns.value = [''] def update_update_db_columns_ticker(self, attr, old, new): self.update_update_db_column() def update_update_db_column(self): new_options = DVH_SQL().get_column_names( self.update_db_table.value.lower()) new_options.pop(new_options.index('import_time_stamp')) if self.update_db_table.value.lower() == 'dvhs': new_options.pop(new_options.index('dvh_string')) new_options.pop(new_options.index('roi_coord_string')) self.update_db_column.options = new_options self.update_db_column.value = new_options[0] def update_query_source(self): columns = [v for v in self.query_columns.value if v] for i, key in enumerate([ 'mrn', 'study_instance_uid' ]): # move/add mrn and study_instance_uid to the front if key in columns: columns.pop(columns.index(key)) columns.insert(i, key) table_columns = [TableColumn(field=c, title=c) for c in columns] query_cursor = DVH_SQL().query(self.query_table.value, ','.join(columns).strip(), self.query_condition.value, order_by='mrn') new_data = { c: [str(line[i]) for line in query_cursor] for i, c in enumerate(columns) } if new_data: self.source.data = new_data self.query_data_table.columns = table_columns self.query_data_table.width = [700, 150 * len(table_columns) ][len(table_columns) > 5] self.update_csv() def update_db(self): if self.update_db_condition.value and self.update_db_value.value: self.update_db_button.label = 'Updating...' self.update_db_button.button_type = 'danger' update_value = self.update_db_value.value if self.update_db_column.value in {'birth_date', 'sim_study_date'}: update_value = update_value + "::date" DVH_SQL().update(self.update_db_table.value, self.update_db_column.value, update_value, self.update_db_condition.value) self.update_query_source() self.update_db_button.label = 'Update' self.update_db_button.button_type = 'warning' self.roi_manager.update_uncategorized_variation_select() self.roi_manager.update_ignored_variations_select() def delete_from_db(self): if self.delete_from_db_value.value and self.delete_auth_text.value == 'delete': condition = self.delete_from_db_column.value + " = '" + self.delete_from_db_value.value + "'" DVH_SQL().delete_rows(condition) self.update_query_source() self.delete_from_db_value.value = '' self.delete_auth_text.value = '' self.roi_manager.update_uncategorized_variation_select() self.roi_manager.update_ignored_variations_select() def change_mrn_uid(self): self.change_mrn_uid_button.label = 'Updating...' self.change_mrn_uid_button.button_type = 'danger' old = self.change_mrn_uid_old_value.value new = self.change_mrn_uid_new_value.value if old and new and old != new: if self.change_mrn_uid_column.value == 'mrn': DVH_SQL().change_mrn(old, new) elif self.change_mrn_uid_column.value == 'study_instance_uid': DVH_SQL().change_uid(old, new) self.change_mrn_uid_old_value.value = '' self.change_mrn_uid_new_value.value = '' self.change_mrn_uid_button.label = 'Rename' self.change_mrn_uid_button.button_type = 'warning' self.update_query_source() def delete_auth_text_ticker(self, attr, old, new): self.delete_from_db_button.button_type = ['warning', 'danger'][new == 'delete'] def import_inbox(self): if self.import_inbox_button.label in {'Cancel'}: self.rebuild_db_button.label = 'Rebuild database' self.rebuild_db_button.button_type = 'warning' else: self.import_inbox_button.button_type = 'warning' self.import_inbox_button.label = 'Importing...' force_update = 0 in self.import_inbox_force.active move_files = 2 in self.import_inbox_force.active import_latest_only = 1 in self.import_inbox_force.active dicom_to_sql(force_update=force_update, import_latest_only=import_latest_only, move_files=move_files) self.roi_manager.update_uncategorized_variation_select() self.import_inbox_button.button_type = 'success' self.import_inbox_button.label = 'Import all from inbox' def rebuild_db_button_click(self): if self.rebuild_db_button.button_type in {'warning'}: self.rebuild_db_button.label = 'Are you sure?' self.rebuild_db_button.button_type = 'danger' self.import_inbox_button.button_type = 'success' self.import_inbox_button.label = 'Cancel' else: directories = load_directories() self.rebuild_db_button.label = 'Rebuilding...' self.rebuild_db_button.button_type = 'danger' self.import_inbox_button.button_type = 'success' self.import_inbox_button.label = 'Import all from inbox' rebuild_database(directories['imported']) self.rebuild_db_button.label = 'Rebuild database' self.rebuild_db_button.button_type = 'warning' def update_all_min_distances_in_db(self, *condition): if condition and condition[0]: condition = " AND (" + condition[0] + ")" else: condition = '' condition = "(LOWER(roi_type) IN ('organ', 'ctv', 'gtv') AND (" \ "LOWER(roi_name) NOT IN ('external', 'skin') OR " \ "LOWER(physician_roi) NOT IN ('uncategorized', 'ignored', 'external', 'skin')))" + condition if 0 in self.calculate_missing_only.active: if condition: condition = "(%s) AND dist_to_ptv_min is NULL" % condition else: condition = "dist_to_ptv_min is NULL" rois = DVH_SQL().query('dvhs', 'study_instance_uid, roi_name, physician_roi', condition) total_rois = float(len(rois)) for i, roi in enumerate(rois): self.calculate_exec_button.label = str( int((float(i) / total_rois) * 100)) + '%' if roi[1].lower() not in {'external', 'skin'} and \ roi[2].lower() not in {'uncategorized', 'ignored', 'external', 'skin'}: print('updating dist to ptv:', roi[1], sep=' ') db_update.min_distances(roi[0], roi[1]) else: print('skipping dist to ptv:', roi[1], sep=' ') def update_all(self, variable, *condition): variable_function_map = { 'ptv_overlap': db_update.treatment_volume_overlap, 'centroid': db_update.centroid, 'spread': db_update.spread, 'cross_section': db_update.cross_section, 'ptv_centroids': db_update.dist_to_ptv_centroids } null_variable = variable if variable == 'ptv_centroids': null_variable = 'dist_to_ptv_centroids' elif variable == 'spread': null_variable = 'spread_x' elif variable == 'cross_section': null_variable = 'cross_section_max' elif variable == 'plan_complexity': null_variable = 'complexity' final_condition = { True: ["(%s is NULL)" % null_variable], False: [] }[0 in self.calculate_missing_only.active] if condition and condition[0]: final_condition.append('(%s)' % condition[0]) final_condition = ' AND '.join(final_condition) rois = DVH_SQL().query('dvhs', 'study_instance_uid, roi_name, physician_roi', final_condition) total_rois = float(len(rois)) for i, roi in enumerate(rois): self.calculate_exec_button.label = str( int((float(i) / total_rois) * 100)) + '%' print('updating %s:' % variable, roi[1], sep=' ') variable_function_map[variable](roi[0], roi[1]) def update_all_tv_overlaps_in_db(self, condition): self.update_all('ptv_overlap', condition) def update_all_centroids_in_db(self, condition): self.update_all('centroid', condition) def update_all_spreads_in_db(self, condition): self.update_all('spread', condition) def update_all_cross_sections_in_db(self, condition): self.update_all('cross_section', condition) def update_all_dist_to_ptv_centoids_in_db(self, condition): self.update_all('ptv_centroids', condition) def update_all_plan_complexities_in_db(self, condition): final_condition = { True: ["(complexity is NULL)"], False: [] }[0 in self.calculate_missing_only.active] if condition and condition[0]: final_condition.append('(%s)' % condition[0]) final_condition = ' AND '.join(final_condition) db_update.plan_complexities(final_condition) def update_all_beam_complexities_in_db(self, condition): final_condition = { True: ["(complexity_min is NULL)"], False: [] }[0 in self.calculate_missing_only.active] if condition and condition[0]: final_condition.append('(%s)' % condition[0]) final_condition = ' AND '.join(final_condition) db_update.beam_complexities(final_condition) def update_all_except_age_in_db(self, *condition): for f in self.calculate_select.options: if f not in {'Patient Ages', 'Default Post-Import'}: self.calculate_select.value = f self.calculate_exec() def update_default_post_import(self, *condition): for f in [ 'PTV Distances', 'PTV Overlap', 'OAR-PTV Centroid Dist', 'Plan Complexities' ]: self.calculate_select.value = f self.calculate_exec() self.calculate_select.value = 'Default Post-Import' # Calculates volumes using Shapely, not dicompyler # This function is not in the GUI @staticmethod def recalculate_roi_volumes(*condition): rois = DVH_SQL().query('dvhs', 'study_instance_uid, roi_name, physician_roi', condition[0]) counter = 0. total_rois = float(len(rois)) for roi in rois: counter += 1. print('updating volume:', roi[1], int(100. * counter / total_rois), sep=' ') db_update.volumes(roi[0], roi[1]) # Calculates surface area using Shapely # This function is not in the GUI @staticmethod def recalculate_surface_areas(*condition): rois = DVH_SQL().query('dvhs', 'study_instance_uid, roi_name, physician_roi', condition[0]) roi_count = float(len(rois)) for i, roi in enumerate(rois): print('updating surface area:', roi[1], int(100. * float(i) / roi_count), sep=' ') db_update.surface_area(roi[0], roi[1]) def reimport_mrn_ticker(self, attr, old, new): new_options = DVH_SQL().get_unique_values('Plans', 'sim_study_date', "mrn = '%s'" % new) if not new_options: new_options = ['MRN not found'] self.reimport_study_date_select.options = new_options self.reimport_study_date_select.value = new_options[0] def reimport_study_date_ticker(self, attr, old, new): if new != 'MRN not found': if new == 'None': new_options = DVH_SQL().get_unique_values( 'Plans', 'study_instance_uid', "mrn = '%s'" % self.reimport_mrn_text.value) else: new_options = DVH_SQL().get_unique_values( 'Plans', 'study_instance_uid', "mrn = '%s' and sim_study_date = '%s'" % (self.reimport_mrn_text.value, new)) else: new_options = ['Study Date not found'] self.reimport_uid_select.options = new_options self.reimport_uid_select.value = new_options[0] def reimport_button_click(self): dicom_directory = DVH_SQL().query( 'DICOM_Files', "folder_path", "study_instance_uid = '%s'" % self.reimport_uid_select.value)[0][0] if os.path.isdir(dicom_directory): if not os.listdir(dicom_directory): print("WARNING: %s is empty." % dicom_directory) print("Aborting DICOM reimport.") else: self.reimport_button.label = "Updating..." self.reimport_button.button_type = 'danger' if self.reimport_old_data_select.value == "Delete from DB": DVH_SQL().delete_rows("study_instance_uid = '%s'" % self.reimport_uid_select.value, ignore_table=['DICOM_Files']) dicom_to_sql(start_path=dicom_directory, force_update=True, move_files=False, update_dicom_catalogue_table=False) self.reimport_button.label = "Reimport" self.reimport_button.button_type = 'warning' self.roi_manager.update_uncategorized_variation_select() self.roi_manager.update_ignored_variations_select() else: print("WARNING: %s does not exist" % dicom_directory) print("Aborting DICOM reimport.") def calculate_exec(self): calc_map = { 'PTV Distances': self.update_all_min_distances_in_db, 'PTV Overlap': self.update_all_tv_overlaps_in_db, 'Patient Ages': recalculate_ages, 'ROI Centroid': self.update_all_centroids_in_db, 'ROI Spread': self.update_all_spreads_in_db, 'ROI Cross-Section': self.update_all_cross_sections_in_db, 'OAR-PTV Centroid Dist': self.update_all_dist_to_ptv_centoids_in_db, 'Beam Complexities': self.update_all_beam_complexities_in_db, 'Plan Complexities': self.update_all_plan_complexities_in_db, 'All (except age)': self.update_all_except_age_in_db, 'Default Post-Import': self.update_default_post_import } start_time = datetime.now() print(str(start_time), 'Beginning %s calculations' % self.calculate_select.value, sep=' ') self.calculate_exec_button.label = 'Calculating...' self.calculate_exec_button.button_type = 'warning' calc_map[self.calculate_select.value](self.calculate_condition.value) self.update_query_source() self.calculate_exec_button.label = 'Perform Calc' self.calculate_exec_button.button_type = 'primary' end_time = datetime.now() print(str(end_time), 'Calculations complete', sep=' ') print_run_time(start_time, end_time, "Calculations for %s" % self.calculate_select.value) def update_csv(self): src_data = [self.source.data] src_names = ['Queried Data'] columns = list(src_data[0]) columns.sort() for i, key in enumerate([ 'mrn', 'study_instance_uid' ]): # move/add mrn and study_instance_uid to the front if key in columns: columns.pop(columns.index(key)) columns.insert(i, key) csv_text = get_csv(src_data, src_names, columns) self.source_csv.data = {'text': [csv_text]}
df=pd.DataFrame({'x':x,'y':y,'label':label}) source = ColumnDataSource(data=dict(x=df.x, y=df.y,label=df.label)) plot_figure = figure(title='Select',plot_height=450, plot_width=600, tools="save,reset", toolbar_location="below") plot_figure.scatter('x', 'y', source=source, size=10,color='label') select = Select(title="Filter plot by color:", value="All", options=["All", "Red", "Orange"]) def select_click(attr,old,new): active_select=select.value ##Getting radio button value # filter the dataframe with value in select if active_select!='All': selected_df=df[df['label']==active_select] else: selected_df=df.copy() source.data=dict(x=selected_df.x, y=selected_df.y,label=selected_df.label) select.on_change('value',select_click) layout=row(select, plot_figure) curdoc().add_root(layout) curdoc().title = "Select Bokeh Server"
minutes = ["{:02d}".format(m) for m in range(60)] # default values config = EmonitorConfig(INSTRUM_FILE) instrum = config.instruments()[0] timezone = config.get(instrum, 'plot_timezone', fallback='UTC') logger.debug("timezone: " + timezone) today = datetime.datetime.now(tz=pytz.timezone(timezone)).date() # controls ## instrument instrum_select = Select(width=300, title='table', value=instrum, options=sorted(config.instruments())) instrum_select.on_change('value', refresh_plot) ## start time delta start_date = DatePicker(title='start', width=140, min_date=datetime.date(2020, 1, 1), max_date=today, value=today - datetime.timedelta(days=7)) start_hour = select = Select(title='hour', value="0", options=hours, width=70) start_minute = select = Select(title='min', value="0", options=minutes, width=70) start_date.on_change('value', refresh_plot) start_hour.on_change('value', refresh_plot) start_minute.on_change('value', refresh_plot)
y=state_data["complaint_count"] ) zip_data = build_zip_data( where_inner = where_inner, where_outer = where_outer ) zip_source.data = dict( x=zip_data["median_income"], y=zip_data["complaint_count"] ) table_source.data = build_data_table(where_inner) state_widget.on_change('value', update) product_widget.on_change('value', update) issue_widget.on_change('value', update) min_complaints_widget.on_change('value', update) ### Step 3: Build the charts # Build state bar chart state_bar_chart = Bar(build_state_data(), label="state", values='complaint_count', toolbar_location=None, title="Complaints by State", width=1300, height=200, ylabel="", xlabel="", color="#2cb34a") # Build zip code scatter plot zip_data = build_zip_data() zip_source.data = dict(x = zip_data["median_income"],
selected = selected[selected[col] < 700] selected = selected[col] return selected def update(attr, old, new): p, q = create_figure() layout.children[1] = p layout.children[2] = q #columns =['song_hotttnesss','year','duration','loudness','tempo','artist_hotttnesss','artist_familiarity'] x = Select(title='X-Axis', value='gid', options=columns) x.on_change('value', update) y = Select(title='Y-Axis', value='song_hotttnesss', options=columns) y.on_change('value', update) var_slider = Slider(start=100, end=2000, value=1000, step=100, title="The # most hottt songs") var_slider.on_change('value', update) #checkbox_year = CheckboxGroup(labels=["Show songs with missing year"], active=[]) #checkbox_year.on_change('active', update) year_slider = RangeSlider(start=1940,