def _get_formatter(self, ctype: ColummDataType): if ctype == ColummDataType.FLOAT: return NumberFormatter(format=self._scheme.number_format) elif ctype == ColummDataType.INT: return NumberFormatter() elif ctype == ColummDataType.DATETIME: return DateFormatter(format="%c") elif ctype == ColummDataType.STRING: return StringFormatter() elif ctype == ColummDataType.PERCENTAGE: return NumberFormatter(format="0.000 %") else: raise Exception(f"Unsupported ColumnDataType: '{ctype}'")
def __create_transactions_table(self, source): """Creates Transactions DataTable with DataSource source passed as it's ColumnData Source. DataTable defines 4 fields that need to be passed in the source ColumnDataSource .data attribute: - .date - .product - .price - .shop Those attributes correspond to column names in .original_df and it's derivatives. Created DataTable will show details of those 4 columns for every transaction necessary. Additionally, .date field will be formatted to %d-%m-%Y format (31-01-2019) and .price field will be formatted into 0,0.00 format (1,897.34). DataTable has it's index (counter) column removed for clarity. Returns created DataTable. """ columns = [ TableColumn(field=self.date, title="Date", formatter=DateFormatter(format="%d-%m-%Y")), TableColumn(field=self.product, title="Product"), TableColumn(field=self.price, title="Price", formatter=NumberFormatter(format="0,0.00")), TableColumn(field=self.shop, title="Shop") ] dt = DataTable(source=source, columns=columns, header_row=True, index_position=None) return dt
def update_data_table(active_radio_button, chosen_algorithm): if active_radio_button == 0: # summary source_datatable.data = pd.DataFrame.from_dict(summary_dict, orient='index') elif active_radio_button == 1: # statistics source_datatable.data = others_combined_dict[chosen_algorithm] elif active_radio_button == 2: # demand source_datatable.data = demands_prices_fw_dict[k0_demand][ chosen_algorithm] elif active_radio_button == 3: # prices source_datatable.data = demands_prices_fw_dict[k0_prices][ chosen_algorithm] columns_keys = source_datatable.data.keys() if active_radio_button == 0: table_columns = [ TableColumn(field=str(i), title=str(i).replace("_", " ").capitalize()) for i in columns_keys ] else: table_columns = [ TableColumn(field=str(i), title=str(i).replace("_", " ").capitalize(), formatter=NumberFormatter(format="0,0.00", text_align="right")) for i in columns_keys ] data_table.columns = table_columns data_table.update()
def add_rank_table(self): columns = [ TableColumn(field="tool", title="Tool"), TableColumn(field="score", title="Weighted Score", formatter=NumberFormatter(format="0.00")), TableColumn(field="rank", title="Rank") ] self.data_table = DataTable(columns=columns, source=self.source, reorderable=True) buttons = zip( [self.ranking[k][0] for k in self.chosen_criteria], [self.ranking[k][1] for k in self.chosen_criteria], [self.weight_sliders[k] for k in self.weight_sliders.keys()]) self.app_layout.children.pop(1) b_layout = [[t[0], t[1], t[2]] for t in buttons] b_layout.append([self.rank_submit, self.b]) b_layout.append(widgetbox(self.data_table)) b_layout.append([self.clear_button]) b_layout.insert(0, [Spacer(width=300), self.swing_table]) self.app_layout.children.append(layout(b_layout))
def fit_table(dist_names): """Tabela com os valores dos teste de aderencia para cada distribuição. Args: dist_names (list[str]): nomes das distribuição. """ source = ColumnDataSource( dict( dist_names=dist_names, chi=[0] * len(dist_names), ks=[0] * len(dist_names), wms=[0] * len(dist_names), )) formatter = NumberFormatter(format="0.000", text_align="center") return DataTable( source=source, columns=[ TableColumn(field="dist_names", title="Distribution"), TableColumn(field="chi", title="Chi", formatter=formatter), TableColumn(field="ks", title="KS", formatter=formatter), TableColumn(field="wms", title="WMS", formatter=formatter), ], width=300, index_position=None, fit_columns=True, )
def get_formatter(data): if data.dtype.name == 'datetime64[ns]': return DateFormatter(format='%Y-%m-%d %H:%M:%S') if data.dtype.name in ['float64', 'int64']: return NumberFormatter(format='0.0[000]') if data.dtype.name == 'bool': return BooleanFormatter() return StringFormatter()
def create_age_gender_stats_subtab(): source_df, source_CDS = get_line_list_analysis() columns = [ TableColumn(field='age_group', title='Age Group'), TableColumn(field='gender', title='Gender'), TableColumn(field='proportion', title='Fraction of Cases', formatter=NumberFormatter(format='0.00%')), TableColumn(field='death_rate', title='Death Rate', formatter=NumberFormatter(format='0.00%')) ] data_table = DataTable(columns=columns, source=source_CDS, sizing_mode='stretch_height') child = row(column([data_table])) return Panel(child=child, title='Infection Statistics by Age & Gender')
def cols_tron(self) -> None: return [ TableColumn(field="lig_rg", title="lig_rg", width=55), TableColumn(field="long_km", title="long_km", width=40, formatter=NumberFormatter(format="0.0")), TableColumn(field="pkd", title="pkd", width=60), TableColumn(field="pkf", title="pkf", width=60), TableColumn(field="lib_ligne", title="ligne", width=200), TableColumn(field="exploitation", title="exploitation", width=100), ]
def create(self): data = dict(coeff=[], values=[]) self.cdsource = ColumnDataSource(data) columns = [ TableColumn(field="coeff", title="Coeff"), TableColumn(field="values", title="Values", formatter=NumberFormatter(format='0.000a')) ] data_table = DataTable(source=self.cdsource, columns=columns, width=400, height=280) self.layout = layout([[data_table]])
def function_geosource(attr, old, new): try: selected_index = geosource.selected.indices[0] subdist = cg.iloc[selected_index]['area_numbe'] community = cg.loc[cg['area_numbe'] == subdist]['community'].values[0] view1 = CDSView( source=source, filters=[GroupFilter(column_name='community_area', group=subdist)]) columns = [ TableColumn(field='primary_type', title='<b>Crime_Description<b>'), TableColumn(field='case_number', title='<b>#Cases<b>', formatter=NumberFormatter(format='0,0')) ] data_table = DataTable(source=source, view=view1, columns=columns, width=280, height=500, editable=False, index_position=None) p2 = figure( y_range=df2.loc[df2['community_area'] == subdist]['primary_type'].unique()[::-1], x_axis_location="above", title="Offence count by neighbourhood: {}".format(community), plot_height=800, plot_width=1000) p2.hbar(y='primary_type', right='case_number', source=source, view=view1, height=0.5) #p2.xaxis.major_label_orientation = 1.2 p2.toolbar.active_drag = None p2.x_range.start = 0 style(p2) p2.outline_line_width = 0 # Replace the updated datatable in the layout layout.children[1] = data_table layout.children[2] = p2 except IndexError: pass
def create_symptom_stats_subtab(): source_df, source_CDS = get_symptom_rates() source_CDS.data['cleaned_symptom'] = [ symptom[12:].replace('_', ' ').title() for symptom in source_CDS.data['symptom'] ] columns = [ TableColumn(field='cleaned_symptom', title='Symptom'), TableColumn(field='rate', title='Fraction of Cases', formatter=NumberFormatter(format='0.00%')), ] data_table = DataTable(columns=columns, source=source_CDS, sizing_mode='stretch_height') child = row(column([data_table])) return Panel(child=child, title='Symptoms Experienced')
def download_tab(data, ticker): data_df = ColumnDataSource(data) datefmt = DateFormatter(format="dd-M-yyyy") pfmt = NumberFormatter(format="0.00") # Columns of table table_columns = [TableColumn(field='Date', title='Trade Date', formatter=datefmt), TableColumn(field='Open', title='Open', formatter=pfmt), TableColumn(field='High', title='High', formatter=pfmt), TableColumn(field='Low', title='Low', formatter=pfmt), TableColumn(field='Close', title='Close', formatter=pfmt), TableColumn(field='Change %', title='Change (%)')] stocks_data = DataTable(source=data_df, columns=table_columns, width=1000) pg_title = Paragraph(text = '[ '+ticker+' ] HISTORICAL DATA') about_ticker = Paragraph(text="""Safaricom Plc, formerly Safaricom Limited, is a telecommunications company. The Company provides integrated telecommunication services, including mobile and fixed voice, short messaging service (SMS), data, Internet and M-PESA, a service to send and receive money or pay for goods and services through a mobile phone. It also provides financial services and enterprise solutions to businesses and the public sector. The Company's voice services include national and international roaming services. It offers mobile handsets, mobile broadband modems, routers, tablets and notebooks. Its converged business solutions include fixed voice service for corporate and Small and Medium-sized Enterprises (SMEs), mobile solutions and fixed data for homes and businesses using fixed lease lines, and Internet solutions for enterprises and hosted services, such as cloud hosting, domains and security services. The Company offers bill payment, bulk payments and dividend payments..""", width=200, height=100) disclaimer = Paragraph(text="""Disclaimer: All investments and trading in the stock market involve risk. Any decisions to place trades in the financial markets, including trading in stock or options or other financial instruments is a personal decision that should only be made after thorough research, including a personal risk and financial assessment and the engagement of professional assistance to the extent you believe necessary. The trading strategies or related information mentioned in this article is for informational purposes only.""") layout = column(pg_title, stocks_data, about_ticker, disclaimer) tab = Panel(child = layout, title = 'Historical Data') return tab
slider = RangeSlider(title="Max Salary", start=10000, end=110000, value=(10000, 50000), step=1000, format="0,0") slider.on_change('value', lambda attr, old, new: update()) button = Button(label="Download", button_type="success") button.js_on_click( CustomJS(args=dict(source=source), code=open(join(dirname(__file__), "download.js")).read())) columns = [ TableColumn(field="name", title="Employee Name"), TableColumn(field="salary", title="Income", formatter=NumberFormatter(format="$0,0.00")), TableColumn(field="years_experience", title="Experience (years)") ] data_table = DataTable(source=source, columns=columns, width=800) controls = column(slider, button) curdoc().add_root(row(controls, data_table)) curdoc().title = "Export CSV" update()
def TabParcialesKilometricos(df): """ PREPARACION DE DATOS """ # Calculo de los valores agregados AVG_Altitud, MAX_Altitud, MIN_Altitud, \ AVG_Velocidad, MAX_Velocidad, MIN_Velocidad, \ AVG_Ritmo, MAX_Ritmo, MIN_Ritmo, \ AVG_FrecuenciaCardiaca, MAX_FrecuenciaCardiaca, MIN_FrecuenciaCardiaca, \ AVG_Cadencia, MAX_Cadencia, MIN_Cadencia, \ AVG_Temperatura, MAX_Temperatura, MIN_Temperatura, \ AVG_LongitudZancada, MAX_LongitudZancada, MIN_LongitudZancada, \ AVG_Pendiente, MAX_Pendiente , MIN_Pendiente = CalculosVectoresAgregados(df) # Calculo de desniveles finales DesnivelPositivo = df['DesnivelPositivoAcumulado'].max() DesnivelNegativo = df['DesnivelNegativoAcumulado'].max() DesnivelAcumulado = DesnivelPositivo + DesnivelNegativo DesnivelPorKilometro = (DesnivelAcumulado / df['Distancia'].max()) * 1000 # Factor de achatamiento de la altitud if DesnivelPorKilometro > 40: OffsetSuperiorAltitud = 0.1 OffsetInferiorAltitud = 0.03 else: OffsetSuperiorAltitud = 2.5 OffsetInferiorAltitud = 0.5 dfTramosKm = TablaParcialesKilometricos(df) dfTramosKm['Ritmo_STR'] = dfTramosKm.Ritmo.apply( lambda x: FormateoTiempos(x, 'R')) # Seleccion de un subconjunto de datos para visualizar dfBokehParcialesKM = df[[ 'Bloque', 'Distancia', 'Altitud', 'FrecuenciaCardiaca', 'Cadencia' ]].copy() dfBokehParcialesKM['AltitudEscalada'] = Reescalado( dfBokehParcialesKM['Altitud'], [ MIN_Altitud[0] - (MAX_Altitud[0] - MIN_Altitud[0]) * OffsetInferiorAltitud, MAX_Altitud[0] + (MAX_Altitud[0] - MIN_Altitud[0]) * OffsetSuperiorAltitud ], [0, dfTramosKm.Velocidad.max()]) dfBokehParcialesKM['FrecuenciaCardiacaEscalada'] = Reescalado( dfBokehParcialesKM['FrecuenciaCardiaca'], [MIN_FrecuenciaCardiaca[0], MAX_FrecuenciaCardiaca[0]], [0, dfTramosKm.Velocidad.max()]) dfBokehParcialesKM['CadenciaEscalada'] = Reescalado( dfBokehParcialesKM['Cadencia'], [MIN_Cadencia[0], MAX_Cadencia[0]], [0, dfTramosKm.Velocidad.max()]) # Reducion de la frecuencia de muestreo dfBokehParcialesKM_Agg = dfBokehParcialesKM.groupby('Bloque').resample( '10S').agg({ 'Distancia': np.max, 'Cadencia': np.mean }) dfBokehParcialesKM_Agg['Cadencia'] = dfBokehParcialesKM_Agg[ 'Cadencia'].round() dfBokehParcialesKM_Agg['CadenciaEscalada'] = Reescalado( dfBokehParcialesKM_Agg['Cadencia'], [MIN_Cadencia[0], MAX_Cadencia[0]], [0, dfTramosKm.Velocidad.max()]) # Creacion de los ColumnDataSource de origen de Bokeh OrigenParcialesKM = ColumnDataSource(dfBokehParcialesKM) OrigenParcialesKM_Agg = ColumnDataSource(dfBokehParcialesKM_Agg) OrigenTramosKm = ColumnDataSource(dfTramosKm) # Asignacion de tamaño segun el total de puntos if df['Distancia'].max() < 5: SizeCircle = 10 elif df['Distancia'].max() < 10: SizeCircle = 8 else: SizeCircle = 5 # Definicion de la paleta de colores por cadencia MapaColorCadencia = LinearColorMapper(palette=paleta_cadencia, low=110, high=190) """ TRAMOS KILOMETRICOS | STRAVA """ PLT_TramosKm = figure(plot_width=900, plot_height=500, x_range=(0, df['Distancia'].max()), y_range=(0, dfTramosKm.Velocidad.max() * 1.1), tools='', toolbar_location=None) PLT_TramosKm.add_layout( Span(location=AVG_Velocidad[0], dimension='width', line_color=BlueJeans[2], line_dash='dashed', line_width=0.1, line_alpha=0.3)) PLT_BarrasKM = PLT_TramosKm.rect(x='x', y='y', width='Distancia', height='Velocidad', source=OrigenTramosKm, line_width=1, line_color=BlueJeans[2], fill_color=BlueJeans[1]) PLT_TramosKm.add_tools( HoverTool(tooltips=[('', '@Ritmo_STR')], renderers=[PLT_BarrasKM], mode='mouse')) PropiedadesLineas = dict(line_width=2, line_alpha=0.7, line_cap='round', visible=False) PLT_TramosKM_Altitud = PLT_TramosKm.line('Distancia', 'AltitudEscalada', source=OrigenParcialesKM, color=paleta_verde[6], **PropiedadesLineas) PLT_TramosKM_FC = PLT_TramosKm.line('Distancia', 'FrecuenciaCardiacaEscalada', source=OrigenParcialesKM, color=paleta_rojo[6], **PropiedadesLineas) PLT_TramosKM_Cadencia = PLT_TramosKm.circle( 'Distancia', 'CadenciaEscalada', source=OrigenParcialesKM_Agg, size=SizeCircle, line_color=transform('Cadencia', MapaColorCadencia), color=transform('Cadencia', MapaColorCadencia), fill_alpha=1, visible=False) # Atributos PLT_TramosKm.title.text = 'RITMO MEDIO KILOMETRICO' PLT_TramosKm.sizing_mode = 'fixed' PLT_TramosKm.xaxis.axis_label = 'Distancia' PLT_TramosKm.xaxis.formatter = NumeralTickFormatter(format='0 a') PLT_TramosKm.yaxis.axis_label = 'Ritmo [min/km]' PLT_TramosKm.grid.visible = False PLT_TramosKm.yaxis.major_label_overrides = { 1: '16:40', 1.5: '16:06', 2: '8:20', 2.5: '6:40', 3: '5:33', 3.5: '4:45', 4: '4:10', 4.5: '3:42', 5: '3:20', 5.5: '3:01', 6: '2:46', 6.5: '2:34', 7: '2:22' } PLT_TramosKm.xaxis.ticker = SingleIntervalTicker(interval=1000) PLT_TramosKm.xaxis.major_label_overrides = FormateoEjes( OrigenParcialesKM.data['Distancia'], 1000, 1000, 0, 0) """ DATOS EN FORMA DE TABLA POR PARCIALES KILOMETRICOS """ TablaKm = [ TableColumn(field='TramoKm', title='Km', width=40, default_sort='ascending', sortable=False, formatter=StringFormatter(font_style='normal', text_align='center', text_color='black')), TableColumn(field='Ritmo_STR', title='Ritmo[min/Km]', width=80, default_sort='ascending', sortable=False, formatter=StringFormatter(font_style='normal', text_align='center', text_color='black')), TableColumn(field='FrecuenciaCardiaca', title='FC[ppm]', width=80, default_sort='ascending', sortable=False, formatter=NumberFormatter(format='0,0', language='es', rounding='round', font_style='normal', text_align='center', text_color='black')), TableColumn(field='Cadencia', title='Cadencia[ppm]', width=80, default_sort='ascending', sortable=False, formatter=NumberFormatter(format='0,0', language='es', rounding='round', font_style='normal', text_align='center', text_color='black')), TableColumn(field='DesnivelAcumulado', title='Desnivel', width=80, default_sort='ascending', sortable=False, formatter=NumberFormatter(format='0,0', language='es', rounding='round', font_style='normal', text_align='center', text_color='black')) ] PLT_TablaKm = DataTable(source=OrigenTramosKm, columns=TablaKm, width=360, height=550, fit_columns=False, sortable=False, reorderable=False, selectable=True, editable=False, index_position=None, header_row=True, row_height=25) """ BOTONES """ CodigoJS = """ var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; l0.visible = indexOf.call(checkbox.active,0)>=0; l1.visible = indexOf.call(checkbox.active,1)>=0; l2.visible = indexOf.call(checkbox.active,2)>=0; """ BotonesTramosKm = CheckboxButtonGroup( labels=["Altitud", "Frecuencia Cardiaca", "Cadencia"], active=[], width=300, height=30) CodigoJSTramosKm = CustomJS(code=CodigoJS, args=dict(l0=PLT_TramosKM_Altitud, l1=PLT_TramosKM_FC, l2=PLT_TramosKM_Cadencia, checkbox=BotonesTramosKm)) BotonesTramosKm.js_on_click(CodigoJSTramosKm) """ LAYOUT """ GridGraficaTramosKm = layout([ Column(PLT_TramosKm, width=900, height=500), [ Spacer(width=300, height=30), Column(BotonesTramosKm, width=300, height=30), Spacer(width=300, height=30) ] ], sizing_mode='stretch_width', width=900, height=570) GridTablaTramosKm = layout([ Spacer(width=360, height=25), Column(PLT_TablaKm, width=360, height=550) ], sizing_mode='stretch_width', width=360, height=570) GridAnalisisKm = gridplot([GridGraficaTramosKm, GridTablaTramosKm], ncols=2, sizing_mode='stretch_width', toolbar_location=None, plot_width=1000, plot_height=570) return GridAnalisisKm
code1 = "source1.set('selected', cb_data['index']);" code2 = "source2.set('selected', cb_data['index']);" callback = CustomJS(args={'source1': source, 'source2': source}, code=code1+code2) hover1 = HoverTool(callback=callback, renderers=[c1], tooltips=tooltip) hover2 = HoverTool(callback=callback, renderers=[c2], tooltips=tooltip) taptool = p1.select(type=TapTool) taptool.callback = OpenURL(url="@youtube") taptool = p2.select(type=TapTool) taptool.callback = OpenURL(url="@youtube") p1.add_tools(hover1) p2.add_tools(hover2) table = Table(features, pca.components_, sica.components_[0:2, :]) sourcetab = ColumnDataSource(table.get_dict()) format = NumberFormatter(format='0.00000') columns = [TableColumn(field='name', title='Feature Name'), TableColumn(field='pca_weightcomp1', title='PCA x-axis Weight', formatter=format), TableColumn(field='pca_weightcomp2', title='PCA y-axis Weight', formatter=format), TableColumn(field='sica_weightcomp1', title='SICA x-axis Weight', formatter=format), TableColumn(field='sica_weightcomp2', title='SICA y-axis Weight', formatter=format)] data_table = DataTable(source=sourcetab, columns=columns, width=700, height=600) ''' g1 = figure(plot_width=600, plot_height=500, x_range=(-1.1,1.1), y_range=(-1.1,1.1)) g_render = from_networkx(G, nx.spring_layout, scale=2, center=(0,0)) g1.renderers.append(g_render) ''' # BOKEH SERVER lambda1 = Slider(title="lambda1", value=sica.l1, start=0, end=1, step=0.01) lambda2 = Slider(title="lambda2", value=sica.l2, start=0, end=1, step=0.01)
def do_layout(self): """ generates the overall layout by creating all the widgets, buttons etc and arranges them in rows and columns :return: None """ self.source = self.generate_source() tab_plot = self.generate_plot(self.source) multi_select = MultiSelect(title="Option (Multiselect Ctrl+Click):", value=self.active_country_list, options=countries, height=500) multi_select.on_change('value', self.update_data) tab_plot.on_change('active', self.update_tab) radio_button_group_per_capita = RadioButtonGroup( labels=["Total Cases", "Cases per Million"], active=0 if not self.active_per_capita else 1) radio_button_group_per_capita.on_click(self.update_capita) radio_button_group_scale = RadioButtonGroup( labels=[Scale.log.name.title(), Scale.linear.name.title()], active=self.active_y_axis_type.value) radio_button_group_scale.on_click(self.update_scale_button) radio_button_group_df = RadioButtonGroup(labels=[ Prefix.confirmed.name.title(), Prefix.deaths.name.title(), Prefix.recovered.name.title(), ], active=int( self.active_case_type)) radio_button_group_df.on_click(self.update_data_frame) refresh_button = Button(label="Refresh Data", button_type="default", width=150) refresh_button.on_click(load_data_frames) export_button = Button(label="Export Url", button_type="default", width=150) export_button.on_click(self.export_url) slider = Slider(start=1, end=30, value=self.active_window_size, step=1, title="Window Size for rolling average") slider.on_change('value', self.update_window_size) radio_button_average = RadioButtonGroup( labels=[Average.mean.name.title(), Average.median.name.title()], active=self.active_average) radio_button_average.on_click(self.update_average_button) plot_variables = [ self.active_plot_raw, self.active_plot_average, self.active_plot_trend ] plots_button_group = CheckboxButtonGroup( labels=["Raw", "Averaged", "Trend"], active=[i for i, x in enumerate(plot_variables) if x]) plots_button_group.on_click(self.update_shown_plots) world_map = self.create_world_map() link_div = Div( name="URL", text= fr'Link <a target="_blank" href="{self.url}">Link to this Plot</a>.', width=300, height=10, align='center') footer = Div( text= """Covid-19 Dashboard created by Andreas Weichslgartner in April 2020 with python, bokeh, pandas, numpy, pyproj, and colorcet. Source Code can be found at <a href="https://github.com/weichslgartner/covid_dashboard/">Github</a>.""", width=1600, height=10, align='center') self.generate_table_cumulative() columns = [ TableColumn(field="name", title="Country"), TableColumn(field="number_rolling", title="daily avg", formatter=NumberFormatter(format="0.")), TableColumn(field="number_daily", title="daily raw", formatter=NumberFormatter(format="0.")) ] top_top_14_new_header = Div(text="Highest confirmed (daily)", align='center') top_top_14_new = DataTable(source=self.top_new_source, name="Highest confirmed(daily)", columns=columns, width=300, height=380) self.generate_table_new() columns = [ TableColumn(field="name", title="Country"), TableColumn(field="number", title="confirmed(cumulative)", formatter=NumberFormatter(format="0.")) ] top_top_14_cum_header = Div(text="Highest confirmed (cumulative)", align='center') top_top_14_cum = DataTable(source=self.top_total_source, name="Highest confirmed(cumulative)", columns=columns, width=300, height=380) self.layout = layout([ row( column(tab_plot, world_map), column(top_top_14_new_header, top_top_14_new, top_top_14_cum_header, top_top_14_cum), column(link_div, row(refresh_button, export_button), radio_button_group_df, radio_button_group_per_capita, plots_button_group, radio_button_group_scale, slider, radio_button_average, multi_select), ), row(footer) ]) curdoc().add_root(self.layout) curdoc().title = "Bokeh Covid-19 Dashboard"
line_alpha=0.6) plot_corr.line('date', 'corr', source=source_corr, line_width=3, line_alpha=0.6) columns = [ TableColumn(field="word", title="word"), TableColumn(field="distance", title="distance") ] per_columns = [ TableColumn(field='word', title=u'词'), TableColumn(field='percentile', title=u'历史分位', formatter=NumberFormatter(format='0.00%')) ] data_table = DataTable(source=source_table, columns=columns, width=400, height=300) per_table = DataTable(source=source_per, columns=per_columns, width=400, height=300) def update_title(): plot_absolute.title.text = text.value + u"(绝对)= 周词频" plot.title.text = text.value + u"(相对)= 周词频 / 周所有词总词频" plot_weighted.title.text = text.value + u"(加权)= 周词频 * 词距离 / 周所有词总词频"
def _bokeh_component_plot(self, component: str, plot_options: dict, data_color: str = "darkblue", core_axis=None): """ Define a plot for an individual component. """ times, obs, err = (self.__dict__[component].times, self.__dict__[component].observations, self.__dict__[component].errors) source = ColumnDataSource( dict(times=times, obs=obs, err=err, lower=obs - err, upper=obs + err)) if not core_axis: p = figure(title=component, x_range=[times[0], times[-1]], **plot_options) else: p = figure(title=component, x_range=core_axis.x_range, **plot_options) p.background_fill_color = "lightgrey" p.yaxis.axis_label = f"{component} (mm)" p.xaxis.axis_label = "Time stamp (UTC)" p.min_border_bottom = 0 p.min_border_top = 0 p_scatter = p.scatter(x="times", y="obs", source=source, line_color=None, color=data_color) p_band = Band(base="times", lower="lower", upper="upper", source=source, level="underlay", fill_alpha=1.0, line_width=1, line_color=data_color) p.add_layout(p_band) datetick_formatter = DatetimeTickFormatter( days=["%Y/%m/%d"], months=["%Y/%m/%d"], hours=["%Y/%m/%dT%H:%M:%S"], minutes=["%Y/%m/%dT%H:%M:%S"], seconds=["%H:%M:%S"], hourmin=["%Y/%m/%dT%H:%M:%S"], minsec=["%H:%M:%S"]) p.xaxis.formatter = datetick_formatter # Add picker picks = ColumnDataSource({"x": [], "y": [], 'color': []}) renderer = p.scatter(x='x', y='y', source=picks, color='color', size=10) renderer_up = p.ray(x='x', y='y', source=picks, color='color', angle=90, angle_units="deg", length=0) renderer_down = p.ray(x='x', y='y', source=picks, color='color', angle=270, angle_units="deg", length=0) draw_tool = PointDrawTool( renderers=[renderer, renderer_up, renderer_down], empty_value="red", num_objects=2) p.add_tools(draw_tool) p.toolbar.active_tap = draw_tool tabledatetimeformatter = DateFormatter(format="%Y/%m/%d") columns = [ TableColumn(field="x", title="Date", formatter=tabledatetimeformatter), TableColumn(field="y", title="Offset (mm)", formatter=NumberFormatter(format="0.00")) ] table = DataTable(source=picks, columns=columns, editable=True, width=300) return p, table
def scattergraph_tab(floorplans): df = floorplans # column_names # df = df.rename(columns={'project_name':'Neighborhood','builder_name':'Builder','city':'Market','master_plan':'Community','typical_lot_size':'Lot Size','total_units_planned':'Total Units','total_units_sold':'Units Sold','total_remaining':'Unsold Homes','hoa1':'HOA','assessments':'Tax Rate','plan_name_1_field':'Plan Name','field_of_beds_1_field':'Beds','field_of_floors_1_field':'Floors','garage_1_field':'Garages','square_footage_1_field':'Square Footage','price_1_field':'Base Price'}) # colors # movies["color"] = np.where(movies["Oscars"] > 0, "orange", "grey") # movies["alpha"] = np.where(movies["Oscars"] > 0, 0.9, 0.25) # movies.fillna(0, inplace=True) # just replace missing values with zero # movies["revenue"] = movies.BoxOffice.apply(lambda x: '{:,d}'.format(int(x))) axis_map = { "Home Size": "Square Footage (1)", "Base Price": "Price (1)", "Lot Size (sf)": "Typical Lot Size", "Latitude": "Lat", "Longitude": "Long", "Sales Rate": "Sales Rate" } # desc = # Div(text=open(join(dirname(__file__), "description.html")).read(), sizing_mode="stretch_width") # Max and Min Values sf_max = math.ceil(df['Square Footage (1)'].max() / 500) * 500 sf_min = math.floor(df['Square Footage (1)'].min() / 500) * 500 price_max = math.ceil(df['Price (1)'].max() / 50000) * 50000 price_min = math.floor(df['Price (1)'].min() / 50000) * 50000 lot_max = math.ceil(df['Typical Lot Size'].max() / 500) * 500 lot_min = math.floor(df['Typical Lot Size'].min() / 500) * 500 # Input controls max_sf_widget = TextInput(title="Maximum Square Footage", value=str(sf_max)) min_sf_widget = TextInput(title="Minimum Square Footage", value=str(sf_min)) max_price_widget = TextInput(title="Maximum Base Price", value=str(price_max)) min_price_widget = TextInput(title="Minimum Base Price", value=str(price_min)) max_lot_size_widget = TextInput(title="Maximum Lot Size (sf)", value=str(lot_max)) min_lot_size_widget = TextInput(title="Minimum Lot Size (sf)", value=str(lot_min)) # builder_select = MultiSelect(title="Builder Select", value=sorted(list(df['Builder Name'].unique())),options=sorted(list(df['Builder Name'].unique()))) # market_select = MultiSelect(title="Market Select", value=sorted(list(df['City'].unique())),options=sorted(list(df['City'].unique()))) x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Home Size") y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Base Price") fha_span = Span(location=403000, dimension='width', line_color='blue', line_dash='dashed', line_width=.1) cll_span = Span(location=453100, dimension='width', line_color='green', line_dash='dashed', line_width=.1) sf_slider = RangeSlider(title="Square Footage", start=sf_min, end=sf_max, value=(sf_min, sf_max), step=500, value_throttled=(250, 250)) price_slider = RangeSlider(title="Base Price", start=price_min, end=price_max, value=(price_min, price_max), step=500, value_throttled=(50000, 50000)) lot_slider = RangeSlider(title="Lot Size (SF)", start=lot_min, end=lot_max, value=(lot_min, lot_max), step=500, value_throttled=(250, 250)) # Create Column Data Source that will be used by the plot source = ColumnDataSource(data=dict( SF=[], Price=[], Builder=[], Color=[], Neighborhood=[], LotSize=[], Market=[], Sales_Rate=[], Total_Homes=[], Homes_Sold=[], Unsold_Homes=[], Beds=[], Baths=[], HOA=[], Tax_Rate=[], Floors=[], Lat=[], Long=[], Submarket=[], OpenDate=[])) # source = ColumnDataSource(data=df) # TOOLTIPS=[ # ("Title", "@title"), # ("Year", "@year"), # ("$", "@revenue") # ] floors = [str(x) for x in df['# of Floors (1)'].unique()] markers = ['hex', 'circle_x', 'triangle', 'square'] # p = figure(plot_height=600, plot_width=700, title="", toolbar_location=None, tooltips=TOOLTIPS, sizing_mode="scale_both") # Create plots and attributes p = figure(plot_height=500, plot_width=800, title="Competitive Market Area") p.scatter( x='SF', y='Price', source=source, size=15, line_color='black', fill_alpha=.25, # legend='Floors', # # marker=factor_mark('Floors', markers, floors), # color=factor_cmap('Floors', 'Category10_4', floors) ) map_options = GMapOptions(lat=df.Lat.mean(), lng=df.Long.mean(), map_type="roadmap", zoom=8) pmap = gmap(Google_API, map_options, plot_width=360, plot_height=400, title="CMA Map", toolbar_location="above") pmap.circle(x="Long", y="Lat", size=15, fill_color='blue', fill_alpha=0.25, line_color='black', line_width=.08, source=source) p.yaxis.formatter = NumeralTickFormatter(format="$ 0,0") p.xaxis.formatter = NumeralTickFormatter(format="0,0") # Filter dataframe based on widget inputs def filter_df(): # builder_list = [builder_select_widget.labels[i] for i in builder_select_widget.active] # market_list = [market_select_widget.labels[i] for i in market_select_widget.active] # submarket_val = submarket.value.strip() selected = df[ (df['Square Footage (1)'] <= float(sf_slider.value[1])) & (df['Square Footage (1)'] >= float(sf_slider.value[0])) & (df['Price (1)'] <= float(price_slider.value[1])) & (df['Price (1)'] >= float(price_slider.value[0])) & (df['Typical Lot Size'] <= float(lot_slider.value[1])) & (df['Typical Lot Size'] >= float(lot_slider.value[0])) # (df['Builder Name'].isin(builder_list)) & # (df['City'].isin(market_list)) ] # if submarket_val != "All": # selected = selected[selected['Submarket'].str.contains(submarket_val)==True] return selected # Update df def update(): df = filter_df() df = df.sort_values(by=['Project Name']) p.xaxis.axis_label = x_axis.value p.yaxis.axis_label = y_axis.value # p.title.text = "%d Floorplans Selected, %d Communities Selected, %d Builders Selected" % (len(df), df.Neighborhood.nunique(), df.Builder.nunique()) source.data = dict( # x=df[x_name], # y=df[y_name], SF=df['Square Footage (1)'], Price=df['Price (1)'], # Color=df['Color'], Neighborhood=df['Project Name'], Floors=df['# of Floors (1)'], Builder=df['Builder Name'], Market=df['City'], Lot_Size=df['Typical Lot Size'], Sales_Rate=df['Sales Rate'], Total_Homes=df['Total Units Planned'], Homes_Sold=df['Total Units Sold'], Unsold_Homes=df['Total Remaining'], HOA=df['HOA1'], Tax_Rate=df['Assessments'], Beds=df['# of Beds (1)'], Baths=df['# of Baths (1)'], Lat=df['Lat'], Long=df['Long'], # Submarket=df['Submarket'], # Open_Date=df['Open Date'] ) # Add plot tools hover_callback = CustomJS( code="""var tooltips = document.getElementsByClassName("bk-tooltip"); for (var i = 0, len = tooltips.length; i < len; i ++) { tooltips[i].style.top = "25px"; // unset what bokeh.js sets tooltips[i].style.left = "100px"; tooltips[i].style.bottom = ""; tooltips[i].style.right = ""; """) hover_callback2 = CustomJS( code="""var tooltips = document.getElementsByClassName("bk-tooltip"); for (var i = 0, len = tooltips.length; i < len; i ++) { tooltips[i].style.top = "25px"; // unset what bokeh.js sets tooltips[i].style.left = "-700px"; tooltips[i].style.bottom = ""; tooltips[i].style.right = ""; }""") hover = HoverTool(tooltips=[ ('Neighborhood', '@Neighborhood'), ('Builder', '@Builder'), ('Market', '@Market'), ('Lot Size', '@{Lot_Size}{(0,0)}' " SF"), ('Square Footage', '@{SF}{0,0SF}' " SF"), ('Base Price', '@{Price}{$0,0}'), ('Floors', '@Floors'), ('Sales Rate', '@{Sales_Rate}{(0.0)}' "/Mo"), ('Beds/Baths', '@{Beds}' "/" '@{Baths}{(0.0)}'), ], callback=hover_callback, show_arrow=False, point_policy='snap_to_data') hover2 = HoverTool(tooltips=[ ('Neighborhood', '@Neighborhood'), ('Builder', '@Builder'), ('Market', '@Market'), ('Lot Size', '@{Lot_Size}{(0,0)}' " SF"), ('Square Footage', '@{SF}{0,0SF}' " SF"), ('Base Price', '@{Price}{$0,0}'), ('Floors', '@Floors'), ('Sales Rate', '@{Sales_Rate}{(0.0)}' "/Mo"), ('Beds/Baths', '@{Beds}' "/" '@{Baths}{(0.0)}'), ], callback=hover_callback2, show_arrow=False, point_policy='snap_to_data') table_columns = [ TableColumn(field='Neighborhood', title='Neighborhood'), TableColumn(field='Market', title='Market'), TableColumn(field='Builder', title='Builder'), TableColumn(field='SF', title='Home Size', formatter=NumberFormatter(format='0,0')), TableColumn(field='Price', title='Base Price', formatter=NumberFormatter(format='$ 0,0[.]00')) # TableColumn(field="Sales_Rate", title="Sales Rate",formatter=HTMLTemplateFormatter(template='<code><%= value +" / Mo" %></code>')), # TableColumn(field="Lot_Size", title='Avg Lot Size',formatter=HTMLTemplateFormatter(template='<code><%= value +" SF" %></code>')), # TableColumn(field="Open_Date", title="Open Date",formatter=DateFormatter(format="%m/%d/%Y")) ] def floorplans_query(): print('something') floorplans = pd.read_csv( join(dirname(join(dirname(__file__))), 'data', 'floorplans.csv')) con = sql.connect(join('data', 'Market.db')) floorplans.to_sql('floorplans', con, if_exists='replace') con.close() print(floorplans) return print('Data uploaded from CSV!') scattergraph_tab(floorplans) def download(): date = datetime.datetime.now().strftime("%m_%d_%y_h%Hm%Ms%S") print('Testing') df.to_csv( os.path.abspath( os.path.join(os.path.dirname(__file__), '..', 'data', 'Downloads', 'scattergraph' + str(date) + '.csv'))) button_dl = Button(label="Download", button_type="success") button_ul = Button(label="Upload data from CSV", button_type="success") button_dl.on_click(download) button_ul.on_click(floorplans_query) table = DataTable(source=source, columns=table_columns, editable=True, height=600, width=1200, fit_columns=True, scroll_to_selection=True) controls = [sf_slider, price_slider, lot_slider] for control in controls: control.on_change('value', lambda attr, old, new: update()) p.add_tools(hover) pmap.add_tools(hover2) pmap.add_tools(WheelZoomTool()) inputs = column([*controls, button_ul, button_dl], width=180, height=250) inputs.sizing_mode = "fixed" # Create layout l = layout([[column([inputs]), p, pmap], table], sizing_mode="fixed") tab = Panel(child=l, title='Scattergraph') # Initial call of update update() # Return return tab
def create(): doc = curdoc() det_data = {} cami_meta = {} def proposal_textinput_callback(_attr, _old, new): nonlocal cami_meta proposal = new.strip() for zebra_proposals_path in pyzebra.ZEBRA_PROPOSALS_PATHS: proposal_path = os.path.join(zebra_proposals_path, proposal) if os.path.isdir(proposal_path): # found it break else: raise ValueError(f"Can not find data for proposal '{proposal}'.") file_list = [] for file in os.listdir(proposal_path): if file.endswith(".hdf"): file_list.append((os.path.join(proposal_path, file), file)) file_select.options = file_list cami_meta = {} proposal_textinput = TextInput(title="Proposal number:", width=210) proposal_textinput.on_change("value", proposal_textinput_callback) def upload_button_callback(_attr, _old, new): nonlocal cami_meta with io.StringIO(base64.b64decode(new).decode()) as file: cami_meta = pyzebra.parse_h5meta(file) file_list = cami_meta["filelist"] file_select.options = [(entry, os.path.basename(entry)) for entry in file_list] upload_div = Div(text="or upload .cami file:", margin=(5, 5, 0, 5)) upload_button = FileInput(accept=".cami", width=200) upload_button.on_change("value", upload_button_callback) def update_image(index=None): if index is None: index = index_spinner.value current_image = det_data["data"][index] proj_v_line_source.data.update(x=np.arange(0, IMAGE_W) + 0.5, y=np.mean(current_image, axis=0)) proj_h_line_source.data.update(x=np.mean(current_image, axis=1), y=np.arange(0, IMAGE_H) + 0.5) image_source.data.update( h=[np.zeros((1, 1))], k=[np.zeros((1, 1))], l=[np.zeros((1, 1))], ) image_source.data.update(image=[current_image]) if main_auto_checkbox.active: im_min = np.min(current_image) im_max = np.max(current_image) display_min_spinner.value = im_min display_max_spinner.value = im_max image_glyph.color_mapper.low = im_min image_glyph.color_mapper.high = im_max if "mf" in det_data: metadata_table_source.data.update(mf=[det_data["mf"][index]]) else: metadata_table_source.data.update(mf=[None]) if "temp" in det_data: metadata_table_source.data.update(temp=[det_data["temp"][index]]) else: metadata_table_source.data.update(temp=[None]) gamma, nu = calculate_pol(det_data, index) omega = np.ones((IMAGE_H, IMAGE_W)) * det_data["omega"][index] image_source.data.update(gamma=[gamma], nu=[nu], omega=[omega]) def update_overview_plot(): h5_data = det_data["data"] n_im, n_y, n_x = h5_data.shape overview_x = np.mean(h5_data, axis=1) overview_y = np.mean(h5_data, axis=2) overview_plot_x_image_source.data.update(image=[overview_x], dw=[n_x], dh=[n_im]) overview_plot_y_image_source.data.update(image=[overview_y], dw=[n_y], dh=[n_im]) if proj_auto_checkbox.active: im_min = min(np.min(overview_x), np.min(overview_y)) im_max = max(np.max(overview_x), np.max(overview_y)) proj_display_min_spinner.value = im_min proj_display_max_spinner.value = im_max overview_plot_x_image_glyph.color_mapper.low = im_min overview_plot_y_image_glyph.color_mapper.low = im_min overview_plot_x_image_glyph.color_mapper.high = im_max overview_plot_y_image_glyph.color_mapper.high = im_max frame_range.start = 0 frame_range.end = n_im frame_range.reset_start = 0 frame_range.reset_end = n_im frame_range.bounds = (0, n_im) scan_motor = det_data["scan_motor"] overview_plot_y.axis[1].axis_label = f"Scanning motor, {scan_motor}" var = det_data[scan_motor] var_start = var[0] var_end = var[-1] + (var[-1] - var[0]) / (n_im - 1) scanning_motor_range.start = var_start scanning_motor_range.end = var_end scanning_motor_range.reset_start = var_start scanning_motor_range.reset_end = var_end # handle both, ascending and descending sequences scanning_motor_range.bounds = (min(var_start, var_end), max(var_start, var_end)) def file_select_callback(_attr, old, new): nonlocal det_data if not new: # skip empty selections return # Avoid selection of multiple indicies (via Shift+Click or Ctrl+Click) if len(new) > 1: # drop selection to the previous one file_select.value = old return if len(old) > 1: # skip unnecessary update caused by selection drop return det_data = pyzebra.read_detector_data(new[0]) if cami_meta and "crystal" in cami_meta: det_data["ub"] = cami_meta["crystal"]["UB"] index_spinner.value = 0 index_spinner.high = det_data["data"].shape[0] - 1 index_slider.end = det_data["data"].shape[0] - 1 zebra_mode = det_data["zebra_mode"] if zebra_mode == "nb": metadata_table_source.data.update(geom=["normal beam"]) else: # zebra_mode == "bi" metadata_table_source.data.update(geom=["bisecting"]) update_image(0) update_overview_plot() file_select = MultiSelect(title="Available .hdf files:", width=210, height=250) file_select.on_change("value", file_select_callback) def index_callback(_attr, _old, new): update_image(new) index_slider = Slider(value=0, start=0, end=1, show_value=False, width=400) index_spinner = Spinner(title="Image index:", value=0, low=0, width=100) index_spinner.on_change("value", index_callback) index_slider.js_link("value_throttled", index_spinner, "value") index_spinner.js_link("value", index_slider, "value") plot = Plot( x_range=Range1d(0, IMAGE_W, bounds=(0, IMAGE_W)), y_range=Range1d(0, IMAGE_H, bounds=(0, IMAGE_H)), plot_height=IMAGE_PLOT_H, plot_width=IMAGE_PLOT_W, toolbar_location="left", ) # ---- tools plot.toolbar.logo = None # ---- axes plot.add_layout(LinearAxis(), place="above") plot.add_layout(LinearAxis(major_label_orientation="vertical"), place="right") # ---- grid lines plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph image_source = ColumnDataSource( dict( image=[np.zeros((IMAGE_H, IMAGE_W), dtype="float32")], h=[np.zeros((1, 1))], k=[np.zeros((1, 1))], l=[np.zeros((1, 1))], gamma=[np.zeros((1, 1))], nu=[np.zeros((1, 1))], omega=[np.zeros((1, 1))], x=[0], y=[0], dw=[IMAGE_W], dh=[IMAGE_H], )) h_glyph = Image(image="h", x="x", y="y", dw="dw", dh="dh", global_alpha=0) k_glyph = Image(image="k", x="x", y="y", dw="dw", dh="dh", global_alpha=0) l_glyph = Image(image="l", x="x", y="y", dw="dw", dh="dh", global_alpha=0) gamma_glyph = Image(image="gamma", x="x", y="y", dw="dw", dh="dh", global_alpha=0) nu_glyph = Image(image="nu", x="x", y="y", dw="dw", dh="dh", global_alpha=0) omega_glyph = Image(image="omega", x="x", y="y", dw="dw", dh="dh", global_alpha=0) plot.add_glyph(image_source, h_glyph) plot.add_glyph(image_source, k_glyph) plot.add_glyph(image_source, l_glyph) plot.add_glyph(image_source, gamma_glyph) plot.add_glyph(image_source, nu_glyph) plot.add_glyph(image_source, omega_glyph) image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") plot.add_glyph(image_source, image_glyph, name="image_glyph") # ---- projections proj_v = Plot( x_range=plot.x_range, y_range=DataRange1d(), plot_height=150, plot_width=IMAGE_PLOT_W, toolbar_location=None, ) proj_v.add_layout(LinearAxis(major_label_orientation="vertical"), place="right") proj_v.add_layout(LinearAxis(major_label_text_font_size="0pt"), place="below") proj_v.add_layout(Grid(dimension=0, ticker=BasicTicker())) proj_v.add_layout(Grid(dimension=1, ticker=BasicTicker())) proj_v_line_source = ColumnDataSource(dict(x=[], y=[])) proj_v.add_glyph(proj_v_line_source, Line(x="x", y="y", line_color="steelblue")) proj_h = Plot( x_range=DataRange1d(), y_range=plot.y_range, plot_height=IMAGE_PLOT_H, plot_width=150, toolbar_location=None, ) proj_h.add_layout(LinearAxis(), place="above") proj_h.add_layout(LinearAxis(major_label_text_font_size="0pt"), place="left") proj_h.add_layout(Grid(dimension=0, ticker=BasicTicker())) proj_h.add_layout(Grid(dimension=1, ticker=BasicTicker())) proj_h_line_source = ColumnDataSource(dict(x=[], y=[])) proj_h.add_glyph(proj_h_line_source, Line(x="x", y="y", line_color="steelblue")) # add tools hovertool = HoverTool(tooltips=[ ("intensity", "@image"), ("gamma", "@gamma"), ("nu", "@nu"), ("omega", "@omega"), ("h", "@h"), ("k", "@k"), ("l", "@l"), ]) box_edit_source = ColumnDataSource(dict(x=[], y=[], width=[], height=[])) box_edit_glyph = Rect(x="x", y="y", width="width", height="height", fill_alpha=0, line_color="red") box_edit_renderer = plot.add_glyph(box_edit_source, box_edit_glyph) boxedittool = BoxEditTool(renderers=[box_edit_renderer], num_objects=1) def box_edit_callback(_attr, _old, new): if new["x"]: h5_data = det_data["data"] x_val = np.arange(h5_data.shape[0]) left = int(np.floor(new["x"][0])) right = int(np.ceil(new["x"][0] + new["width"][0])) bottom = int(np.floor(new["y"][0])) top = int(np.ceil(new["y"][0] + new["height"][0])) y_val = np.sum(h5_data[:, bottom:top, left:right], axis=(1, 2)) else: x_val = [] y_val = [] roi_avg_plot_line_source.data.update(x=x_val, y=y_val) box_edit_source.on_change("data", box_edit_callback) wheelzoomtool = WheelZoomTool(maintain_focus=False) plot.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), hovertool, boxedittool, ) plot.toolbar.active_scroll = wheelzoomtool # shared frame ranges frame_range = Range1d(0, 1, bounds=(0, 1)) scanning_motor_range = Range1d(0, 1, bounds=(0, 1)) det_x_range = Range1d(0, IMAGE_W, bounds=(0, IMAGE_W)) overview_plot_x = Plot( title=Title(text="Projections on X-axis"), x_range=det_x_range, y_range=frame_range, extra_y_ranges={"scanning_motor": scanning_motor_range}, plot_height=400, plot_width=IMAGE_PLOT_W - 3, ) # ---- tools wheelzoomtool = WheelZoomTool(maintain_focus=False) overview_plot_x.toolbar.logo = None overview_plot_x.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), ) overview_plot_x.toolbar.active_scroll = wheelzoomtool # ---- axes overview_plot_x.add_layout(LinearAxis(axis_label="Coordinate X, pix"), place="below") overview_plot_x.add_layout(LinearAxis(axis_label="Frame", major_label_orientation="vertical"), place="left") # ---- grid lines overview_plot_x.add_layout(Grid(dimension=0, ticker=BasicTicker())) overview_plot_x.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph overview_plot_x_image_source = ColumnDataSource( dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_W], dh=[1])) overview_plot_x_image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") overview_plot_x.add_glyph(overview_plot_x_image_source, overview_plot_x_image_glyph, name="image_glyph") det_y_range = Range1d(0, IMAGE_H, bounds=(0, IMAGE_H)) overview_plot_y = Plot( title=Title(text="Projections on Y-axis"), x_range=det_y_range, y_range=frame_range, extra_y_ranges={"scanning_motor": scanning_motor_range}, plot_height=400, plot_width=IMAGE_PLOT_H + 22, ) # ---- tools wheelzoomtool = WheelZoomTool(maintain_focus=False) overview_plot_y.toolbar.logo = None overview_plot_y.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), ) overview_plot_y.toolbar.active_scroll = wheelzoomtool # ---- axes overview_plot_y.add_layout(LinearAxis(axis_label="Coordinate Y, pix"), place="below") overview_plot_y.add_layout( LinearAxis( y_range_name="scanning_motor", axis_label="Scanning motor", major_label_orientation="vertical", ), place="right", ) # ---- grid lines overview_plot_y.add_layout(Grid(dimension=0, ticker=BasicTicker())) overview_plot_y.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph overview_plot_y_image_source = ColumnDataSource( dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_H], dh=[1])) overview_plot_y_image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") overview_plot_y.add_glyph(overview_plot_y_image_source, overview_plot_y_image_glyph, name="image_glyph") roi_avg_plot = Plot( x_range=DataRange1d(), y_range=DataRange1d(), plot_height=150, plot_width=IMAGE_PLOT_W, toolbar_location="left", ) # ---- tools roi_avg_plot.toolbar.logo = None # ---- axes roi_avg_plot.add_layout(LinearAxis(), place="below") roi_avg_plot.add_layout(LinearAxis(major_label_orientation="vertical"), place="left") # ---- grid lines roi_avg_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) roi_avg_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) roi_avg_plot_line_source = ColumnDataSource(dict(x=[], y=[])) roi_avg_plot.add_glyph(roi_avg_plot_line_source, Line(x="x", y="y", line_color="steelblue")) cmap_dict = { "gray": Greys256, "gray_reversed": Greys256[::-1], "plasma": Plasma256, "cividis": Cividis256, } def colormap_callback(_attr, _old, new): image_glyph.color_mapper = LinearColorMapper(palette=cmap_dict[new]) overview_plot_x_image_glyph.color_mapper = LinearColorMapper( palette=cmap_dict[new]) overview_plot_y_image_glyph.color_mapper = LinearColorMapper( palette=cmap_dict[new]) colormap = Select(title="Colormap:", options=list(cmap_dict.keys()), width=210) colormap.on_change("value", colormap_callback) colormap.value = "plasma" STEP = 1 def main_auto_checkbox_callback(state): if state: display_min_spinner.disabled = True display_max_spinner.disabled = True else: display_min_spinner.disabled = False display_max_spinner.disabled = False update_image() main_auto_checkbox = CheckboxGroup(labels=["Main Auto Range"], active=[0], width=145, margin=[10, 5, 0, 5]) main_auto_checkbox.on_click(main_auto_checkbox_callback) def display_max_spinner_callback(_attr, _old_value, new_value): display_min_spinner.high = new_value - STEP image_glyph.color_mapper.high = new_value display_max_spinner = Spinner( low=0 + STEP, value=1, step=STEP, disabled=bool(main_auto_checkbox.active), width=100, height=31, ) display_max_spinner.on_change("value", display_max_spinner_callback) def display_min_spinner_callback(_attr, _old_value, new_value): display_max_spinner.low = new_value + STEP image_glyph.color_mapper.low = new_value display_min_spinner = Spinner( low=0, high=1 - STEP, value=0, step=STEP, disabled=bool(main_auto_checkbox.active), width=100, height=31, ) display_min_spinner.on_change("value", display_min_spinner_callback) PROJ_STEP = 0.1 def proj_auto_checkbox_callback(state): if state: proj_display_min_spinner.disabled = True proj_display_max_spinner.disabled = True else: proj_display_min_spinner.disabled = False proj_display_max_spinner.disabled = False update_overview_plot() proj_auto_checkbox = CheckboxGroup(labels=["Projections Auto Range"], active=[0], width=145, margin=[10, 5, 0, 5]) proj_auto_checkbox.on_click(proj_auto_checkbox_callback) def proj_display_max_spinner_callback(_attr, _old_value, new_value): proj_display_min_spinner.high = new_value - PROJ_STEP overview_plot_x_image_glyph.color_mapper.high = new_value overview_plot_y_image_glyph.color_mapper.high = new_value proj_display_max_spinner = Spinner( low=0 + PROJ_STEP, value=1, step=PROJ_STEP, disabled=bool(proj_auto_checkbox.active), width=100, height=31, ) proj_display_max_spinner.on_change("value", proj_display_max_spinner_callback) def proj_display_min_spinner_callback(_attr, _old_value, new_value): proj_display_max_spinner.low = new_value + PROJ_STEP overview_plot_x_image_glyph.color_mapper.low = new_value overview_plot_y_image_glyph.color_mapper.low = new_value proj_display_min_spinner = Spinner( low=0, high=1 - PROJ_STEP, value=0, step=PROJ_STEP, disabled=bool(proj_auto_checkbox.active), width=100, height=31, ) proj_display_min_spinner.on_change("value", proj_display_min_spinner_callback) def hkl_button_callback(): index = index_spinner.value h, k, l = calculate_hkl(det_data, index) image_source.data.update(h=[h], k=[k], l=[l]) hkl_button = Button(label="Calculate hkl (slow)", width=210) hkl_button.on_click(hkl_button_callback) def events_list_callback(_attr, _old, new): doc.events_list_spind.value = new events_list = TextAreaInput(rows=7, width=830) events_list.on_change("value", events_list_callback) doc.events_list_hdf_viewer = events_list def add_event_button_callback(): diff_vec = [] p0 = [1.0, 0.0, 1.0] maxfev = 100000 wave = det_data["wave"] ddist = det_data["ddist"] gamma = det_data["gamma"][0] omega = det_data["omega"][0] nu = det_data["nu"][0] chi = det_data["chi"][0] phi = det_data["phi"][0] scan_motor = det_data["scan_motor"] var_angle = det_data[scan_motor] x0 = int(np.floor(det_x_range.start)) xN = int(np.ceil(det_x_range.end)) y0 = int(np.floor(det_y_range.start)) yN = int(np.ceil(det_y_range.end)) fr0 = int(np.floor(frame_range.start)) frN = int(np.ceil(frame_range.end)) data_roi = det_data["data"][fr0:frN, y0:yN, x0:xN] cnts = np.sum(data_roi, axis=(1, 2)) coeff, _ = curve_fit(gauss, range(len(cnts)), cnts, p0=p0, maxfev=maxfev) m = cnts.mean() sd = cnts.std() snr_cnts = np.where(sd == 0, 0, m / sd) frC = fr0 + coeff[1] var_F = var_angle[math.floor(frC)] var_C = var_angle[math.ceil(frC)] frStep = frC - math.floor(frC) var_step = var_C - var_F var_p = var_F + var_step * frStep if scan_motor == "gamma": gamma = var_p elif scan_motor == "omega": omega = var_p elif scan_motor == "nu": nu = var_p elif scan_motor == "chi": chi = var_p elif scan_motor == "phi": phi = var_p intensity = coeff[1] * abs( coeff[2] * var_step) * math.sqrt(2) * math.sqrt(np.pi) projX = np.sum(data_roi, axis=(0, 1)) coeff, _ = curve_fit(gauss, range(len(projX)), projX, p0=p0, maxfev=maxfev) x_pos = x0 + coeff[1] projY = np.sum(data_roi, axis=(0, 2)) coeff, _ = curve_fit(gauss, range(len(projY)), projY, p0=p0, maxfev=maxfev) y_pos = y0 + coeff[1] ga, nu = pyzebra.det2pol(ddist, gamma, nu, x_pos, y_pos) diff_vector = pyzebra.z1frmd(wave, ga, omega, chi, phi, nu) d_spacing = float(pyzebra.dandth(wave, diff_vector)[0]) diff_vector = diff_vector.flatten() * 1e10 dv1, dv2, dv3 = diff_vector diff_vec.append(diff_vector) if events_list.value and not events_list.value.endswith("\n"): events_list.value = events_list.value + "\n" events_list.value = ( events_list.value + f"{x_pos} {y_pos} {intensity} {snr_cnts} {dv1} {dv2} {dv3} {d_spacing}" ) add_event_button = Button(label="Add spind event") add_event_button.on_click(add_event_button_callback) metadata_table_source = ColumnDataSource( dict(geom=[""], temp=[None], mf=[None])) num_formatter = NumberFormatter(format="0.00", nan_format="") metadata_table = DataTable( source=metadata_table_source, columns=[ TableColumn(field="geom", title="Geometry", width=100), TableColumn(field="temp", title="Temperature", formatter=num_formatter, width=100), TableColumn(field="mf", title="Magnetic Field", formatter=num_formatter, width=100), ], width=300, height=50, autosize_mode="none", index_position=None, ) # Final layout import_layout = column(proposal_textinput, upload_div, upload_button, file_select) layout_image = column( gridplot([[proj_v, None], [plot, proj_h]], merge_tools=False)) colormap_layout = column( colormap, main_auto_checkbox, row(display_min_spinner, display_max_spinner), proj_auto_checkbox, row(proj_display_min_spinner, proj_display_max_spinner), ) layout_controls = column( row(metadata_table, index_spinner, column(Spacer(height=25), index_slider)), row(add_event_button, hkl_button), row(events_list), ) layout_overview = column( gridplot( [[overview_plot_x, overview_plot_y]], toolbar_options=dict(logo=None), merge_tools=True, toolbar_location="left", ), ) tab_layout = row( column(import_layout, colormap_layout), column(layout_overview, layout_controls), column(roi_avg_plot, layout_image), ) return Panel(child=tab_layout, title="hdf viewer")
def process_data_samples__tabular(options, name, data, data_types, type_categories, title, with_column_title_rotation=True): """ Create a tabular panel of the data & types Args: options: data: a dictionary of (key, values) data_types: a dictionary of (key, type) indicating special type of ``key`` title: the title of the panel to be displayed Returns: a panel """ image_style = """ img { height:%dpx; width:%dpx; } """ % (options.image_size, options.image_size) template = f""" <div> <style> {image_style} </style> <img src=<%= value %> ></img> </div> """ with_images = False columns = [] for key in data.keys(): type = data_types.get(key) if type is not None and 'BLOB_IMAGE' in type: with_images = True c = TableColumn(field=key, title=key, formatter=HTMLTemplateFormatter(template=template)) else: type_category = type_categories[key] table_kargs = {} if type_category == DataCategory.Continuous: table_kargs['formatter'] = NumberFormatter(format='0,0[.000]') c = TableColumn(field=key, title=key, **table_kargs) columns.append(c) # filter out data filtered_data = filter_large_data(options, data) data_source = ColumnDataSource(filtered_data) if with_column_title_rotation: # custom CSS to slightly rotate the column header # and draw text outside their respective columns # to improve readability. TODO That could be improved div = Div(text=f""" <style> .trw_reporting_table_{name} .slick-header-column {{ background-color: transparent; background-image: none !important; transform: rotate(-10deg) }} .bk-root .slick-header-column.ui-state-default {{ height: 40px; overflow: visible; vertical-align: bottom; line-height: 4.4; }} </style> """) div.visible = False # hide the div to avoid position issues else: div = Div() row_height = options.font_size if with_images: row_height = options.image_size data_table = DataTable( source=data_source, columns=columns, row_height=row_height, #fit_columns=True, css_classes=[f"trw_reporting_table_{name}"]) return Panel(child=column(data_table, div, sizing_mode='stretch_both'), title=title), data_table
tabs = Tabs(tabs=[mk_tab("red"), mk_tab("green"), mk_tab("blue")]) source = ColumnDataSource(data=mpg) columns = [ TableColumn(field="manufacturer", title="Manufacturer", editor=SelectEditor(options=sorted(mpg["manufacturer"].unique())), formatter=StringFormatter(font_style="bold")), TableColumn(field="model", title="Model", editor=StringEditor(completions=sorted(mpg["model"].unique()))), 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=sorted(mpg["trans"].unique()))), TableColumn(field="drv", title="Drive", editor=SelectEditor(options=sorted(mpg["drv"].unique()))), TableColumn(field="class", title="Class", editor=SelectEditor(options=sorted(mpg["class"].unique()))),
s1 = tdoa_plot.circle(x='x', y='y', radius='rx', fill_color='black', line_color='black', fill_alpha=0.4, source=st_source) s2 = tdoa_plot.inverted_triangle(x='x', y='y', size=4, color='black', source=st_source) tdoa_plot.diamond(x='x', y='y', size=10, color='blue', source=ig_source) tdoa_plot.scatter(x='x', y='y', size=3, color='blue', source=etx_source) tdoa_plot.scatter(x='x', y='y', size=5, color='lime', source=ctx_source) tdoa_plot.line(x='x', y='y', line_width=2, color='lime', source=ell_source) tdoa_plot.scatter(x='x', y='y', size=5, color='red', source=tx_source) # tool = PointDrawTool(renderers=[s1, s2], num_objects=3) # tdoa_plot.add_tools(tool) ### --------------------------------------------------------------------------- # setup the inputs # define the receiver columns to display columns = [ TableColumn(field="x", title="X (km)", formatter=NumberFormatter(format='0[.]000', text_align='center')), TableColumn(field="y", title="Y (km)", formatter=NumberFormatter(format='0[.]000', text_align='center')), ] st_datatable = DataTable(source=st_source, columns=columns, width=250, height=125, editable=True) # define the initial guess ig_datatable = DataTable(source=ig_source, columns=columns, width=250, height=75, editable=True) # define the emitter location tx_datatable = DataTable(source=tx_source, columns=columns, width=250, height=75, editable=True) tdoa_results = "<font size='3'>AOU (km^2):<br>" ### --------------------------------------------------------------------------- T = calc_arrival_times(S, T, P, N, v)
qq.line(x='x', y='y', color='gray', source=qq_line_source) # Distribution dropdown widget #options = [x for x in dir(stats) if isinstance(getattr(stats, x), stats.rv_continuous)] options = ['gamma', 'lognorm', 'norm', 'weibull_min'] dist_menu = Select(options=options, value='norm', title='Select distribution:') dist_menu.on_change('value', on_dist_change) # Data source dropdown widget #files = [x for x in os.listdir('data') if x.split('.')[-1] == 'csv'] files = ['data.csv', 'data2.csv'] data_source_menu = Select(options=files, value='data.csv', title='Select data source:') data_source_menu.on_change('value', on_change_data_source) # Table widget num_format = NumberFormatter() num_format.format = '0.00000' metrics_columns = [ TableColumn(field='method', title='Source'), TableColumn(field='mean', title='Mean', formatter=num_format), TableColumn(field='sd', title='Std Dev', formatter=num_format), TableColumn(field='loc', title='Loc Param', formatter=num_format), TableColumn(field='scale', title='Scale Param', formatter=num_format), TableColumn(field='shape', title='Shape Param', formatter=num_format), TableColumn(field='aic', title='AIC', formatter=num_format), ] metrics_table = DataTable(source=metrics_source, columns=metrics_columns, height=100) # Text input widget loc_val_input = TextInput(title='Specify distribution location value:', placeholder='none', value='') loc_val_input.on_change('value', on_dist_change)
def __init__(self, scheduler, width=800, **kwargs): self.scheduler = scheduler self.names = [ 'worker', 'ncores', 'cpu', 'memory', 'memory_limit', 'memory_percent', 'num_fds', 'read_bytes', 'write_bytes', 'cpu_fraction' ] table_names = [ 'worker', 'ncores', 'cpu', 'memory', 'memory_limit', 'memory_percent', 'num_fds', 'read_bytes', 'write_bytes' ] self.source = ColumnDataSource({k: [] for k in self.names}) columns = { name: TableColumn(field=name, title=name.replace('_percent', ' %')) for name in table_names } formatters = { 'cpu': NumberFormatter(format='0.0 %'), 'memory_percent': NumberFormatter(format='0.0 %'), 'memory': NumberFormatter(format='0 b'), 'memory_limit': NumberFormatter(format='0 b'), 'read_bytes': NumberFormatter(format='0 b'), 'write_bytes': NumberFormatter(format='0 b'), 'num_fds': NumberFormatter(format='0'), 'ncores': NumberFormatter(format='0') } if LooseVersion(bokeh.__version__) < '0.12.15': dt_kwargs = {'row_headers': False} else: dt_kwargs = {'index_position': None} table = DataTable(source=self.source, columns=[columns[n] for n in table_names], reorderable=True, sortable=True, width=width, **dt_kwargs) for name in table_names: if name in formatters: table.columns[table_names.index( name)].formatter = formatters[name] hover = HoverTool(point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 10px; font-family: Monaco, monospace;">@host: </span> <span style="font-size: 10px; font-family: Monaco, monospace;">@memory_percent</span> </div> """) mem_plot = figure(title='Memory Use (%)', toolbar_location=None, x_range=(0, 1), y_range=(-0.1, 0.1), height=60, width=width, tools='', **kwargs) mem_plot.circle(source=self.source, x='memory_percent', y=0, size=10, fill_alpha=0.5) mem_plot.ygrid.visible = False mem_plot.yaxis.minor_tick_line_alpha = 0 mem_plot.xaxis.visible = False mem_plot.yaxis.visible = False mem_plot.add_tools(hover, BoxSelectTool()) hover = HoverTool(point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 10px; font-family: Monaco, monospace;">@worker: </span> <span style="font-size: 10px; font-family: Monaco, monospace;">@cpu</span> </div> """) cpu_plot = figure(title='CPU Use (%)', toolbar_location=None, x_range=(0, 1), y_range=(-0.1, 0.1), height=60, width=width, tools='', **kwargs) cpu_plot.circle(source=self.source, x='cpu_fraction', y=0, size=10, fill_alpha=0.5) cpu_plot.ygrid.visible = False cpu_plot.yaxis.minor_tick_line_alpha = 0 cpu_plot.xaxis.visible = False cpu_plot.yaxis.visible = False cpu_plot.add_tools(hover, BoxSelectTool()) self.cpu_plot = cpu_plot if 'sizing_mode' in kwargs: sizing_mode = {'sizing_mode': kwargs['sizing_mode']} else: sizing_mode = {} self.root = column(cpu_plot, mem_plot, table, id='bk-worker-table', **sizing_mode)
slider.on_change('value', lambda attr, old, new: update()) # Plot object which is updated plot = figure(title="Meetup Network Analysis", x_range=(-1.4,2.6), y_range=(-2.0,2.0), tools = "pan,wheel_zoom,box_select,reset,box_zoom,crosshair", plot_width=800, plot_height=700) # Assign layout for nodes, render graph, and add hover tool graph.node_renderer.data_source.selected.on_change("indices", selected_points) graph.layout_provider = StaticLayoutProvider(graph_layout=positions) graph.node_renderer.glyph = Circle(size='node_size', fill_color='node_color') graph.selection_policy = NodesOnly() plot.renderers.append(graph) plot.tools.append(HoverTool(tooltips=[('Name', '@index')])) # Create Summary Data Table num_format = NumberFormatter(format="0.00") summary_table_title = Div(text="""<b>Summary Statistics</b>""", width=525, height=10) summary_table_cols = [TableColumn(field='summary_stats', title="SummaryStats"), TableColumn(field='mean_member_count', title="Member Count",formatter=num_format), TableColumn(field='mean_degree_centrality', title="Degree Centrality",formatter=num_format), TableColumn(field='mean_rel_closeness_centrality', title="Rel. Closeness Centrality",formatter=num_format)] summary_data_table = DataTable(source=summary_data_table_source, columns=summary_table_cols, width=525, height=80) # Create Data Table data_table_cols = [TableColumn(field="group_name", title="Node Name"), TableColumn(field="member_count", title="Member Count",formatter=num_format), TableColumn(field="degree_centrality", title="Degree Centrality",formatter=num_format), TableColumn(field="rel_closeness_centrality", title="Rel. Closeness Centrality",formatter=num_format)] data_table = DataTable(source=data_table_source, columns=data_table_cols, width=525, height=550)
'pc', source=source_wei_index, line_width=3, line_alpha=0.6) plot_wei_index.title.text = words[0] + u'微指数' # plot_wei_index.line('date', 'mobile', source=source_wei_index, color='green', line_width=3, line_alpha=0.6, legend=u'移动端') columns = [ TableColumn(field="word", title="word"), TableColumn(field="distance", title="distance") ] per_columns = [ TableColumn(field='word', title=u'词'), TableColumn(field='percentile', title=u'历史分位', formatter=NumberFormatter(format='0.00%')), TableColumn(field='wei_percentile', title=u'微指数历史分位', formatter=NumberFormatter(format='0.00%')), TableColumn(field='diff', title=u'(华尔街见闻-微指数)历史分位', formatter=NumberFormatter(format='0.00%')) ] topic_columns = [ TableColumn(field='word', title=u'词'), TableColumn(field='value', title=u'概率', formatter=NumberFormatter(format='0.0000')) ] topic_per_columns = [ TableColumn(field='topic', title=u'主题'),
def __init__(self, scheduler, **kwargs): self.scheduler = scheduler self.names = [ 'disk-read', 'cores', 'cpu', 'disk-write', 'memory', 'last-seen', 'memory_percent', 'host', 'network-send', 'network-recv' ] self.source = ColumnDataSource({k: [] for k in self.names}) columns = { name: TableColumn(field=name, title=name.replace('_percent', ' %')) for name in self.names } cnames = [ 'host', 'cores', 'memory', 'cpu', 'memory_percent', 'network-send', 'network-recv' ] formatters = { 'cpu': NumberFormatter(format='0.0 %'), 'memory_percent': NumberFormatter(format='0.0 %'), 'memory': NumberFormatter(format='0 b'), 'latency': NumberFormatter(format='0.00000'), 'last-seen': NumberFormatter(format='0.000'), 'disk-read': NumberFormatter(format='0 b'), 'disk-write': NumberFormatter(format='0 b'), 'network-send': NumberFormatter(format='0 b'), 'network-recv': NumberFormatter(format='0 b') } table = DataTable( source=self.source, columns=[columns[n] for n in cnames], ) for name in cnames: if name in formatters: table.columns[cnames.index(name)].formatter = formatters[name] hover = HoverTool(point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 10px; font-family: Monaco, monospace;">@host: </span> <span style="font-size: 10px; font-family: Monaco, monospace;">@memory_percent</span> </div> """) mem_plot = figure(title='Memory Use (%)', toolbar_location=None, x_range=(0, 1), y_range=(-0.1, 0.1), height=80, tools='', **kwargs) mem_plot.circle(source=self.source, x='memory_percent', y=0, size=10, fill_alpha=0.5) mem_plot.ygrid.visible = False mem_plot.yaxis.minor_tick_line_alpha = 0 mem_plot.yaxis.visible = False mem_plot.add_tools(hover, BoxSelectTool()) hover = HoverTool(point_policy="follow_mouse", tooltips=""" <div> <span style="font-size: 10px; font-family: Monaco, monospace;">@host: </span> <span style="font-size: 10px; font-family: Monaco, monospace;">@cpu</span> </div> """) cpu_plot = figure(title='CPU Use (%)', toolbar_location=None, x_range=(0, 1), y_range=(-0.1, 0.1), height=80, tools='', **kwargs) cpu_plot.circle(source=self.source, x='cpu', y=0, size=10, fill_alpha=0.5) cpu_plot.ygrid.visible = False cpu_plot.yaxis.minor_tick_line_alpha = 0 cpu_plot.yaxis.visible = False cpu_plot.add_tools(hover, BoxSelectTool()) if 'sizing_mode' in kwargs: sizing_mode = {'sizing_mode': kwargs['sizing_mode']} else: sizing_mode = {} self.root = column(cpu_plot, mem_plot, table, id='bk-worker-table', **sizing_mode)
NumberFormatter, StringFormatter, TableColumn) from bokeh.sampledata.periodic_table import elements elements['name_lower'] = elements['name'].str.lower() source = ColumnDataSource(elements) html_font_template = '<font color="<%= CPK %>"><%= value %></font>' html_image_template = """ <a href="http://images-of-elements.com/<%= value %>.php" target="_blank"> <img src="http://images-of-elements.com/<%= value %>.jpg" style="width:40px;height:40px;border:0"> </a> """ columns = [ TableColumn(field='atomic number', title='Atomic Number', formatter=NumberFormatter(text_align="right")), TableColumn(field='symbol', title='Symbol', formatter=StringFormatter(text_align="center")), TableColumn(field='name', title='Name', formatter=HTMLTemplateFormatter(template=html_font_template)), TableColumn(field='name_lower', title='Image', formatter=HTMLTemplateFormatter(template=html_image_template)) ] data_table = DataTable(source=source, columns=columns, editable=False, row_height=45)
def plot_chart_bokeh(processed, dataCollection, keys, outputfilename): stock = processed['data'] # Define constants W_PLOT = 1000 H_PLOT = 360 TOOLS = 'pan,wheel_zoom,reset' VBAR_WIDTH = 1 * 12 * 60 * 60 * 1000 # one day in ms RED = Category20[7][6] GREEN = Category20[5][4] BLUE = Category20[3][0] BLUE_LIGHT = Category20[3][1] ORANGE = Category20[3][2] PURPLE = Category20[9][8] BROWN = Category20[11][10] # ========================================================================== # =================== PLOT CANDLE STICK GRAPH ==================== # ========================================================================== p1 = figure(plot_width=W_PLOT, plot_height=H_PLOT, tools=TOOLS, toolbar_location='right') inc = stock.data['Close'] >= stock.data['Open'] dec = stock.data['Open'] > stock.data['Close'] # limit = stock.data['ZC_d2/dt2'] > 10 # limit = stock.data['ZC_d/dt'] > 0 # view_inc = CDSView(source=stock, filters=[BooleanFilter(inc), BooleanFilter(limit)]) # view_dec = CDSView(source=stock, filters=[BooleanFilter(dec), BooleanFilter(limit)]) view_inc = CDSView(source=stock, filters=[BooleanFilter(inc)]) view_dec = CDSView(source=stock, filters=[BooleanFilter(dec)]) # # map dataframe indices to date strings and use as label overrides p1.y_range.start = 0.9 * min(stock.data['Low']) p1.y_range.end = 1.1 * max(stock.data['High']) p1.segment(x0='Date', x1='Date', y0='Low', y1='High', color=GREEN, source=stock, view=view_inc) p1.segment(x0='Date', x1='Date', y0='Low', y1='High', color=RED, source=stock, view=view_dec) vb1 = p1.vbar(x='Date', width=VBAR_WIDTH, top='Open', bottom='Close', fill_color='forestgreen', fill_alpha=1, line_color='forestgreen', source=stock, view=view_inc, name="price") vb2 = p1.vbar(x='Date', width=VBAR_WIDTH, top='Open', bottom='Close', fill_color='orangered', fill_alpha=1, line_color='orangered', source=stock, view=view_dec, name="price") # Bollinger band plot patch1 = p1.varea(x='Date', y1='lowerband', y2='upperband', source=stock, fill_alpha=0.05, fill_color='dodgerblue') patch_line1 = p1.line(x='Date', y='lowerband', source=stock, line_color='blue', line_alpha=0.4) patch_line2 = p1.line(x='Date', y='middleband', source=stock, line_color='grey', line_alpha=0.8, line_dash='dotdash') patch_line3 = p1.line(x='Date', y='upperband', source=stock, line_color='blue', line_alpha=0.4) # ZC Line plot zc_7 = p1.line(x='Date', y='ma7', source=stock, line_color='crimson', line_alpha=0.4) zc_26 = p1.line(x='Date', y='ma26', source=stock, line_color='darkslateblue', line_alpha=0.4) # # Resistance plots # r1 = p1.line(x='Date', y='r1', source=stock, line_color='forestgreen', line_dash='dotdash', line_alpha=0.6) # r2 = p1.line(x='Date', y='r2', source=stock, line_color='forestgreen', line_dash='dotdash', line_alpha=0.8) # r3 = p1.line(x='Date', y='r3', source=stock, line_color='forestgreen', line_dash='dotdash', line_alpha=1.0) # # Support plots # s1 = p1.line(x='Date', y='s1', source=stock, line_color='crimson', line_dash='dotdash', line_alpha=0.6) # s2 = p1.line(x='Date', y='s2', source=stock, line_color='crimson', line_dash='dotdash', line_alpha=0.8) # s3 = p1.line(x='Date', y='s3', source=stock, line_color='crimson', line_dash='dotdash', line_alpha=1.0) # Extrema plots # minima = p1.inverted_triangle(x='Date', y='minima', source=stock, size=5, color="goldenrod", alpha=0.5) # maxima = p1.triangle(x='Date', y='maxima', source=stock, size=5, color="teal", alpha=0.5) # minima = p1.circle( # x='Date', y='minima', source=stock, size=10, # fill_color="grey", hover_fill_color="firebrick", # fill_alpha=0.2, hover_alpha=0.8, hover_line_color="white") # maxima = p1.triangle( # x='Date', y='maxima', source=stock, # size=10, fill_color="grey", fill_alpha=0.2, # hover_fill_color="firebrick", hover_alpha=0.8, hover_line_color="white") # Volume plot # Setting the second y axis range name and range p1.extra_y_ranges = { "vol_axis": Range1d(start=0, end=max(stock.data['Volume']) * 4) } # Adding the second axis to the plot. p1.add_layout(LinearAxis(y_range_name="vol_axis", visible=False), 'right') vol_inc = p1.vbar(x="Date", top="Volume", bottom=0, width=int(VBAR_WIDTH * 2), fill_color=GREEN, fill_alpha=0.1, line_color=GREEN, line_alpha=0.2, source=stock, view=view_inc, y_range_name="vol_axis") vol_dec = p1.vbar(x="Date", top="Volume", bottom=0, width=int(VBAR_WIDTH * 2), fill_color=RED, fill_alpha=0.1, line_color=RED, line_alpha=0.2, source=stock, view=view_dec, y_range_name="vol_axis") legend = Legend(items=[ LegendItem( label="All", renderers=[ patch1, patch_line1, patch_line2, patch_line3, vol_inc, vol_dec, zc_7, zc_26, # s1, s2, s3,r1, r2, r3, # minima, maxima ], index=0), LegendItem(label="BB", renderers=[patch1, patch_line1, patch_line2, patch_line3], index=1), LegendItem(label="Volume", renderers=[vol_inc, vol_dec], index=2), LegendItem(label="ZC", renderers=[zc_7, zc_26], index=3), LegendItem(label="MA7", renderers=[zc_7], index=4), LegendItem(label="MA26", renderers=[zc_26], index=5), # LegendItem(label="Support", renderers=[s1, s2, s3], index=6), # LegendItem(label="Resistance", renderers=[r1, r2, r3], index=7), # LegendItem(label="Extrema", renderers=[minima, maxima], index=8) ]) p1.add_layout(legend) p1.legend.location = "top_left" p1.legend.border_line_alpha = 0 p1.legend.background_fill_alpha = 0 p1.legend.click_policy = "hide" p1.legend.orientation = "horizontal" # p1.add_layout(Title(text="Stock price", align="left"), "left") p1.yaxis.axis_label = 'Stock price' p1.yaxis.formatter = NumeralTickFormatter(format='0.00') p1.x_range.range_padding = 0.05 p1.xaxis.ticker.desired_num_ticks = 40 p1.xaxis.major_label_orientation = 3.14 / 4 p1.xaxis.visible = False p1.xgrid.grid_line_color = None p1.ygrid.grid_line_color = None # Select specific tool for the plot p1.add_tools( HoverTool( tooltips=[("Datetime", "@Date{%Y-%m-%d}"), ("Open", "@Open{0,0.00}"), ("Close", "@Close{0,0.00}"), ("Volume", "@Volume{(0.00 a)}")], formatters={"@Date": 'datetime'}, # display a tooltip whenever the cursor is vertically in line with a glyph mode='vline', renderers=[vb1, vb2])) # ========================================================================== # =================== PLOT STOCH / RSI GRAPH ================= # ========================================================================== p2 = figure(plot_width=W_PLOT, plot_height=int(H_PLOT / 4), tools=TOOLS, toolbar_location='above', x_range=p1.x_range, x_axis_type='datetime') # , y_range=(-20, 120) stoch_k = p2.line(x='Date', y='slowk', source=stock, line_color='royalblue', alpha=0.8, muted_alpha=0.2) stoch_d = p2.line(x='Date', y='slowd', source=stock, line_color='tomato', alpha=0.8, muted_alpha=0.2) rsi = p2.line(x='Date', y='rsi', source=stock, line_color='gray', alpha=0.8, muted_alpha=0.2) mid_box = BoxAnnotation(bottom=20, top=80, fill_alpha=0.2, fill_color='palegreen', line_color='lightcoral', line_alpha=0.4, line_dash='dashed') # candle = p2.line(x='Date', y='candle', source=stock, line_color='royalblue', alpha=0.8, muted_alpha=0.2) # mid_box = BoxAnnotation(bottom=-300, top=300, fill_alpha=0.2, fill_color='palegreen', line_color='lightcoral', line_alpha=0.4, line_dash='dashed') legend = Legend(items=[ LegendItem(label="Stoch", renderers=[stoch_k, stoch_d], index=0), LegendItem(label="RSI", renderers=[rsi], index=1) # LegendItem(label="Candle", renderers=[candle], index=1) ]) p2.add_layout(legend) p2.add_layout(mid_box) # p2.add_layout(lower) zero = Span(location=0, dimension='width', line_color='seagreen', line_dash='solid', line_width=0.8) p2.add_layout(zero) p2.yaxis.axis_label = 'Stochastic / RSI' p2.x_range.range_padding = 0.05 # p2.toolbar.autohide = True p2.xaxis.visible = False p2.legend.location = "top_left" p2.legend.border_line_alpha = 0 p2.legend.background_fill_alpha = 0 p2.legend.click_policy = "mute" p2.xgrid.grid_line_color = None p2.ygrid.grid_line_color = None # ========================================================================== # =================== Plot MACD ==================== # ========================================================================== y_limit = abs(max(stock.data['macd_hist'], key=abs)) y2_limit = abs(max(stock.data['macd_d/dt'], key=abs)) p3 = figure(plot_width=W_PLOT, plot_height=int(H_PLOT / 2.5), tools=TOOLS, toolbar_location='above', x_range=p1.x_range, x_axis_type='datetime', y_range=(-y_limit, y_limit)) mapper = LinearColorMapper(palette=Viridis256) macd_line = p3.line(x='Date', y='macd_hist', source=stock, line_color='darkgreen', alpha=0.8, muted_alpha=0.2) # macd_hist = p3.vbar_stack(['macd'], x='Date', source=stock, width=int(VBAR_WIDTH * 2), fill_color={'field':'macd', 'transform': mapper}) mid_box = BoxAnnotation(bottom=-0.5, top=0.5, fill_alpha=0.2, fill_color='blanchedalmond', line_color='grey', line_alpha=0.4, line_dash='dashed') zero = Span(location=0, dimension='width', line_color='seagreen', line_dash='solid', line_width=0.8) p3.add_layout(zero) p3.add_layout(mid_box) # Setting the second y axis range name and range p3.extra_y_ranges = { "extra_y_axis": Range1d(start=-y2_limit, end=y2_limit) } # Adding the second axis to the plot. p3.add_layout(LinearAxis(y_range_name="extra_y_axis"), 'right') macd_v = p3.line(x='Date', y='macd_d/dt', source=stock, line_color='dodgerblue', line_dash='solid', alpha=0.8, muted_alpha=0.2, y_range_name="extra_y_axis") macd_acc = p3.line(x='Date', y='macd_d2/dt2', source=stock, line_color='tomato', line_dash='dotdash', alpha=0.8, muted_alpha=0.2, y_range_name="extra_y_axis") legend = Legend(items=[ LegendItem(label="MACD", renderers=[macd_line], index=0), LegendItem(label="MACD-v", renderers=[macd_v], index=1), LegendItem(label="MACD-a", renderers=[macd_acc], index=2) ]) p3.add_layout(legend) p3.legend.location = "top_left" p3.legend.border_line_alpha = 0 p3.legend.background_fill_alpha = 0 p3.legend.click_policy = "mute" p3.legend.orientation = "horizontal" # p3.add_layout(Title(text="MACD", align="center"), "left") p3.yaxis.axis_label = 'MACD' p3.x_range.range_padding = 0.05 p3.xaxis.visible = False p3.xaxis.ticker.desired_num_ticks = 40 p3.xaxis.major_label_orientation = 3.14 / 4 p3.toolbar.autohide = True p3.xgrid.grid_line_color = None p3.ygrid.grid_line_color = None # ========================================================================== # =================== Plot ZC ==================== # ========================================================================== y_limit = abs(max(stock.data['ZC'], key=abs)) y2_limit = abs(max(stock.data['ZC_d/dt'], key=abs)) # y_limit = abs(max(stock.data['slowk'], key=abs)) # y2_limit = abs(max(stock.data['slowk_d/dt'], key=abs)) p4 = figure(plot_width=W_PLOT, plot_height=int(H_PLOT / 3), tools=TOOLS, toolbar_location='above', x_range=p1.x_range, x_axis_type='datetime', y_range=(-y_limit, y_limit)) p4.xaxis.formatter = DatetimeTickFormatter( hours=["%d.%m.%y"], days=["%d.%m.%y"], months=["%d.%m.%y"], years=["%d.%m.%y"], ) # macd_v = p4.line(x='Date', y='macd_d/dt', source=stock, line_color='royalblue', alpha=0.8, muted_alpha=0.2) # macd_acc = p4.line(x='Date', y='macd_d2/dt2', source=stock, line_color='tomato', alpha=0.8, muted_alpha=0.2) # ad = p4.line(x='Date', y='ck_AD', source=stock, line_color='royalblue', alpha=0.8, muted_alpha=0.2) # adosc = p4.line(x='Date', y='ck_ADOSC', source=stock, line_color='tomato', alpha=0.8, muted_alpha=0.2) # obv = p4.line(x='Date', y='OBV', source=stock, line_color='darkgreen', alpha=0.8, muted_alpha=0.2) # Setting the second y axis range name and range p4.extra_y_ranges = { "extra_y_axis": Range1d(start=-y2_limit, end=y2_limit) } # Adding the second axis to the plot. p4.add_layout(LinearAxis(y_range_name="extra_y_axis"), 'right') zc = p4.line(x='Date', y='ZC', source=stock, line_color='darkgreen', alpha=0.8, muted_alpha=0.2) zc_v = p4.line(x='Date', y='ZC_d/dt', source=stock, line_color='dodgerblue', line_dash='dotdash', alpha=0.8, muted_alpha=0.2, y_range_name="extra_y_axis") zc_a = p4.line(x='Date', y='ZC_d2/dt2', source=stock, line_color='tomato', line_dash='dotdash', alpha=0.8, muted_alpha=0.2, y_range_name="extra_y_axis") # slowk = p4.line(x='Date', y='slowk', source=stock, line_color='darkgreen', alpha=0.8, muted_alpha=0.2) # slowk_v = p4.line(x='Date', y='slowk_d/dt', source=stock, line_color='dodgerblue', line_dash='dotdash', alpha=0.8, muted_alpha=0.2, y_range_name="extra_y_axis") # slowk_a = p4.line(x='Date', y='slowk_d2/dt2', source=stock, line_color='tomato', line_dash='dotdash', alpha=0.8, muted_alpha=0.2, y_range_name="extra_y_axis") mid_box = BoxAnnotation(bottom=-0.5, top=0.5, fill_alpha=0.2, fill_color='blanchedalmond', line_color='grey', line_alpha=0.4, line_dash='dashed') zero = Span(location=0, dimension='width', line_color='seagreen', line_dash='solid', line_width=0.8) p4.add_layout(zero) p4.add_layout(mid_box) # p4.yaxis.axis_label = 'MACD v/acc' legend = Legend(items=[ LegendItem(label="ZC", renderers=[zc], index=0), LegendItem(label="ZC-v", renderers=[zc_v], index=1), LegendItem(label="ZC-a", renderers=[zc_a], index=2), # LegendItem(label="slowk", renderers=[slowk], index=0), # LegendItem(label="slowk-v", renderers=[slowk_v], index=1), # LegendItem(label="slowk-a", renderers=[slowk_a], index=2) ]) p4.add_layout(legend) p4.legend.location = "top_left" p4.legend.border_line_alpha = 0 p4.legend.background_fill_alpha = 0 p4.legend.click_policy = "mute" p4.legend.orientation = "horizontal" p4.x_range.range_padding = 0.05 p4.xaxis.ticker.desired_num_ticks = 40 p4.xaxis.major_label_orientation = 3.14 / 4 p4.toolbar.autohide = True p4.xgrid.grid_line_color = None p4.ygrid.grid_line_color = None addSpans([p1, p2, p3, p4]) columns = [ TableColumn(field="Date", title="Date", formatter=DateFormatter(format='%d.%b')), # TableColumn(field="Open", title="Open", formatter=NumberFormatter(format='0.00')), # TableColumn(field="Close", title="Close", formatter=NumberFormatter(format='0.00')), TableColumn(field="ZC", title="ZC", formatter=NumberFormatter(format='0.000', text_align='right')), TableColumn(field="ZC_d/dt", title="ZC-v", formatter=NumberFormatter(format='0.000', text_align='right')), TableColumn(field="macd_hist", title="MACD", formatter=NumberFormatter(format='0.000', text_align='right')), TableColumn(field="macd_d/dt", title="MACD-v", formatter=NumberFormatter(format='0.000', text_align='right')), # TableColumn(field="macd_d2/dt2", title="MACD-a", formatter=NumberFormatter(format='0.000')), TableColumn(field="stoch", title="STOCH", formatter=NumberFormatter(format='0.0', text_align='right')), TableColumn(field="stoch-v", title="STOCH-v", formatter=NumberFormatter(format='0.0', text_align='right')), # TableColumn(field="slowk_d/dt", title="slowk-v", formatter=NumberFormatter(format='0.000')), # TableColumn(field="slowk_d2/dt2", title="slowk-a", formatter=NumberFormatter(format='0.000')), ] data_table = DataTable(source=stock, columns=columns, width=int(W_PLOT / 3), height=int(H_PLOT * 2.2), index_position=None, width_policy='min') # ========================================================================== # =================== SELECT WIDGET ==================== # ========================================================================== callback_select_main = """ var d0 = s0.data; var symbol = cb_obj.value.split(" ")[0] var data_all = dataCollection[symbol] var data = data_all.data.data; /// Iterate over keys in new data and reassign old data with new data for (const key of Object.keys(data)) { d0[key] = [] d0[key] = data[key] } s0.change.emit() /// Update y-axes range plot.y_range.have_updated_interactively = true plot.y_range.start = 0.9 * Math.min(...data['Low']) plot.y_range.end = 1.1 * Math.max(...data['High']) plot.extra_y_ranges['vol_axis'].have_updated_interactively = true plot.extra_y_ranges['vol_axis'].start = 0 plot.extra_y_ranges['vol_axis'].end = Math.max(...data['Volume']) * 4 """ callback_select_va = """ var symbol = cb_obj.value.split(" ")[0] var data_all = dataCollection[symbol] var data = data_all.data.data; var y_limit = Math.max.apply(null, data[param_main].map(Math.abs)); var y_extra_limit = Math.max.apply(null, data[param_extra].map(Math.abs)); /// Update y-axes range plot.y_range.have_updated_interactively = true plot.y_range.start = -y_limit plot.y_range.end = y_limit plot.extra_y_ranges['extra_y_axis'].have_updated_interactively = true plot.extra_y_ranges['extra_y_axis'].start = -y_extra_limit plot.extra_y_ranges['extra_y_axis'].end = y_extra_limit """ selecthandler_main = CustomJS(args={ 's0': stock, 'dataCollection': dataCollection, 'plot': p1 }, code=callback_select_main) selecthandler_p3 = CustomJS(args={ 'dataCollection': dataCollection, 'plot': p3, 'param_main': 'macd_hist', 'param_extra': 'macd_d/dt' }, code=callback_select_va) selecthandler_p4 = CustomJS(args={ 'dataCollection': dataCollection, 'plot': p4, 'param_main': 'ZC', 'param_extra': 'ZC_d/dt' }, code=callback_select_va) # selecthandler_p4 = CustomJS(args={'dataCollection':dataCollection, 'plot':p4, 'param_main': 'slowk', 'param_extra': 'slowk_d/dt'}, code = callback_select_va) select = Select(title="Select:", value=keys[0], options=keys) select.js_on_change('value', selecthandler_main) select.js_on_change('value', selecthandler_p3) select.js_on_change('value', selecthandler_p4) # [cleanDate(x, stock.data) for x in [p1, p2, p3, p4]] # show the results gp1 = gridplot([select, data_table], ncols=1, plot_width=150, toolbar_options=dict(autohide=True)) gp2 = gridplot([p1, p2, p3, p4], ncols=1, sizing_mode='scale_width', toolbar_location='right') output_file(outputfilename + '.html') show(row(gp1, gp2)) # show(gp2) return True