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 __init__( self, model: DataModel, filter: typing.Optional[typing.Callable[[typing.Any], bool]] = None, ): # Note : typing.Any represent the type of the row tuple self.model = model # Note : views here should be "per-line" of data # Note : potentially a model is already a view (root of view tree... cf Ahman's Containers...) # For a "per-column" view -> model needs to be transformed (via a dataprocess) self.filter = filter # we always render ALL columns here. otherwise change your datamodel. self._table_columns = [ TableColumn(field=f, title=f, formatter=DateFormatter(format="%m/%d/%Y %H:%M:%S")) if pandas.api.types.is_datetime64_any_dtype(self.model.data.dtypes[i - 1]) else TableColumn(field=f, title=f) # CAREFUL with index for i, f in enumerate(self.model.columns) ] # TODO : some clever introspection of model to find most appropriate arguments... self._table_args = { "sortable": False, "reorderable": False, "index_position": None, } self._plot_args = dict()
def __graph_table(table): if table.shape[0] < 1: return Paragraph(text='No Exceptions Found', style={'color': 'blue'}) source = ColumnDataSource(table) columns = [] for name in table.columns.values: if pd.core.dtypes.common.is_datetime_or_timedelta_dtype(table[name]): columns.append( TableColumn(field=name, title=name, formatter=DateFormatter(format='%T'))) else: columns.append(TableColumn(field=name, title=name)) columns[-1].width = 1000 # if table.shape[0] >= 9: # height = 280 # else: # height = 30*table.shape[0] + 10 height = 280 data_table = DataTable(source=source, columns=columns, width=1000, height=height, fit_columns=True) return layouts.widgetbox(data_table, sizing_mode='fixed')
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 show_table(self): print("Showing table.") cube_copy = deepcopy(self.original_cube) for col in self.element.columns: cube_copy["ELEMENT_" + col] = self.element[col] source = ColumnDataSource(cube_copy) columns = [TableColumn(field=x, title=x) if "date" not in x else TableColumn(field=x, title=x, formatter=DateFormatter()) for x in cube_copy.columns] dt = DataTable(source=source, columns=columns, width=len(columns) * 150, height=800, editable=True) show(dt)
def table(self): date_fmt = DateFormatter(format="%Y-%m-%d") columns = [ TableColumn(field="Message", title="Message"), TableColumn(field="First", title="First", formatter=date_fmt), TableColumn(field="Last", title="Last", formatter=date_fmt), TableColumn(field="Count", title="Count"), ] table = DataTable(source=ColumnDataSource(self.data()), columns=columns) return table
def __init__(self): self.test = False self.url = "https://docs.google.com/spreadsheets/d/1vSPSRnhkG7lLRn74pKBqHwSKsVEKMLFnX1nT-ofKWQE/edit#gid=0" self.credentials = os.path.join(os.environ['OPSTOOL_DIR'], "google_access_account.json") self.creds = ServiceAccountCredentials.from_json_keyfile_name( self.credentials) self.client = gspread.authorize(self.creds) if self.test: self.df = pd.read_csv( os.path.join(os.environ['OPSTOOL_DIR'], 'obs_schedule_test.csv')) else: self.df = pd.read_csv( os.path.join(os.environ['OPSTOOL_DIR'], 'obs_schedule_official.csv')) self.df['Date'] = pd.to_datetime(self.df['Date'], format='%m/%d/%y') self.user_info = pd.read_csv( os.path.join(os.environ['OPSTOOL_DIR'], 'user_info.csv')) self.today = datetime.datetime.now().strftime('%Y-%m-%d') self.today_df = self.df[self.df.Date == self.today] self.today_source = ColumnDataSource(self.today_df) today_columns = [ TableColumn(field="Date", title='Date', formatter=DateFormatter()), TableColumn(field="LO_1", title='Lead Observer 1'), TableColumn(field="LO_2", title="Lead Observer 2"), TableColumn(field='OS_1', title='Observing Scientist 1'), TableColumn(field='OS_2', title='Observing Scientist 2'), TableColumn(field='DQS_1', title='Data Quality Scientist') ] self.data_table = DataTable(source=self.today_source, columns=today_columns, width=1000, height=100) all_names = [] for name in np.unique(self.df.OS_1): all_names.append(name.strip()) for name in np.unique(self.df.OS_2): all_names.append(name.strip()) for name in np.unique(self.df.DQS_1): all_names.append(name.strip()) all_names = np.unique(all_names) for name in all_names: emails = self.user_info[self.user_info['name'] == name]['email'] try: email = emails.values[0] except: print(name)
def __init__(self): self.test = True self.df = pd.read_csv('obs_schedule_official.csv') self.df['Date'] = pd.to_datetime(self.df['Date'], format='%m/%d/%y') self.user_info = pd.read_csv('user_info.csv') self.today = datetime.datetime.now().strftime('%Y-%m-%d') self.today_df = self.df[self.df.Date == self.today] self.day = self.today self.datefmt = DateFormatter(format="yyyy-mm-dd")
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 immunoematologici_tab(dataset: pd.DataFrame): src_table = ColumnDataSource(dataset) columns = [TableColumn(field=q, title=q) for q in dataset.columns.tolist() if q != 'Data Referto'] columns.append(TableColumn(field='Data Referto', title='Data Referto', formatter=DateFormatter())) table = DataTable(source=src_table, columns=columns, fit_columns=True, selectable=True, sortable=True, width=1000, height=100) layout = column(table) # Make a tab with the layout tab = Panel(child=layout, title='Esami Immunoematologici') return tab
def make_table(tbl_src): # columns = [TableColumn(field=col, title=col, formatter = DateFormatter(format="yy-m-d") if 'date' in col.lower() else None) for col in list(tbl_src.data.keys())] columns = [ TableColumn(field=col, title=col, formatter=DateFormatter(format="%Y-%m-%d")) if 'date' in col.lower() else TableColumn(field=col, title=col) for col in list(tbl_src.data.keys())[1:] ] data_table = DataTable(source=tbl_src, columns=columns, editable=True, width=600, height=600) return data_table
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
#### Mapplot tools_to_show_p1 = 'box_zoom,pan,save,hover,reset,tap,wheel_zoom' p1 = figure(x_range=(1043319, 1471393), y_range=(5684768, 6176606), plot_width=600, plot_height=600, x_axis_type="mercator", y_axis_type="mercator", tools=tools_to_show_p1)#, sizing_mode="scale_both") p1.add_tile(tile_provider) hover1 = p1.select(dict(type=HoverTool)) hover1.tooltips = [("Stationsname", "@Stationsname"), ("Stationsmessort", "@Stationsmessort"), ("Parametername", "@Parametername")] hover1.mode = 'mouse' p1.circle(x="x", y="y", size=15, fill_color="blue", fill_alpha=0.4, source=df) #### Initiate source for plots and table source = ColumnDataSource(data=dict(index=['1970-01-01 00:00'], XX=['NaN'])) # Initialize empty source for table and plot #### Datatable datefmt = DateFormatter(format="%Y-%m-%d %H:%M") columns = [ TableColumn(field="index", title="date", formatter=datefmt),#, editor=DateEditor), TableColumn(field=parameter, title=parameter), ] old_source = copy.deepcopy(source) data_table = DataTable(source=source, columns=columns, width=400, height=600, fit_columns=True, editable=True) #### Valueplot tools_to_show_p2 = 'box_zoom,pan,save,reset,wheel_zoom' p2 = figure(tools=tools_to_show_p2, x_axis_type='datetime') p2.xaxis.formatter=DatetimeTickFormatter( hours=["%d %B %Y"], days=["%d %B %Y"],
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
def modify_document(self, doc): self.tb.lock() sink = bokehgui.vec_sink_f_proc(self.tb.get_num_channels(), "", 1) self.tb.connect((self.mag_to_zW, 0), (sink, 0)) self.tb.unlock() log_cds = ColumnDataSource(data=self.lw.get_table()) blw = BokehLogWatcher(doc, log_cds) logging.getLogger().addHandler(blw) def cleanup_session(session_context): self.tb.lock() self.tb.disconnect((self.mag_to_zW, 0), (sink, 0)) self.tb.unlock() logging.getLogger().removeHandler(blw) doc.on_session_destroyed(cleanup_session) doc.title = "Gal Scan GUI" plot_lst = [] plot = vec_sink_f(doc, plot_lst, sink, is_message=False) plot.initialize(update_time=100, legend_list=['']) plot.get_figure().aspect_ratio = 2 plot.set_y_axis([0, 10]) plot.set_y_label("Power at feed (zW / Hz)") plot.set_x_label("Frequency (MHz)") def set_x_values(): plot.set_x_values( np.linspace( self.tb.get_sdr_frequency() - (self.tb.get_output_vector_bandwidth() / 2), self.tb.get_sdr_frequency() + (self.tb.get_output_vector_bandwidth() / 2), self.tb.get_num_channels()) / 1e6) set_x_values() plot.enable_axis_labels(True) plot.set_layout(1, 0) plot.enable_max_hold() plot.format_line(0, "blue", 1, "solid", None, 1.0) azimuth = Knob(title="Azimuth", max=360, min=0, unit="°") elevation = Knob(title="Elevation", max=360, min=0, unit="°") rx_power = Knob(title="Average RX Power", digits=4, decimals=1, unit="dB(mW/Hz)") plot.stream.js_on_change( "streaming", CustomJS( args=dict(rx_power=rx_power), code=""" const data = cb_obj.data const average = data['y0'].reduce((a,b) => a+b)/data['y0'].length rx_power.value = (10*Math.log10(average))-180 """, )) log_table = SortedDataTable( source=log_cds, columns=[ TableColumn(field="asctime", title="Time", width=140), TableColumn(field="levelname", title="Level", width=60), TableColumn(field="message", title="Message", width=1500), ], autosize_mode="none", aspect_ratio=2, sizing_mode="stretch_width", sortable=True, ) gain = Slider(title="gain", value=self.tb.get_sdr_gain(), start=0, end=65) gain.on_change('value', lambda name, old, new: self.set_gain(new)) rx = ActiveButton(label="RX enabled") rx.on_click(lambda: self.set_rx(not rx.active)) frequency = Knob(title="center frequency", writable=True, value=self.tb.get_sdr_frequency(), digits=10, decimals=0, unit="Hz") frequency.on_change('value', lambda name, old, new: self.set_frequency(new)) bandwidth = Knob(title="filter bandwidth", writable=False, value=self.tb.get_bandwidth(), digits=7, decimals=0, unit="Hz") bandwidth.on_change('value', lambda name, old, new: self.set_bandwidth(new)) reset = Button(label="Reset") def on_reset(): gain.value = run.flowgraph_defaults['sdr_gain'] frequency.value = run.flowgraph_defaults['sdr_frequency'] bandwidth.value = run.flowgraph_defaults['bandwidth'] reset.on_click(on_reset) manual = Panel(title="Manual", child=column( row(rx, gain), row(frequency, bandwidth), reset, )) run_models = {} automated_panels = [] for group, args in run.arg_groups.items(): # TODO: show grouping panel_models = [] for key, arg in args.items(): key = key.replace('-', '_') bokeh_args = arg.get('bokeh', {}) bokeh_args['name'] = key bokeh_args['tags'] = ['args'] if 'default' in arg: bokeh_args['value'] = arg['default'] if 'help' in arg: bokeh_args['title'] = arg['help'] if 'metavar' in arg: bokeh_args['title'] += " (%s)" % (arg['metavar']) type = TextInput if arg.get('type') in (float, int): type = Spinner if 'bokeh' in arg and 'start' in arg[ 'bokeh'] and 'end' in arg['bokeh']: type = Slider if 'step' not in bokeh_args: if arg['type'] == int: bokeh_args['step'] = 1 else: bokeh_args['step'] = 0.01 if arg.get('metavar') == 'Hz': if 'digits' not in bokeh_args: bokeh_args['digits'] = 10 if bokeh_args.get('max'): bokeh_args['digits'] = len("%d" % bokeh_args['max']) type = functools.partial(Knob, decimals=0, unit=arg['metavar']) del bokeh_args['step'] del bokeh_args['tags'] if 'writable' not in bokeh_args: bokeh_args['writable'] = True elif 'choices' in arg: type = Select bokeh_args['options'] = [str(x) for x in arg['choices']] if 'value' in bokeh_args: bokeh_args['value'] = str(bokeh_args['value']) elif arg.get('action') in ('store_true', 'store_false'): type = Select bokeh_args['options'] = [('0', 'False'), ('1', 'True')] bokeh_args['value'] = str(int(bokeh_args['value'])) bokeh_args['tags'] = ['boolean'] + bokeh_args.get( 'tags', []) if group.startswith("mode="): # Make this smarter if we ever have a mode=gal tab bokeh_args['disabled'] = True m = type(**bokeh_args) run_models[key] = m panel_models.append(m) automated_panels.append( Panel(title=group, child=grid(panel_models, ncols=2))) for panel in automated_panels: if panel.title.startswith("mode="): mode_str = panel.title.split('=')[1] run_models['mode'].js_on_change( 'value', CustomJS( args=dict(panel=panel, mode=mode_str), code= """panel.select(Bokeh.require("models/widgets/control").Control).forEach(c => c.disabled = (this.value != mode))""", )) plan_p = Paragraph(sizing_mode="stretch_width", ) load = UploadButton(name="load-settings", accept=".json,application/json", label="Load settings") def on_load(attr, old, new): data = json.loads(base64.b64decode(new)) for key, value in data.items(): if isinstance(run_models[key], Select): value = str(value) run_models[key].value = value load.on_change('value', on_load) save = DownloadButton(label="Save settings", filename="gal_scan_settings.json", mime_type="application/json", data=CustomJS(args=dict(run_models=run_models), code=""" const out = {} for (let k in run_models) { if (!run_models[k].disabled) { out[k] = run_models[k].value const tags = run_models[k].tags if (tags && tags.indexOf("boolean") >= 0) { out[k] = parseInt(out[k]) } } } return JSON.stringify(out, null, 2); """)) start = Button(label="Start scan") def get_args(output_dir): return run.parse_args( [output_dir], { k: int(v.value) if "boolean" in v.tags else v.value for k, v in run_models.items() if not v.disabled }, ) def on_start(): try: output_dir = os.path.join( self.runs_dir, "run_" + datetime.datetime.now().replace(microsecond=0).isoformat()) args = get_args(output_dir) self.enqueue_run(args) except SystemExit: pass start.on_click(on_start) automated = Panel(title="Plan", child=column(Tabs(tabs=automated_panels), plan_p, row(load, save, start))) # TODO: Show cancel buttons for active or queued actions queue_cds = ColumnDataSource(data=self.get_queue_data()) action_column = ActionMenuColumn( field="id", title="Action", menu=[ ("Cancel", "cancel"), ], ) def on_action_menu_click(event): if event.item == "cancel": self.cancel_action(event.value) else: logging.warn("Unknown action clicked: %s", event.item) action_column.on_event(ActionMenuClick, on_action_menu_click) queue_table = SortedDataTable( source=queue_cds, columns=[ TableColumn( field="time", title="Time", formatter=DateFormatter(format="%Y-%m-%d %H:%M:%S"), ), TableColumn(field="user", title="User"), TableColumn(field="name", title="Job"), action_column, ], highlight_field="active", sort_ascending=True, autosize_mode="fit_viewport", aspect_ratio=2, sizing_mode="stretch_width", ) queue = Panel(title="Queue", child=queue_table) results_cds = ColumnDataSource(data={"name": [], "mtime": []}) results_table = SortedDataTable( source=results_cds, columns=[ TableColumn( field="mtime", title="Time", formatter=DateFormatter(format="%Y-%m-%d %H:%M:%S"), ), TableColumn( field="name", title="Name", formatter=HTMLTemplateFormatter( template= '<a href="/runs/<%= value %>/" target="_blank"><%= value %></a>' )), ], autosize_mode="fit_viewport", aspect_ratio=2, sizing_mode="stretch_width", sortable=True, ) results = Panel(title="Results", child=results_table) tabs = Tabs(tabs=[manual, automated, queue, results]) status_p = Paragraph(sizing_mode="stretch_width", ) controls = column(row(azimuth, elevation, rx_power), status_p, tabs, log_table) def get_survey_data(): pointers = { 'ra': [], 'dec': [], 'label': [], 'colour': [], } for o in self.messier: pointers['ra'].append(o['ra']) pointers['dec'].append(o['dec']) pointers['label'].append(o['label']) pointers['colour'].append('') survey = self.active_action.get('survey') out = { 'pointers': pointers, 'status_message': 'Idle', 'plan_message': 'Invalid parameters' } if survey: groups = survey.coord_groups i = 0 for sc, colour in zip(reversed(groups), ('rgb(0, 192, 0)', 'rgb(192, 0, 0)')): sc = sc.icrs for sc in sc: pointers['ra'].append(sc.ra.to(u.degree).value) pointers['dec'].append(sc.dec.to(u.degree).value) pointers['label'].append(str(i + 1)) pointers['colour'].append(colour) i += 1 out['status_message'] = 'Time remaining on current survey: %s' % ( survey.time_remaining.to_datetime()) survey = None try: survey = run.Survey(get_args('bogus')) out['plan_message'] = 'Estimated runtime: %s' % ( survey.time_remaining.to_datetime()) if tabs.tabs[tabs.active] == automated: # TODO: Use the underlying numpy arrays sc = survey.iterator.coords_now.icrs for i, sc in enumerate(sc[:1000]): pointers['ra'].append(sc.ra.to(u.degree).value) pointers['dec'].append(sc.dec.to(u.degree).value) pointers['label'].append(str(i + 1)) pointers['colour'].append('rgb(148,0,211)') except: logging.getLogger('stderr').exception('Invalid parameters') return out sd = get_survey_data() pointers_cds = ColumnDataSource(data=sd['pointers']) def update_pointers(attr, old, new): logging.debug('Updating pointers') sd = get_survey_data() pointers_cds.data = sd['pointers'] plan_p.text = sd['plan_message'] status_p.text = sd['status_message'] update_pointers(None, None, None) log_cds.on_change('data', update_pointers) tabs.on_change('active', update_pointers) for m in run_models.values(): m.on_change('value', update_pointers) skymap = Skymap( height=600, sizing_mode="stretch_height", pointer_data_source=pointers_cds, ) skymap.on_event(Tap, lambda event: self.point(event.x, event.y)) doc.add_root(row( column( skymap, plot.get_figure(), ), controls, ), ) async def update_status(last_status={}): set_x_values() status = self.client.status skymap.latlon = (status['Latitude'], status['Longitude']) skymap.azel = (status['AzPos'], status['ElPos']) if status['CommandAzFlags'] == 'POSITION' or status[ 'CommandElFlags'] == 'POSITION': skymap.targetAzel = (status['CommandAzPos'], status['CommandElPos']) else: skymap.targetAzel = None azimuth.value = status['AzPos'] elevation.value = status['ElPos'] rx_active = status['Sequencer']['Bands'][0]['CommandRX'] if not last_status or rx_active != last_status['Sequencer'][ 'Bands'][0]['CommandRX']: if rx_active: rx.label = "RX enabled" else: rx.label = "RX disabled (50Ω load)" rx.active = rx_active queue_data = self.get_queue_data() if queue_cds.data != queue_data: queue_cds.data = queue_data with os.scandir(self.runs_dir) as it: files = list( sorted(it, reverse=True, key=lambda f: f.stat().st_mtime)) results_data = { "name": [f.name for f in files], "mtime": [int(f.stat().st_mtime * 1000) for f in files], } if results_data != results_cds.data: results_cds.data = results_data last_status.update(status) doc.add_periodic_callback(update_status, 200)
trainings_todo = [training_generator('forth') for i in range(5)] data_forth = {'title': [], 'start' : [], 'end' : []} for train in trainings_todo : data_forth['title'].append(train.certification) data_forth['start'].append(train.start) data_forth['end'].append(train.end) trainings_done = [training_generator('back') for i in range(5)] data_back = {'title': [], 'start' : [], 'end' : []} for train in trainings_done : data_back['title'].append(train.certification) data_back['start'].append(train.start) data_back['end'].append(train.end) table_forth_source = ColumnDataSource(data_forth) table_back_source = ColumnDataSource(data_back) columns = [ TableColumn(field="title", title="Certification"), TableColumn(field="start", title="Date", formatter=DateFormatter()), ] forth_table = DataTable(source=table_forth_source, columns=columns, width=400, height=280) back_table = DataTable(source=table_back_source, columns=columns, width=400, height=280) show(gridplot([p_training_kpi,forth_table],[p_indicators, back_table],merge_tools=False))
def layout(self): self.report = PreText(text=' ') info = Div(text=' ') title = Div(text='Operations Schedule Viewer', css_classes=['h1-title-style'], width=800) self.date_title = Div(text='DESI Operations Schedule for {}'.format( self.day), css_classes=['h1-title-style'], width=800) self.obs_comment = Div(text='', css_classes=['obs-comment']) self.lo_1 = Div(text='Lead Obs. 1', css_classes=['lo-style'], width=400) self.lo_2 = Div(text='Lead Obs. 2', css_classes=['lo-style'], width=400) self.lo_head = Div(text='LO: ', css_classes=['lo-style'], width=75) self.os_1 = Div(text='Obs. Scientist 1', css_classes=['os-style'], width=400) self.os_2 = Div(text='Obs. Scientist 2', css_classes=['os-style'], width=400) self.os_head = Div(text='OS: ', css_classes=['os-style'], width=75) self.dqs_1 = Div(text='Data QA Scientist 1 ', css_classes=['dqs-style'], width=400) self.dqs_2 = Div(text='Data QA Scientist 2', css_classes=['dqs-style'], width=400) self.dqs_head = Div(text='DQS: ', css_classes=['dqs-style'], width=75) self.oa = Div(text='Observing Associate', css_classes=['oa-style'], width=400) self.oa_head = Div(text="OA: ", css_classes=['oa-style'], width=75) self.em = Div(text='Electronic Mainetenance', css_classes=['em-style'], width=400) self.em_head = Div(text='EM: ', css_classes=['em-style'], width=75) self.buffer = Div(text='') self.date_before = Button(label='Previous Date', css_classes=['next_button'], width=200) self.date_after = Button(label='Next Date', css_classes=['next_button'], width=200) self.enter_date = TextInput(placeholder='YYYY-MM-DD', width=200) self.date_btn = Button(label='Enter date', width=200, css_classes=['change_button']) main_layout = layout([ self.date_title, self.obs_comment, [self.lo_head, self.lo_1, self.lo_2], [self.os_head, self.os_1, self.os_2], [self.dqs_head, self.dqs_1, self.dqs_2], [self.oa_head, self.oa], [self.em_head, self.em], self.buffer, [self.date_before, self.date_after], [self.enter_date, self.date_btn] ]) main_tab = Panel(child=main_layout, title='Main') self.sched_source = ColumnDataSource(self.df) sched_columns = [ TableColumn(field='Day', title='Day', width=10), TableColumn(field='Date', title='Date', width=75, formatter=DateFormatter()), TableColumn(field='Comments', title='Comment', width=150), TableColumn(field='LO_1', title='LO 1', width=150), TableColumn(field='LO_2', title='LO 2', width=150), TableColumn(field='OS_1', title='OS 1', width=150), TableColumn(field='OS_2', title='OS 2', width=150), TableColumn(field='DQS_1', title='DQS 1', width=150), TableColumn(field='DQS_2', title='DQS 2', width=150), TableColumn(field='OA', title='OA', width=150), TableColumn(field='EM', title='EM', width=150) ] #, self.sched_table = DataTable(source=self.sched_source, columns=sched_columns, width=1200, height=2000, fit_columns=False) sched_layout = layout([title, self.sched_table]) sched_tab = Panel(child=sched_layout, title='Schedule') #highlight current row #only show one row previously self.layout = Tabs(tabs=[main_tab, sched_tab])
def set_up_widgets(p, source, source1, source2, source3, source4, source5, df, all_dates, text_dsn): '''Set up widgets needed after an initial dsn is entered''' dsn = text_dsn.value # Set up widgets text_title = TextInput(title="Title:", value="{} Data".format(dsn)) text_save = TextInput(title="Save As:", value=dsn) max_for_dsn = df.timestamp.max() min_day = date_of_file( all_dates[0]) # works if sorted, needs to be formatted... max_day = date_of_file(all_dates[-1]) plus_one = max_for_dsn + timedelta(days=1) calendar = DatePicker(title="Day:", value=date(plus_one.year, plus_one.month, plus_one.day), max_date=max_day, min_date=min_day) button = Button(label="Update", button_type="success") columns = [ TableColumn(field="day", title="Date", formatter=DateFormatter(format="%m/%d/%Y")), TableColumn(field="hr", title="Avg HR", formatter=NumberFormatter(format="0.0")), TableColumn(field="o2", title="Avg O2", formatter=NumberFormatter(format="0.0")), TableColumn(field="temp", title="Avg Temp", formatter=NumberFormatter(format="0.0")) ] # table_title = Div(text="""Daily Averages:""", width=200) # daily_avg = get_daily_avgs(df_full) # data = { # 'day' : daily_avg.index, # 'hr' : daily_avg.heart_rate_avg, # 'o2' : daily_avg.oxygen_avg, # 'temp' : daily_avg.skin_temperature # } # table_source = ColumnDataSource(data=data) # data_table = DataTable(source=table_source, columns=columns, width=280, height=180, index_position=None) # export_png(data_table, filename="table.png") # save_table = Button(label='Save Daily Averages Table', button_type="primary") # Set up callbacks def update_title(attrname, old, new): p.title.text = text_title.value def update_save(attrname, old, new): p.tools[0].save_name = text_save.value def update(): text_dsn.value = text_dsn.value.strip(" ") # Get rid of extra space # Make sure time is valid update_data(p, source, source1, source2, source3, source4, source5, df, text_dsn.value, all_dates, date=str(calendar.value)) # Title/save update dsn text_title.value = text_dsn.value + " Data" text_save.value = text_dsn.value def save(): export_png(data_table, filename="{}_averages.png".format(text_dsn.value)) text_title.on_change('value', update_title) text_save.on_change('value', update_save) button.on_click(update) button.js_on_click(CustomJS(args=dict(p=p), code="""p.reset.emit()""")) # save_table.on_click(save) # Set up layouts and add to document inputs = widgetbox(text_title, text_save, calendar, button) #, table_title, data_table, save_table) curdoc().add_root(row(inputs, p, width=1300))
def set_up_widgets(p, source, source1, source2, source3, source4, source5, df, all_dates, text_dsn): '''Set up widgets needed after an initial dsn is entered''' dsn = text_dsn.value # Set up widgets text_title = TextInput(title="Title:", value="{} Data".format(dsn)) text_save = TextInput(title="Save As:", value=dsn) min_day = date_of_file(all_dates[0]) max_day = date_of_file(all_dates[-1]) plus_one = max_day + timedelta(days=1) calendar = DatePicker(title="Day:", value=date(plus_one.year, plus_one.month, plus_one.day), max_date=max_day, min_date=min_day) button = Button(label="Update", button_type="success") columns = [ TableColumn(field="day", title="Date", formatter=DateFormatter(format="%m/%d/%Y")), TableColumn(field="hr", title="Avg HR", formatter=NumberFormatter(format="0.0")), TableColumn(field="o2", title="Avg O2", formatter=NumberFormatter(format="0.0")), TableColumn(field="temp", title="Avg Temp", formatter=NumberFormatter(format="0.0")) ] # Set up callbacks def update_title(attrname, old, new): p.title.text = text_title.value def update_save(attrname, old, new): p.tools[0].save_name = text_save.value def update(): text_dsn.value = text_dsn.value.strip(" ") # Get rid of extra space update_data(p, source, source1, source2, source3, source4, source5, df, text_dsn.value, all_dates, date=str(calendar.value)) # Title/save update dsn text_title.value = text_dsn.value + " Data" text_save.value = text_dsn.value text_title.on_change('value', update_title) text_save.on_change('value', update_save) button.on_click(update) # Set up layouts and add to document inputs = widgetbox(text_title, text_save, calendar, button) curdoc().add_root(row(inputs, p, width=1300))
def output_training_dashboard(cert_report_dict): kpis = get_kpis(cert_report_dict) kpi_names = ['%T', '%(U-Y-X)'] print(kpis) kpi_data = { 'kpi': kpis, 'y': [1, 2], 'txt_kpi': [k + 0.03 for k in kpis], 'txt_y': kpi_names, 'txt_format': [str(k * 100) + ' %' for k in kpis] } kpi_source = ColumnDataSource(kpi_data) # ---------------- MAIN KPI VIEW ---------------- p_training_kpi = figure(plot_height=250, plot_width=250, title="Max T%") p_training_kpi.title.align = 'center' p_training_kpi.annular_wedge(x=0, y=0, inner_radius=0.5, outer_radius=0.6, start_angle=-2 * pi * kpis[0], end_angle=0, color="green", alpha=0.6) citation = Label(x=0, y=-0.1, text=str(kpis[0] * 100) + ' %', render_mode='css', text_font_size='20pt', text_align='center') p_training_kpi.add_layout(citation) dashboardize(p_training_kpi) # ---------------- INDIVIDUAL KPI VIEW ---------------- p_indicators = figure(plot_height=250, plot_width=250, x_range=[0, 1.3], y_range=kpi_names) p_indicators.hbar(y='y', height=0.5, left=0, right='kpi', fill_alpha=0.6, source=kpi_source) p_indicators.circle(x='kpi', y='y', name='tip', alpha=0, hover_alpha=1, source=kpi_source) text_glyph = Text(x='txt_kpi', y="txt_y", text='txt_format') p_indicators.add_glyph(kpi_source, text_glyph) hover = HoverTool(tooltips=[('Value %', '@kpi')], mode='hline', names=['tip']) p_indicators.add_tools(hover) dashboardize(p_indicators) p_indicators.yaxis.visible = True # ---------------- TRAINING TO DO VIEW ---------------- temp = [(k, v) for k, v in cert_report_dict['requiredcertifications'].items()] data_forth = {'title': [], 'date': []} data_forth['title'] = [v[0] for v in temp] data_forth['date'] = [v[1] for v in temp] temp = cert_report_dict['certifications'].items() data_back = {'title': [], 'date': []} data_back['title'] = [v[0] for v in temp] data_back['date'] = [v[1] for v in temp] table_forth_source = ColumnDataSource(data_forth) table_back_source = ColumnDataSource(data_back) columns = [ TableColumn(field="title", title="Certification"), TableColumn(field="date", title="Date", formatter=DateFormatter()), ] forth_table = DataTable(source=table_forth_source, columns=columns, width=400, height=280) back_table = DataTable(source=table_back_source, columns=columns, width=400, height=280) show( gridplot([p_training_kpi, forth_table], [p_indicators, back_table], merge_tools=False))
def formatter(acol): value = ACOLS[acol] if acol == "Date": return DateFormatter() return NumberFormatter(format=value)
p.circle( x='man_date', y='system_qty', # size='system_size', size=20, alpha=0.7, line_width=2, fill_color='fill_mapper', line_color='line_mapper', hover_color='grey', hover_alpha=0.5, # legend_field='status', source=source, ) date_format = DateFormatter(format='%Y-%m-%d') columns = [ TableColumn(field='batch', title='Batch'), TableColumn(field='system_qty', title='System Qty'), TableColumn(field='reserved_qty', title='Reserved Qty'), TableColumn(field='avail', title='Available Qty'), TableColumn(field='man_date', title='Manufacturing Date', formatter=date_format), TableColumn(field='bdc', title='BDC'), TableColumn(field='sales', title='Sales Number') ] data_table = DataTable(source=source, columns=columns, index_position=None,
def layout(self): self.report = PreText(text=' ') info = Div(text=' ') title = Div(text='Operations Planning Tool', css_classes=['h1-title-style']) today_title = Div(text="Today's Observers: ") night_report_title = Div(text='Daily Report: ', css_classes=['title-style']) self.enter_date = TextInput(title='Date', placeholder='YYYY-MM-DD', width=200) self.date_btn = Button(label='Change date', width=200, css_classes=['change_button']) self.email_all_btn = Button(label='Make all emails', width=200, css_classes=['change_button']) self.update_df_btn = Button(label='Update DataFrame', width=200, css_classes=['next_button']) self.one_month_email = TextInput(title='Email: ', placeholder='Serena Williams', width=200) self.one_month_title = Div(text='One Month: ', css_classes=['title-style']) self.one_month_name = TextInput(title='Name: ', placeholder='Serena Williams', width=200) self.one_month_btn = Button(label="Email One Month Info", width=200, css_classes=['next_button']) self.one_month_start = TextInput(title='Date Start: ', placeholder='Month DD, YYYY', width=200) self.two_weeks_email = TextInput(title='Email: ', placeholder='Lindsay Vonn', width=200) self.two_weeks_title = Div(text='Two Weeks: ', css_classes=['title-style']) self.two_weeks_name = TextInput(title='Name: ', placeholder='Lindsay Vonn', width=200) self.two_weeks_btn = Button(label="Email Two Weeks Info", width=200, css_classes=['next_button']) self.two_weeks_start = TextInput(title='Date Start: ', placeholder='Month DD, YYYY', width=200) self.two_weeks_select = RadioButtonGroup(labels=['OS', 'DQS'], active=0) self.night_before_email = TextInput(title='Email: ', placeholder='Mia Hamm', width=200) self.night_before_title = Div(text='Night/Weekend Before : ', css_classes=['title-style']) self.night_before_name = TextInput(title='Name: ', placeholder='Mia Hamm', width=200) self.night_before_btn = Button(label="Email Night Before Info", width=200, css_classes=['next_button']) self.weekend_select = RadioButtonGroup(labels=['Tomorrow', 'Weekend'], active=0) self.follow_up_email = TextInput(title='Email: ', placeholder='Danica Patrick', width=200) self.follow_up_name = TextInput(title='Name: ', placeholder='Danica Patrick', width=200) self.follow_up_title = Div(text='Follow Up: ', css_classes=['title-style']) self.follow_up_btn = Button(label="Email Follow Up", width=200, css_classes=['next_button']) main_layout = layout([ title, today_title, self.data_table, [self.enter_date, self.date_btn], night_report_title, self.report, self.email_all_btn, [[ self.one_month_title, self.one_month_name, self.one_month_email, self.one_month_start, self.one_month_btn ], [ self.two_weeks_title, self.two_weeks_name, self.two_weeks_email, self.two_weeks_select, self.two_weeks_start, self.two_weeks_btn ], [ self.night_before_title, self.night_before_name, self.weekend_select, self.night_before_email, self.night_before_btn ], [ self.follow_up_title, self.follow_up_name, self.follow_up_email, self.follow_up_btn ]] ]) main_tab = Panel(child=main_layout, title='Main') self.sched_source = ColumnDataSource(self.df) sched_columns = [ TableColumn(field='Day', title='Day', width=10), TableColumn(field='Date', title='Time', width=50, formatter=DateFormatter()), TableColumn(field='Comments', title='Comment', width=150), TableColumn(field='LO_1', title='Lead Obs. 1', width=75), TableColumn(field='LO_2', title='Lead Obs. 2', width=75), TableColumn(field='OS_1', title='Obs. Sci 1', width=75), TableColumn(field='OS_2', title='Obs. Sci 1', width=75), TableColumn(field='DQS_1', title='Data QA Sci.', width=75) ] #, self.sched_table = DataTable(source=self.sched_source, columns=sched_columns, width=1000, height=500) sched_layout = layout([title, self.sched_table]) sched_tab = Panel(child=sched_layout, title='Schedule') self.layout = Tabs(tabs=[main_tab, sched_tab])
def table(self): columns = [ TableColumn( field="unit_id", title="Unit ID", width=60, ), TableColumn( field="camera_id", title="Camera ID", width=60, ), TableColumn( field="time", title="Time [UTC]", formatter=DateFormatter(format='%Y-%m-%d %H:%M'), width=130, ), TableColumn( field="field_name", title="Field Name", width=240, ), TableColumn( field="ra", title="RA [deg]", formatter=NumberFormatter(format="0.000"), width=70, ), TableColumn( field="dec", title="Dec [deg]", formatter=NumberFormatter(format="0.000"), width=70, ), TableColumn( field="num_images", title="Images", width=40, ), TableColumn( field="status", title="Status", width=75, ), TableColumn( field="exptime", title="Exptime [sec]", formatter=NumberFormatter(format="0.00"), width=60, ), TableColumn( field="total_minutes_exptime", title="Total Minutes", formatter=NumberFormatter(format="0.0"), width=60, ), ] cds = self.update_dataset() data_table = DataTable( source=cds, name='observations_table', columns=columns, index_position=None, min_width=1100, fit_columns=True, sizing_mode='stretch_both', ) return data_table
from datetime import date from random import randint from bokeh.io import show from bokeh.models import ColumnDataSource, DataTable, DateFormatter, TableColumn data = dict( dates=[date(2014, 3, i + 1) for i in range(10)], downloads=[randint(0, 100) for i in range(10)], ) source = ColumnDataSource(data) columns = [ TableColumn(field="dates", title="Date", formatter=DateFormatter()), TableColumn(field="downloads", title="Downloads"), ] data_table = DataTable(source=source, columns=columns, width=400, height=280) show(data_table)
def create_panels(files, names): tab_list = [] for i in range(len(files)): df = pd.read_csv('reports/{}'.format(files[i])) col1 = df.columns[0] col2 = df.columns[1] if col1 == 'date': df['date'] = pd.to_datetime(df['date']) # create a new plot with a datetime axis type p = figure(width=800, height=350, x_axis_type="datetime") # create 30 day rolling average if plotting dates window_size = 30 window = np.ones(window_size)/float(window_size) avg = np.convolve(df[col2], window, 'same') source = ColumnDataSource(df) #add renderers p.line(source.data[col1], avg, color='navy', legend='avg') p.circle(source.data[col1], source.data[col2], size=4, color='darkgrey', alpha=0.2, legend='{}'.format(names[i])) p.title.text = "One-Month Average of {}".format(names[i]) else: p = figure(width=800, height=350) source = ColumnDataSource(df) #add renderers p.line(source.data[col1], source.data[col2], line_width=2) p.circle(source.data[col1], source.data[col2], fill_color="white", size=8) p.title.text = "Count of {}".format(names[i]) # NEW: customize by setting attributes p.legend.location = "top_left" p.grid.grid_line_alpha=0 p.xaxis.axis_label = '{}'.format(col1) p.yaxis.axis_label = '{}'.format(names[i]) p.ygrid.band_fill_color="olive" p.ygrid.band_fill_alpha = 0.1 columns = [ TableColumn(field=c, title=c, formatter=DateFormatter(format='m/d/yy') if np.issubdtype(df[c].dtype, np.datetime64) else None) for c in df.columns ] data_table = DataTable(source=source, columns=columns, width=400, height=280) div = Div(text="""<h2>Quick Info:</h2> <ul> <li>Number of observations: {}</li> <li>Max: {}</li> <li>Min: {}</li> </ul> """.format(df.shape[0], df[col2].max(), df[col2].min()), width=400, height=100) info = row(data_table, div) tab_list.append(Panel(child= column(p, info), title=names[i])) return tab_list
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 __init__(self, type): self.test = False self.report_type = type self.utc = TimezoneInfo() self.kp_zone = TimezoneInfo(utc_offset=-7*u.hour) self.zones = [self.utc, self.kp_zone] self.datefmt = DateFormatter(format="%m/%d/%Y %H:%M:%S") self.inst_style = {'font-size':'150%'} self.subt_style = {'font-size':'200%','font-style':'bold'} self.title_style = {'font-size':'250%','font-style':'bold'} self.alert_style = {'font-size':'150%','color':'red'} self.nl_file = None self.intro_subtitle = Div(text="Connect to Night Log",css_classes=['subt-style']) self.time_note = Div(text="<b> Note: </b> Enter all times as HHMM (1818 = 18:18 = 6:18pm) in Kitt Peak local time. Either enter the time or hit the <b> Now </b> button if it just occured.", css_classes=['inst-style']) hostname = socket.gethostname() ip_address = socket.gethostbyname(hostname) if 'desi' in hostname: self.location = 'kpno' #self.conn = psycopg2.connect(host="desi-db", port="5442", database="desi_dev", user="******", password="******") elif 'app' in hostname: #this is not true. Needs to change. self.location = 'nersc' else: self.location = 'other' nw_dirs = {'nersc':'/global/cfs/cdirs/desi/spectro/nightwatch/nersc/', 'kpno':'/exposures/nightwatch/', 'other':None} self.nw_dir = nw_dirs[self.location] self.nl_dir = os.environ['NL_DIR'] self.your_name = TextInput(title ='Your Name', placeholder = 'John Smith') self.os_name_1 = TextInput(title ='Observing Scientist 1', placeholder = 'Ruth Bader Ginsberg') self.os_name_2 = TextInput(title ='Observing Scientist 2', placeholder = "Sandra Day O'Connor") self.lo_names = ['None ','Liz Buckley-Geer','Ann Elliott','Parker Fagrelius','Satya Gontcho A Gontcho','James Lasker','Martin Landriau','Claire Poppett','Michael Schubnell','Luke Tyas','Other '] self.oa_names = ['None ','Karen Butler','Amy Robertson','Anthony Paat','Dave Summers','Doug Williams','Other '] self.intro_txt = Div(text=' ') self.comment_txt = Div(text=" ", css_classes=['inst-style'], width=1000) self.date_init = Select(title="Existing Night Logs") self.time_title = Paragraph(text='Time* (Kitt Peak local time)', align='center') self.now_btn = Button(label='Now', css_classes=['now_button'], width=50) days = [d for d in os.listdir(self.nl_dir) if os.path.isdir(os.path.join(self.nl_dir, d))] init_nl_list = np.sort([day for day in days if 'nightlog_meta.json' in os.listdir(os.path.join(self.nl_dir,day))])[::-1][0:10] self.date_init.options = list(init_nl_list) self.date_init.value = init_nl_list[0] self.connect_txt = Div(text=' ', css_classes=['alert-style']) self.connect_bt = Button(label="Connect to Existing Night Log", css_classes=['connect_button']) self.exp_info = Div(text="Fill In Only Relevant Data. Mandatory fields have an asterisk*.", css_classes=['inst-style'],width=500) self.exp_comment = TextAreaInput(title ='Comment/Remark', placeholder = 'Humidity high for calibration lamps',value=None,rows=10, cols=5,width=800,max_length=5000) self.exp_time = TextInput(placeholder = '20:07',value=None, width=100) #title ='Time in Kitt Peak local time*', self.exp_btn = Button(label='Add', css_classes=['add_button']) self.exp_type = Select(title="Exposure Type", value = None, options=['None','Zero','Focus','Dark','Arc','FVC','DESI']) self.exp_alert = Div(text=' ', css_classes=['alert-style']) self.exp_exposure_start = TextInput(title='Exposure Number: First', placeholder='12345', value=None) self.exp_exposure_finish = TextInput(title='Exposure Number: Last', placeholder='12346', value=None) self.nl_subtitle = Div(text="Current DESI Night Log: {}".format(self.nl_file), css_classes=['subt-style']) self.nl_btn = Button(label='Get Current DESI Night Log', css_classes=['connect_button']) self.nl_text = Div(text=" ", css_classes=['inst-style'], width=1000) self.nl_alert = Div(text='You must be connected to a Night Log', css_classes=['alert-style'], width=500) self.nl_info = Div(text="Night Log Info:", css_classes=['inst-style'], width=500) self.exptable_alert = Div(text=" ",css_classes=['alert-style'], width=500) self.checklist = CheckboxGroup(labels=[]) self.check_time = TextInput(placeholder = '20:07', value=None) #title ='Time in Kitt Peak local time*', self.check_alert = Div(text=" ", css_classes=['alert-style']) self.check_btn = Button(label='Submit', css_classes=['add_button']) self.check_comment = TextAreaInput(title='Comment', placeholder='comment if necessary', rows=3, cols=3) self.prob_subtitle = Div(text="Problems", css_classes=['subt-style']) self.prob_inst = Div(text="Describe problems as they come up and at what time they occur. If there is an Alarm ID associated with the problem, include it, but leave blank if not. If possible, include a description of the remedy.", css_classes=['inst-style'], width=1000) self.prob_time = TextInput(placeholder = '20:07', value=None, width=100) #title ='Time in Kitt Peak local time*', self.prob_input = TextAreaInput(placeholder="NightWatch not plotting raw data", rows=10, cols=3, title="Problem Description*:") self.prob_alarm = TextInput(title='Alarm ID', placeholder='12', value=None, width=100) self.prob_action = TextAreaInput(title='Resolution/Action',placeholder='description',rows=10, cols=3) self.prob_btn = Button(label='Add', css_classes=['add_button']) self.prob_alert = Div(text=' ', css_classes=['alert-style']) self.img_subtitle = Div(text="Images", css_classes=['subt-style']) self.img_upinst = Div(text="Include images in the Night Log by uploading a png image from your local computer. Select file, write a comment and click Add", css_classes=['inst-style'], width=1000) self.img_upinst2 = Div(text=" Choose image to include with comment: ", css_classes=['inst-style']) self.img_upload = FileInput(accept=".png") self.img_upload.on_change('value', self.upload_image) self.img_upload_comments = FileInput(accept=".png") self.img_upload_comments.on_change('value', self.upload_image_comments) self.img_upload_comments_os = FileInput(accept=".png") self.img_upload_comments_os.on_change('value', self.upload_image_comments_os) self.img_upload_problems = FileInput(accept=".png") self.img_upload_problems.on_change('value', self.upload_image_problems) self.img_inst = Div(text="Include images in the Night Log by entering the location of the images on the desi cluster", css_classes=['inst-style'], width=1000) self.img_input = TextInput(title='image file location on desi cluster', placeholder='/n/home/desiobserver/image.png',value=None) self.img_comment = TextAreaInput(placeholder='comment about image', rows=8, cols=3, title='Image caption') self.img_btn = Button(label='Add', css_classes=['add_button']) self.img_alert = Div(text=" ",width=1000) self.plot_subtitle = Div(text="Telemetry Plots", css_classes=['subt-style']) self.DESI_Log = None self.save_telem_plots = False
# update the text with predict button click predict_output = Div(text='Current Survival Prediction (Base Model): ' + '</br>' + '1205.19 days' + '</br>', width=800, style={'font-size': '200%', 'color': 'black'}) #, height=height) def predict_output_handler(): predict_output.text = 'Updated Survival Prediction: ' + '</br>' + str(prediction) + '</br>' '''--- Output ---''' ### DataTable #return alsfrs_source #def alsfrs_source_cols(): alsfrs_source_columns = [ TableColumn(field="test", title="Test Number"), TableColumn(field="date", title="Date", formatter=DateFormatter(format="%m/%d/%Y")), TableColumn(field="day_from_onset", title="Days from Onset"), TableColumn(field="Q1", title="Q1"), TableColumn(field="Q2", title="Q2"), TableColumn(field="Q3", title="Q3"), TableColumn(field="Q4", title="Q4"), TableColumn(field="Q5", title="Q5"), TableColumn(field="Q6", title="Q6"), TableColumn(field="Q7", title="Q7"), TableColumn(field="Q8", title="Q8"), TableColumn(field="Q9", title="Q9"), TableColumn(field="Q10_R1", title="Q10_R1"), TableColumn(field="R2", title="R2"), TableColumn(field="R3", title="R3") ] data_table = DataTable(source=alsfrs_source, columns=alsfrs_source_columns,
def __init__(self): self.input_df = pd.DataFrame({ 'x': ['2010-01-01'] * DF_NUM_PREVIEW_ROWS, 'y': [0] * DF_NUM_PREVIEW_ROWS }) self.forecasted_df = None self.datefmt = DateFormatter(format='%m-%d-%Y') self.inputs = None self.x_range = [0, 10] self.demand_plot = figure( x_range=self.x_range, x_axis_type="datetime", tools=["pan", 'wheel_zoom']) #,wheel_zoom,box_zoom,reset,resize") self.plot_data_source = ColumnDataSource( data=self.input_df) #dict(x=[0], y=[0]) self.line1 = self.demand_plot.line(x='x', y='y', source=self.plot_data_source, line_color='blue', name='line1') self.demand_plot.xaxis.formatter = DatetimeTickFormatter( days="%d %b %Y", hours="") self.demand_plot.axis.minor_tick_line_color = None self.demand_plot.xaxis[ 0].ticker.desired_num_ticks = 10 #num_minor_ticks = 0 self.demand_plot.xaxis.major_label_orientation = radians( 30) # from math import radians # Set up widgets self.data_source_selector = Select( title='Step 1/5: Select Data', value='Not Selected', options=['Not Selected', 'Use Example Data', 'Upload Data']) self.file_input = FileInput(accept='.csv,.xlsx') self.data_table = DataTable( height=DATATABLE_PREVIEW_HEIGHT, width=DATATABLE_PREVIEW_WIDTH, fit_columns=False, index_position=None, margin=(0, 15, 0, 15), #aspect_ratio=0.5, #default_size=50 ) self.data_preview_paragraph = Paragraph(text='Data Preview:', margin=(0, 15, 0, 15)) self.values_col_selector = Select( title='Step 2/5: Select column with demand values', value='Not Selected', options=['Not Selected']) self.product_id_col_selector = Select( title='Step 3/5: Select column with product ID', value='Not Selected', options=['Not Selected']) self.date_col_selector = Select(title="Step 4/5: Select date column", value='Not Selected', options=['Not Selected']) self.last_date_picker = DatePicker( title='Select the date of last observation', max_date=datetime.datetime.date(pd.to_datetime("today")), value=datetime.datetime.date(pd.to_datetime("today"))) self.workdays_checkboxgroup = CheckboxGroup( labels=["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], active=[], inline=True, margin=(0, 15, 0, 0)) self.workdays_apply_button = Button(label='Select Business Days', button_type='primary') self.product_selector_plotting = Select( title='Select Product to Display', value='v1', options=['v1', 'v2']) self.prediction_button = Button( label='Forecast Demand for Selected Product ID', button_type='primary') self.default_info_msg = 'This window will contain additional information,\nas you interact with the app.' self.info_paragraph = PreText( text='Details:\n{}'.format(self.default_info_msg)) # self.text = TextInput(title='title', value='my sine wave') # self.offset = Slider(title='offset', value=0.0, start=-5.0, end=5.0, step=0.1) self.widgets = { 'data_source_selector': self.data_source_selector, 'file_input': self.file_input, 'values_col_selector': self.values_col_selector, 'product_id_col_selector': self.product_id_col_selector, 'data_preview_paragraph': self.data_preview_paragraph, 'data_table': self.data_table, 'product_selector': self.product_selector_plotting, 'demand_plot': self.demand_plot, 'date_col_selector': self.date_col_selector, 'last_date_picker': self.last_date_picker, 'workdays_checkboxgroup': self.workdays_checkboxgroup, 'workdays_apply_button': self.workdays_apply_button, 'prediction_button': self.prediction_button, #'': self., } self.values_colname = None self.product_id_colname = None self.date_colname = None self.product_ids = []