def main_function(self, mode): external_stylesheets = [ 'https://raw.githubusercontent.com/rab657/explainx/master/explainx.css', dbc.themes.BOOTSTRAP, { 'href': 'https://fonts.googleapis.com/css?family=Montserrat', 'rel': 'stylesheet' } ] local = JupyterDash(__name__, external_stylesheets=external_stylesheets, suppress_callback_exceptions=True) local.title = "explainX.ai - Feature Interaction" local.layout = feature_interaction.layout_interaction( self.data, self.df_with_shap, local) if mode == None: import random port = random.randint(5000, 6000) return local.run_server(port=port) else: import random port = random.randint(5000, 6000) return local.run_server(mode='inline', port=port)
def main_function(self, mode): external_stylesheets = [ 'https://raw.githubusercontent.com/rab657/explainx/master/explainx.css', dbc.themes.BOOTSTRAP, { 'href': 'https://fonts.googleapis.com/css?family=Montserrat', 'rel': 'stylesheet' } ] local = JupyterDash(__name__, external_stylesheets=external_stylesheets, suppress_callback_exceptions=True) local.title = "explainX.ai - Local Level Explanation" local.layout = local_explanation.layout_local(self.shapley_values, self.data, self.df_with_shap, local) debug_value = False if mode is None: import random port = random.randint(6000, 7000) return local.run_server(port=port, debug=debug_value, dev_tools_ui=debug_value, dev_tools_props_check=debug_value, dev_tools_silence_routes_logging=True, dev_tools_hot_reload=True) else: import random port = random.randint(6000, 7000) return local.run_server(mode='inline', port=port, debug=debug_value, dev_tools_ui=debug_value, dev_tools_props_check=debug_value, dev_tools_silence_routes_logging=True, dev_tools_hot_reload=True)
def main_function(self, mode): external_stylesheets = [ 'https://raw.githubusercontent.com/rab657/explainx/master/explainx.css', dbc.themes.BOOTSTRAP, { 'href': 'https://fonts.googleapis.com/css?family=Montserrat', 'rel': 'stylesheet' } ] cohort = JupyterDash(__name__, external_stylesheets=external_stylesheets, suppress_callback_exceptions=True) cohort.title = "explainX.ai - Model Performance Analysis" cohort.layout = cohort_app.test_func(self.data, self.model, cohort) debug_value = False if mode == None: import random port = random.randint(4000, 5000) return cohort.run_server(port=port, debug=debug_value, dev_tools_ui=debug_value, dev_tools_props_check=debug_value, dev_tools_silence_routes_logging=True, dev_tools_hot_reload=True) else: import random port = random.randint(4000, 5000) return cohort.run_server(mode='inline', port=port, debug=debug_value, dev_tools_ui=debug_value, dev_tools_props_check=debug_value, dev_tools_silence_routes_logging=True, dev_tools_hot_reload=True)
# In[12]: df1['ISO3'] = [ countries.get(country, 'Unknown code') for country in input_countries ] df1 = df1.drop([29, 67], axis=0) # removing countries that no longer exist # ### Creating app layout # In[13]: app.layout = html.Div([ html.H1("World Happiness", style={'text-align': 'center'}), dcc.Slider(id='my_slider', min=2015, max=2019, step=1, value=2015), html.Div(id='slider_output_container', children={}), html.Br(), dcc.Graph(id="my_happy_map", figure={}) ]) # ### Defining the inputs and outputs using callback and creating the actual figure # In[14]: @app.callback([ Output(component_id='slider_output_container', component_property='children'), Output(component_id='my_happy_map', component_property='figure') ], [dash.dependencies.Input('my_slider', 'value')]) def update_graph(option_slctd):
countdown = 20 #global df # sample dataframe of a wide format cols = ['temperature'] X = np.ones(50) * 18 df = pd.DataFrame(X, columns=cols) # plotly figure fig = df.plot(template='plotly_dark') app = JupyterDash(__name__) app.layout = html.Div([ html.H1("Winecellar temperatures"), dcc.Interval( id='interval-component', interval=20 * 1000, # in milliseconds n_intervals=0), dcc.Graph(id='graph'), ]) # Define callback to update graph @app.callback(Output('graph', 'figure'), [Input('interval-component', "n_intervals")]) def streamFig(value): global df raw = requests.get('http://app:8000/records/all?dt=24') Y = raw.json()
app.layout = html.Div(children=[ navbar, dbc.Row([ dbc.Col( dbc.Button( [ "Generate", dbc.Badge( "50", color="light", id="mybadge", className="ml-1"), ], color="primary", id="Generate_images", block=True, ), width={ "size": 4, "offset": 4 }, style={"margin-bottom": "20px"}, ), dbc.Col(radioitems, width={ "size": 3, "offset": 0 }), ]), dbc.Row( dbc.Col( dcc.Slider( id="my-slider", min=25, max=150, step=None, marks={ 25: "25 Images", 50: "50 Images", 75: "75 Images", 100: "100 Images", 125: "125 Images", 150: "150 Images", }, value=50, ), width={ "size": 8, "offset": 2 }, )), html.Div(id="slider-output-container"), dbc.Row( dbc.Col( dbc.Alert( "It may take a few minutes to generate first set of images.", id="alert-fade", dismissable=True, is_open=True, ), width={ "size": 6, "offset": 3 }, )), dcc.Loading( id="loading-1", type="default", style={"margin-top": "70px"}, children=html.Div(id="loading-output-1"), ), dbc.Row(dbc.Col(dbc.Container(id="output_container"))), html.P(id="placeholder", style={"visibility": "none"}), ])
""" def compute_data_choice_2(df): # Compute delay averages avg_car = df.groupby(['Month','Reporting_Airline'])['CarrierDelay'].mean().reset_index() avg_weather = df.groupby(['Month','Reporting_Airline'])['WeatherDelay'].mean().reset_index() avg_NAS = df.groupby(['Month','Reporting_Airline'])['NASDelay'].mean().reset_index() avg_sec = df.groupby(['Month','Reporting_Airline'])['SecurityDelay'].mean().reset_index() avg_late = df.groupby(['Month','Reporting_Airline'])['LateAircraftDelay'].mean().reset_index() return avg_car, avg_weather, avg_NAS, avg_sec, avg_late # Application layout app.layout = html.Div(children=[html.H1('Airline Dashboard', style={'textAlign': 'center', 'color': '#503D36', 'font-size': 40}), # REVIEW2: Dropdown creation # Create an outer division html.Div([ # Add an division html.Div([ # Create an division for adding dropdown helper text for report type html.Div( [ html.H2('Report Type:', style={'margin-right': '2em'}), ] ), # TODO2: Add a dropdown dcc.Dropdown( id='demo-dropdown', options=[
Path(get_project_path()) / "data/cap_gradient_space.tsv" ) gradient_space["type"] = None mask_group = gradient_space["participant_id"] == "group" gradient_space.loc[mask_group, "type"] = "group" gradient_space.loc[~mask_group, "type"] = "sub" app = JupyterDash(__name__) app.layout = html.Div( [ dcc.Graph(id="gradient-space"), html.P("CAP label"), dcc.Checklist( id="cap-label", options=[{"label": f"{i}", "value": f"{i}"} for i in range(1, 9)], value=["1", "2"], labelStyle={"display": "inline-block"}, ), ] ) @app.callback(Output("gradient-space", "figure"), [Input("cap-label", "value")]) def update_chart(value): mask = [] for i in value: cap = gradient_space[gradient_space["CAP"] == int(i)] mask.extend(cap.index.tolist()) fig = px.scatter_3d(
app.layout = html.Div([ html.H1("Wage gap study"), dcc.Markdown(style={ "background-color": "yellow", "border": "solid 1px black" }, children=markdown_text), html.H2("Men and Women income study"), dcc.Graph(figure=table), html.H2("Gender Opionions on Male BreadWinner"), dcc.Graph(figure=gss_p3), html.H2("Gender Opinions on Relationship Between Job Prestige vs. Income"), dcc.Graph(figure=gss_p4), html.H2("Job Prestige vs. Sex"), dcc.Graph(figure=gss_p5), html. H2("Gender Opinions on Relationship Between Job Prestige vs. Income from Six Categories" ), dcc.Graph(figure=gss_p6), html.Div([ html.H3("x-axis feature"), dcc.Dropdown(id='x-axis', options=[{ 'label': i, 'value': i } for i in mycol_ch2], value='relationship'), html.H3("y-axis feature"), dcc.Dropdown(id='y-axis', value='index_col'), html.H3("colors"), dcc.Dropdown(id='color', options=[{ 'label': i, 'value': i } for i in cat_columns3], value=None) ], style={ "width": "25%", "float": "left" }), html.Div([ dcc.Graph(id="graph", style={ "width": "70%", "display": "inline-block" }) ]) ])
app.layout = html.Div(children=[ # All elements from the top of the page html.Div([ html.H1("App Store Dashboard", style={'text-align': 'center'}), html.P('Select The Type Of The App:'), dcc.Dropdown(id="type_select", options=[{ "label": "Free", "value": "Free" }, { "label": "Paid", "value": "Paid" }], multi=False, value="Free", style={'width': "40%"}), html.Br(), html.P('Select The Category Of The App:'), dcc.Dropdown(id="category_select", options=[{ "label": "BEAUTY", "value": "BEAUTY" }, { "label": "PARENTING", "value": "PARENTING" }, { "label": "COMICS", "value": "COMICS" }, { "label": "EVENTS", "value": "EVENTS" }, { "label": "ART AND DESIGN", "value": "ART_AND_DESIGN" }, { "label": "WEATHER", "value": "WEATHER" }, { "label": "LIBRARIES AND DEMO", "value": "LIBRARIES_AND_DEMO" }, { "label": "AUTO AND VEHICLES", "value": "AUTO_AND_VEHICLES" }, { "label": "HOUSE AND HOME", "value": "HOUSE_AND_HOME" }, { "label": "FOOD AND DRINK", "value": "FOOD_AND_DRINK" }, { "label": "MAPS AND NAVIGATION", "value": "MAPS_AND_NAVIGATION" }, { "label": "ENTERTAINMENT", "value": "ENTERTAINMENT" }, { "label": "EDUCATION", "value": "EDUCATION" }, { "label": "VIDEO PLAYERS", "value": "VIDEO_PLAYERS" }, { "label": "BOOKS AND REFERENCE", "value": "BOOKS_AND_REFERENCE" }, { "label": "DATING", "value": "DATING" }, { "label": "TRAVEL AND LOCAL", "value": "TRAVEL_AND_LOCAL" }, { "label": "SHOPPING", "value": "SHOPPING" }, { "label": "NEWS AND MAGAZINES", "value": "NEWS_AND_MAGAZINES" }, { "label": "SOCIAL", "value": "SOCIAL" }, { "label": "PHOTOGRAPHY", "value": "PHOTOGRAPHY" }, { "label": "HEALTH AND FITNESS", "value": "HEALTH_AND_FITNESS" }, { "label": "FINANCE", "value": "FINANCE" }, { "label": "LIFESTYLE", "value": "LIFESTYLE" }, { "label": "SPORTS", "value": "SPORTS" }, { "label": "COMMUNICATION", "value": "COMMUNICATION" }, { "label": "PERSONALIZATION ", "value": "PERSONALIZATION " }, { "label": "PRODUCTIVITY", "value": "PRODUCTIVITY" }, { "label": "BUSINESS", "value": "BUSINESS" }, { "label": "MEDICAL", "value": "MEDICAL" }, { "label": "TOOLS", "value": "TOOLS" }, { "label": "GAME", "value": "PHOTOGRAPHY" }, { "label": "FAMILY", "value": "FAMILY" }], multi=False, value="SOCIAL", style={'width': "40%"}), html.Br(), html.P('Select The Rating Range Of The Plot:'), dcc.RangeSlider( id='my_range_slider', min=0, max=5, step=0.5, value=[0, 5]), html.Br(), html.Div(id='output-container-range-slider'), dcc.Graph(id='first_plot', figure={}) ]), # New Div for all elements in the new 'row' of the page html.Div([ html.P('Write The Plot Title:'), dcc.Input(id="text1", type="text", placeholder=""), html.Br(), html.Div(id='output_text'), html.P('Select The Y-Axis Column:'), dcc.RadioItems(id="radiobuttons_select", options=[{ 'label': 'Size', 'value': 'Size' }, { 'label': 'Installs', 'value': 'Installs' }, { 'label': 'Price', 'value': 'Price' }], value='Installs') ]), html.Br(), dcc.Graph(id='second_plot', figure={}) ])
app.layout = html.Div(children=[ html.H1('US Domestic Airline Flights Performance', style={'textAlign': 'center', 'color': '#503D36', 'font-size': 24}), # Create an outer division html.Div([ # Add an division html.Div([ # Create a division for adding dropdown helper text for report type html.Div( [ html.H2('Report Type:', style={'margin-right': '2em'}), ] ), dcc.Dropdown(id='input-type', options=[ {'label': 'Yearly Airline Performance Report', 'value': 'OPT1'}, {'label': 'Yearly Airline Delay Report', 'value': 'OPT2'} ], placeholder='Select a report type', style={'width':'80%', 'padding':'3px', 'font-size': '20px', 'text-align-last' : 'center'}), # Place them next to each other using the division style ], style={'display':'flex'}), # Add next division html.Div([ # Create an division for adding dropdown helper text for choosing year html.Div( [ html.H2('Choose Year:', style={'margin-right': '2em'}) ] ), dcc.Dropdown(id='input-year', # Update dropdown values using list comphrehension options=[{'label': i, 'value': i} for i in year_list], placeholder="Select a year", style={'width':'80%', 'padding':'3px', 'font-size': '20px', 'text-align-last' : 'center'}), # Place them next to each other using the division style ], style={'display': 'flex'}), ]), # Add Computed graphs html.Div([ ], id='plot1'), html.Div([ html.Div([ ], id='plot2'), html.Div([ ], id='plot3') ], style={'display': 'flex'}), html.Div([ html.Div([ ], id='plot4'), html.Div([ ], id='plot5') ], style={'display': 'flex'}), ])
def init_app(self): app = JupyterDash(__name__) # app = dash.Dash() app.css.config.serve_locally = True app.scripts.config.serve_locally = True # self.add_rec(['main', 'MLPClassifier'], 'alpha=0.1', self.icicle_data) # self.add_rec(['main', 'MLPClassifier'], 'alpha=0.01', self.icicle_data) def df_to_dict(ut): data = {} for col_name in self.hierarchy_path: for i, g in ut.groupby(col_name): data_key = g[col_name].iloc[0] data[data_key] = {} data = copy.deepcopy(self.icicle_data) icicle_plot_fig = icicle_plot.Icicle(id='icicle_plot_fig', value='main/', label='my-label', low=self.low_color, high=self.high_color, data=data) def make_ints(row): for col in self.hierarchy_path: if row[col] != None: try: row[col] = float(row[col].split("=")[1]) except: row[col] return row pc_data_numeric = self.pc_data.apply(make_ints, axis=1) pc = go.Figure(data=[go.Scatter(x=[], y=[])]) if self.pc_data is not 0 and not self.pc_data.empty: pc = px.parallel_coordinates(pc_data_numeric.apply(make_ints, axis=1), color="accuracy", dimensions=self.hierarchy_path + ['accuracy'], color_continuous_scale='RdBu', height=350) pc_o = pc marks = {} for i in range(0, 100, 10): marks[i / 100] = str(i / 100) button_style = { "background-color": "#008CBA", "border": "none", "color": "white", "padding": "15px 32px", "text-align": "center", "display": "inline-block", "font-size": 16, "margin": "4px 2px", "cursor": "pointer", "width": "150px", "border-radius": "5%" } app.layout = html.Div( [ html.Div( [ html.Div(icicle_plot_fig, id='icicle-wrap'), dcc.Graph(id='pc', figure=pc, style={'height': 350}), dcc.Interval( id='interval-component', interval=1000, # in milliseconds n_intervals=0), dcc.Interval( id='interval-component2', interval=1000, # in milliseconds n_intervals=0), dcc.Interval(id='interval-loading', interval=100, n_intervals=0), html.H3('Sand Box', id='sandboxtext'), dcc.Textarea(id='sandbox', value='', style={ 'height': 120, 'width': '90%' }), html.Div([ html.Button('Execute', id='execute-button', style=button_style), dcc.Loading(id="loading", children=html.Div( [html.Div(id='output')]), type="circle", style={'margin-bottom': '6%'}) ]) ], style={ 'width': '87%', 'height': '100%', 'float': 'left' }), html.Div([ dcc.RangeSlider(id='metric-slider', min=0, max=1, step=0.01, value=[0, 1], marks=marks, vertical=True, verticalHeight=500) ], style={ 'margin-left': '90%', 'margin-top': '2%' }) # html.Div([ # html.H3('Sand Box', id='sandboxtext', style={"text-align": 'center'}), # dcc.Textarea( # id='sandbox', # value='', # style={'height': 400} # ), # html.Div([ # html.Button('Execute', id='execute-button', style=button_style), # dcc.Loading( # id="loading", # children=html.Div([ # html.Div(id='output') # ]), # type="circle" # ) # ], style= {'right': 37, 'position': 'absolute'}) # ], style={'margin-left': '5%'}) ], style={ 'height': '100%', 'overflow': 'hidden' }) @app.callback(Output('icicle-wrap', 'children'), [ Input('metric-slider', 'value'), Input('interval-component', 'n_intervals') ]) def update_icicle(rangeData, n): trigger_context = dash.callback_context.triggered[0]['prop_id'] if len(dash.callback_context.triggered ) <= 1 and self.update_available == False and ( trigger_context == 'interval-component.n_intervals' or trigger_context == '.'): raise PreventUpdate # revert to original state data = copy.deepcopy(self.icicle_data) # print(data) if not self.pc_data.empty: # delete entries self.remove_nodes_out_of_range(rangeData[0], rangeData[1], data) filtered_accs = self.pc_data.query( "accuracy >= " + str(rangeData[0]) + " and accuracy <= " + str(rangeData[1]))['accuracy'] self.low_color = filtered_accs.min() self.high_color = filtered_accs.max() if rangeData != self.rangeDataOld: self.id_updater += 1 self.rangeDataOld = rangeData if self.update_available: # print("update vailable") self.id_updater += 1 self.update_available = False # id is dictionary for Dash pattern matching callbacks return icicle_plot.Icicle(id={ 'role': 'icicle_plot_fig', 'index': self.id_updater }, value='main/', label='my-label', low=self.low_color, high=self.high_color, data=data) @app.callback(Output('pc', 'figure'), [ Input({ 'role': 'icicle_plot_fig', 'index': ALL }, 'value'), Input('metric-slider', 'value'), Input('interval-component2', 'n_intervals') ]) def update_pc(clickData, rangeData, n): if self.pc_data.empty: return go.Figure(data=[go.Scatter(x=[], y=[])]) trigger_context = dash.callback_context.triggered[0]['prop_id'] if len(dash.callback_context.triggered ) <= 1 and self.update_available == False and ( trigger_context == 'interval-component2.n_intervals'): raise PreventUpdate pc_data_copy = self.pc_data if len(clickData) == 0: if self.update_available: pc = px.parallel_coordinates( pc_data_copy.apply(make_ints, axis=1), color="accuracy", dimensions=self.hierarchy_path + ['accuracy'], color_continuous_scale='RdBu', height=350) return pc raise PreventUpdate # return self.pc # revert to original state # delete entries pc_data_copy = pc_data_copy.query("accuracy >= " + str(rangeData[0]) + " and accuracy <= " + str(rangeData[1])) if isinstance(clickData, list): clickData = clickData[0] if 'recommendationval' in clickData: raise PreventUpdate if clickData.split("/")[:-2] == []: pc = px.parallel_coordinates(pc_data_copy.apply(make_ints, axis=1), color="accuracy", dimensions=self.hierarchy_path + ['accuracy'], color_continuous_scale='RdBu', height=350) return pc if clickData: click_path = clickData.split("/")[:-1][1:] subset_counter = len(click_path) if click_path == []: return pc_o selected_df = pc_data_copy j = -1 for i in click_path: j += 1 if "=" in i: comps_name = i.split("=") hyp_name = comps_name[0] hyp_val = comps_name[1] selected_df = selected_df[selected_df.apply( lambda x: x['model_params'][hyp_name] == hyp_val if hyp_name in x['model_params'] else False, axis=1)] else: selected_df = selected_df[selected_df['model'] == i] sample_vals = selected_df.iloc[0] labels_pc = {} for i in self.hierarchy_path[subset_counter:]: if sample_vals[i]: labels_pc[i] = sample_vals[i].split("=")[0] selected_df = selected_df.apply(make_ints, axis=1) self.pc = px.parallel_coordinates( selected_df, color="accuracy", dimensions=self.hierarchy_path[subset_counter:] + ['accuracy'], labels=labels_pc, color_continuous_scale='RdBu', height=350) # print(pc_data_copy.apply(make_ints, axis=1)) return self.pc self.pc = px.parallel_coordinates(pc_data_copy.apply(make_ints, axis=1), color="accuracy", dimensions=self.hierarchy_path + ['accuracy'], color_continuous_scale='RdBu', height=350) return self.pc @app.callback( Output('sandbox', 'value'), [Input({ 'role': 'icicle_plot_fig', 'index': ALL }, 'value')]) def update_sandbox(clickData): if len(clickData) == 0: raise PreventUpdate if isinstance(clickData, list): clickData = clickData[0] if 'recommendationval' in clickData: # update the sand box clickData = clickData.replace(" recommendationval", "") model_name = "" params_rec = {} for i in clickData.split("/"): if 'main' in i or not i or not i.strip(): continue # model name if '=' not in i: model_name = i continue try: params_rec[i.split("=")[0]] = float(i.split( "=")[1]) # for int, long, float and complex if params_rec[i.split("=")[0]].is_integer(): params_rec[i.split("=")[0]] = int( params_rec[i.split("=")[0]]) except ValueError: params_rec[i.split("=")[0]] = i.split("=")[1] code = "app.experiment(\nlibrary = 'sklearn',\nmodel = " + model_name + ",\nparams = \n" + str( params_rec).replace('{', '{\n ').replace( ',', ',\n ').replace('}', '\n}') + ",\nhighlighted = True)" return code else: raise PreventUpdate @app.callback(Output('execute-button', 'style'), [Input('interval-loading', 'n_intervals')]) def check_execution(n_intervals): button_style = { "background-color": "#008CBA", "border": "none", "color": "white", "padding": "15px 32px", "text-align": "center", "display": "inline-block", "font-size": 16, "margin": "4px 2px", "cursor": "pointer", "width": "150px", "border-radius": "5%" } if not self.running_experiment and not self.running_recommendation: return button_style if self.running_recommendation: button_style['visibility'] = "hidden" button_style["cursor"] = 'not-allowed' button_style['pointer-events'] = "none" return button_style button_style["cursor"] = 'not-allowed' button_style['pointer-events'] = "none" button_style["opacity"] = 0.5 return button_style # execute button handler app.callback(Output('output', 'value'), [Input('execute-button', 'n_clicks')], [State('sandbox', 'value')])(self.execute_code) self.app = app
app.layout = html.Div([ html.Div( [ html.Div([ dcc.Dropdown(id='crossfilter-xaxis-column', options=[{ 'label': i, 'value': i } for i in available_indicators], value='Fertility rate, total (births per woman)'), dcc.RadioItems(id='crossfilter-xaxis-type', options=[{ 'label': i, 'value': i } for i in ['Linear', 'Log']], value='Linear', labelStyle={'display': 'inline-block'}) ], style={ 'width': '49%', 'display': 'inline-block' }), html.Div([ dcc.Dropdown(id='crossfilter-yaxis-column', options=[{ 'label': i, 'value': i } for i in available_indicators], value='Life expectancy at birth, total (years)'), dcc.RadioItems(id='crossfilter-yaxis-type', options=[{ 'label': i, 'value': i } for i in ['Linear', 'Log']], value='Linear', labelStyle={'display': 'inline-block'}) ], style={ 'width': '49%', 'float': 'right', 'display': 'inline-block' }) ], style={ 'borderBottom': 'thin lightgrey solid', 'backgroundColor': 'rgb(250, 250, 250)', 'padding': '10px 5px' }), html.Div([ dcc.Graph(id='crossfilter-indicator-scatter', hoverData={'points': [{ 'customdata': 'Japan' }]}) ], style={ 'width': '49%', 'display': 'inline-block', 'padding': '0 20' }), html.Div([ dcc.Graph(id='x-time-series'), dcc.Graph(id='y-time-series'), ], style={ 'display': 'inline-block', 'width': '49%' }), html.Div(dcc.Slider( id='crossfilter-year--slider', min=df['Year'].min(), max=df['Year'].max(), value=df['Year'].max(), marks={str(year): str(year) for year in df['Year'].unique()}, step=None), style={ 'width': '49%', 'padding': '0px 20px 20px 20px' }) ])
app.layout = html.Div(style={'backgroundColor': colors['background']}, children = [ html.Div(children=[ html.H1('Pv data visualization', style={'textAlign': 'center', 'color': colors['text']}), #--------------------- html.Div([ html.Div([ html.Div([ html.Div(children = [ html.H3('Substation:', style={'paddingRight': '30px', 'fontSize': 18, 'color': colors['text_sub'], 'font-weight': 'bold'}), dcc.Dropdown( id='subs_ticker', options=[ {'label': i, 'value': i} for i in customer.Substation.unique() ], multi=True, value=[], style={'color': colors['text']}, placeholder="Select a substation", ) ], style={"width": "40%"}, className="six columns"), html.Div([ html.H3('Signal:', style={'paddingRight': '30px', 'fontSize': 18, 'color': colors['text_sub'], 'font-weight': 'bold'}), dcc.Dropdown( id='signal1_ticker', options=[ {'label': i, 'value': i} for i in ['P_GEN', 'Q_GEN', 'S_GEN'] ], multi=True, value=[], style={'color': colors['text']} ), ], style={"width": "40%"}, className="six columns"), ], className="row"), html.Div([ html.Div([ html.H3('Weather site:', style={'paddingRight': '30px', 'fontSize': 18, 'color': colors['text_site'], 'font-weight': 'bold'}), dcc.Dropdown( id='sites_ticker', options=[ {'label': i, 'value': i} for i in weather.Site.unique() ], multi=True, value=[], style={'color': colors['text']}, placeholder="Select a weather site" ), ], style={"width": "40%"}, className="six columns"), html.Div([ html.H3('Signal:', style={'paddingRight': '30px', 'fontSize': 18, 'color': colors['text_site'], 'font-weight': 'bold'}), dcc.Dropdown( id='signal2_ticker', options=[ {'label': i, 'value': i} for i in ['TempOut', 'SolarRad', 'SolarEnergy', 'HiSolarRad', 'OutHum', 'WindSpeed', 'WindDir', 'WindRun', 'Rain'] ], multi=True, value=[], style={'color': colors['text']}, ), ], style={"width": "40%"}, className="six columns") ], className="row"), html.H3('Download displayed traces:', style={'paddingRight': '30px', 'fontSize': 18, 'color': colors['text']}), html.Div([ html.Div([ html.Button("Substations Traces", id="btn1"), Download(id="download1") ], className="six columns", style={"width": "20%", 'color': colors['text']}), html.Div([ html.Button("Weather Traces", id="btn2"), Download(id="download2") ], className="six columns", style={"width": "20%", 'color': colors['text'], 'padding-left':'25%'}) ], className="row"), ], className="six columns"), #------------------ html.Div([ dcc.Graph(id='map') ], className="six columns"), ], className="row", style={'marginTop': '5em','padding-left':'10%', 'padding-right':'15%', 'verical-align': 'center'}), #--------------- html.Div([ dcc.Graph(id='graph') ], style={'padding-left':'1%', 'padding-right':'1%'}), ]) ])
def make_dash_app(self, template='plotly_white', server_mode='external', port=8050, app_type='jupyter', plot_height=680, external_stylesheets=[ 'https://codepen.io/chriddyp/pen/bWLwgP.css' ], infer_proxy=False, slider_width=140, cutout_hdu=None, cutout_size=10): """ Create a Plotly/Dash app for interactive exploration Parameters ---------- template : str `plotly` style `template <https://plotly.com/python/templates/#specifying-themes-in-graph-object-figures>`_. server_mode, port : str, int If not `None`, the app server is started with `app.run_server(mode=server_mode, port=port)`. app_type : str If ``jupyter`` then `app = jupyter_dash.JupyterDash()`, else `app = dash.Dash()` plot_height : int Height in pixels of the scatter and SED+P(z) plot windows. infer_proxy : bool Run `JupyterDash.infer_jupyter_proxy_config()`, before app initilization, e.g., for running on GoogleColab. Returns ------- app : object App object following `app_type`. """ import dash from dash import dcc from dash import html import plotly.express as px from urllib.parse import urlparse, parse_qsl, urlencode import astropy.wcs as pywcs if app_type == 'dash': app = dash.Dash(__name__, external_stylesheets=external_stylesheets) else: from jupyter_dash import JupyterDash if infer_proxy: JupyterDash.infer_jupyter_proxy_config() app = JupyterDash(__name__, external_stylesheets=external_stylesheets) PLOT_TYPES = [ 'zphot-zspec', 'Mag-redshift', 'Mass-redshift', 'UVJ', 'RA/Dec', 'UV-redshift', 'chi2-redshift' ] for _t in self.extra_plots: PLOT_TYPES.append(_t) COLOR_TYPES = ['z_phot', 'z_spec', 'mass', 'sSFR', 'chi2'] #_title = f"{self.photoz.param['MAIN_OUTPUT_FILE']}" #_subhead = f"Nobj={self.photoz.NOBJ} Nfilt={self.photoz.NFILT}" _title = [ html.Strong(self.photoz.param['MAIN_OUTPUT_FILE']), ' / N', html.Sub('obj'), f'={self.photoz.NOBJ}', ' / N', html.Sub('filt'), f'={self.photoz.NFILT}', ] slider_row_style = { 'width': '90%', 'float': 'left', 'margin-left': '10px' } slider_container = { 'width': f'{slider_width}px', 'margin-left': '-25px' } check_kwargs = dict(style={ 'text-align': 'center', 'height': '14pt', 'margin-top': '-20px' }) # bool_options = {'has_zspec': 'z_spec > 0', # 'use': 'Use == 1'} if cutout_hdu is not None: cutout_wcs = pywcs.WCS(cutout_hdu.header, relax=True) cutout_data = cutout_hdu.data print('xxx', cutout_data.shape) cutout_div = html.Div( [dcc.Graph(id='cutout-figure', style={})], style={ 'right': '70px', 'width': '120px', 'height': '120px', 'border': '1px solid rgb(200,200,200)', 'top': '10px', 'position': 'absolute' }) cutout_target = 'figure' else: cutout_div = html.Div(id='cutout-figure', style={ 'left': '1px', 'width': '1px', 'height': '1px', 'bottom': '1px', 'position': 'absolute' }) cutout_data = None cutout_target = 'children' ####### App layout app.layout = html.Div([ # Selectors html.Div( [ dcc.Location(id='url', refresh=False), html.Div([ html.Div(_title, id='title-bar', style={ 'float': 'left', 'margin-top': '4pt' }), html.Div([ html.Div([ dcc.Dropdown(id='plot-type', options=[{ 'label': i, 'value': i } for i in PLOT_TYPES], value='zphot-zspec', clearable=False, style={ 'width': '120px', 'margin-right': '5px', 'margin-left': '5px', 'font-size': '8pt' }), ], style={'float': 'left'}), html.Div([ dcc.Dropdown(id='color-type', options=[{ 'label': i, 'value': i } for i in COLOR_TYPES], value='sSFR', clearable=False, style={ 'width': '80px', 'margin-right': '5px', 'font-size': '8pt' }), ], style={ 'display': 'inline-block', 'margin-left': '10px' }), ], style={'float': 'right'}), ], style=slider_row_style), html.Div( [ html.Div([ dcc.Dropdown( id='mag-filter', options=[{ 'label': i, 'value': i } for i in self.photoz.flux_columns], value=self.DEFAULT_FILTER, style={ 'width': f'{slider_width-45}px', 'margin-right': '20px', 'font-size': '8pt' }, clearable=False), ], style={'float': 'left'}), html.Div([ dcc.RangeSlider(id='mag-slider', min=12, max=32, step=0.2, value=[18, 27], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='mag-checked', options=[{ 'label': 'AB mag', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), # html.Div([ dcc.RangeSlider(id='chi2-slider', min=0, max=20, step=0.1, value=[0, 6], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='chi2-checked', options=[{ 'label': 'chi2', 'value': 'checked' }], value=[], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), html.Div([ dcc.RangeSlider(id='nfilt-slider', min=1, max=self.MAXNFILT, step=1, value=[3, self.MAXNFILT], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='nfilt-checked', options=[{ 'label': 'nfilt', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), ], style=slider_row_style), html.Div( [ html.Div([ dcc.RangeSlider(id='zphot-slider', min=-0.5, max=12, step=0.1, value=[0, self.ZMAX], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='zphot-checked', options=[{ 'label': 'z_phot', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(float='left', **slider_container)), html.Div([ dcc.RangeSlider(id='zspec-slider', min=-0.5, max=12, step=0.1, value=[-0.5, 6.5], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='zspec-checked', options=[{ 'label': 'z_spec', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), html.Div([ dcc.RangeSlider(id='mass-slider', min=7, max=13, step=0.1, value=[8, 11.8], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='mass-checked', options=[{ 'label': 'mass', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), # Boolean dropdown # dcc.Dropdown(id='bool-checks', # options=[{'label': self.bool_options[k], # 'value': k} # for k in self.bool_options], # value=[], # multi=True, # style={'width':'100px', # 'display':'inline-block', # 'margin-left':'0px', # 'font-size':'8pt'}, # clearable=True), ], style=slider_row_style), ], style={ 'float': 'left', 'width': '55%' }), # Object-level controls html.Div([ html.Div([ html.Div('ID / RA,Dec.', style={ 'float': 'left', 'width': '100px', 'margin-top': '5pt' }), dcc.Input(id='id-input', type='text', style={ 'width': '120px', 'padding': '2px', 'display': 'inline', 'font-size': '8pt' }), html.Div(children='', id='match-sep', style={ 'margin': '5pt', 'display': 'inline', 'width': '50px', 'font-size': '8pt' }), dcc.RadioItems(id='sed-unit-selector', options=[{ 'label': i, 'value': i } for i in ['Fλ', 'Fν', 'νFν']], value='Fλ', labelStyle={ 'display': 'inline', 'padding': '3px', }, style={ 'display': 'inline', 'width': '130px' }) ], style={ 'width': '260pix', 'float': 'left', 'margin-right': '20px' }), ]), html.Div( [ # html.Div([ # ], style={'width':'120px', 'float':'left'}), html.Div(id='object-info', children='ID: ', style={ 'margin': 'auto', 'margin-top': '10px', 'font-size': '10pt' }) ], style={ 'float': 'right', 'width': '45%' }), # Plots html.Div( [ # Scatter plot dcc.Graph(id='sample-selection-scatter', hoverData={ 'points': [{ 'customdata': (self.df['id'][0], 1.0, -9.0) }] }, style={'width': '95%'}) ], style={ 'float': 'left', 'height': '70%', 'width': '49%' }), html.Div( [ # SED dcc.Graph(id='object-sed-figure', style={'width': '95%'}) ], style={ 'float': 'right', 'width': '49%', 'height': '70%' }), cutout_div ]) ##### Callback functions @app.callback(dash.dependencies.Output('url', 'search'), [ dash.dependencies.Input('plot-type', 'value'), dash.dependencies.Input('color-type', 'value'), dash.dependencies.Input('mag-filter', 'value'), dash.dependencies.Input('mag-slider', 'value'), dash.dependencies.Input('mass-slider', 'value'), dash.dependencies.Input('chi2-slider', 'value'), dash.dependencies.Input('nfilt-slider', 'value'), dash.dependencies.Input('zphot-slider', 'value'), dash.dependencies.Input('zspec-slider', 'value'), dash.dependencies.Input('id-input', 'value') ]) def update_url_state(plot_type, color_type, mag_filter, mag_range, mass_range, chi2_range, nfilt_range, zphot_range, zspec_range, id_input): search = f'?plot_type={plot_type}&color_type={color_type}' search += f'&mag_filter={mag_filter}' search += f'&mag={mag_range[0]},{mag_range[1]}' search += f'&mass={mass_range[0]},{mass_range[1]}' search += f'&chi2={chi2_range[0]},{chi2_range[1]}' search += f'&nfilt={nfilt_range[0]},{nfilt_range[1]}' search += f'&zphot={zphot_range[0]},{zphot_range[1]}' search += f'&zspec={zspec_range[0]},{zspec_range[1]}' if id_input is not None: search += f"&id={id_input.replace(' ', '%20')}" return search @app.callback([ dash.dependencies.Output('plot-type', 'value'), dash.dependencies.Output('color-type', 'value'), dash.dependencies.Output('mag-filter', 'value'), dash.dependencies.Output('mag-slider', 'value'), dash.dependencies.Output('mass-slider', 'value'), dash.dependencies.Output('chi2-slider', 'value'), dash.dependencies.Output('nfilt-slider', 'value'), dash.dependencies.Output('zphot-slider', 'value'), dash.dependencies.Output('zspec-slider', 'value'), dash.dependencies.Output('id-input', 'value'), ], [dash.dependencies.Input('url', 'href')]) def set_state_from_url(href): plot_type = 'zphot-zspec' color_type = 'sSFR' mag_filter = self.DEFAULT_FILTER mag_range = [18, 27] mass_range = [8, 11.6] chi2_range = [0, 4] nfilt_range = [1, self.MAXNFILT] zphot_range = [0, self.ZMAX] zspec_range = [-0.5, 6.5] id_input = None if '?' not in href: return (plot_type, color_type, mag_filter, mag_range, mass_range, chi2_range, nfilt_range, zphot_range, zspec_range, id_input) search = href.split('?')[1] params = search.split('&') for p in params: if 'plot_type' in p: val = p.split('=')[1] if val in PLOT_TYPES: plot_type = val elif 'color_type' in p: val = p.split('=')[1] if val in COLOR_TYPES: color_type = val elif 'mag_filter' in p: val = p.split('=')[1] if val in self.photoz.flux_columns: mag_filter = val elif 'mag=' in p: try: vals = [float(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: mag_range = vals except ValueError: pass elif 'mass' in p: try: vals = [float(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: mass_range = vals except ValueError: pass elif 'nfilt=' in p: try: vals = [int(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: nfilt_range = vals except ValueError: pass elif 'zspec' in p: try: vals = [float(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: zspec_range = vals except ValueError: pass elif 'zphot' in p: try: vals = [float(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: zphot_range = vals except ValueError: pass elif 'id' in p: try: id_input = p.split('=')[1].replace('%20', ' ') except ValueError: id_input = None if not id_input: id_input = None return (plot_type, color_type, mag_filter, mag_range, mass_range, chi2_range, nfilt_range, zphot_range, zspec_range, id_input) @app.callback( dash.dependencies.Output('sample-selection-scatter', 'figure'), [ dash.dependencies.Input('plot-type', 'value'), dash.dependencies.Input('color-type', 'value'), dash.dependencies.Input('mag-filter', 'value'), dash.dependencies.Input('mag-slider', 'value'), dash.dependencies.Input('mag-checked', 'value'), dash.dependencies.Input('mass-slider', 'value'), dash.dependencies.Input('mass-checked', 'value'), dash.dependencies.Input('chi2-slider', 'value'), dash.dependencies.Input('chi2-checked', 'value'), dash.dependencies.Input('nfilt-slider', 'value'), dash.dependencies.Input('nfilt-checked', 'value'), dash.dependencies.Input('zphot-slider', 'value'), dash.dependencies.Input('zphot-checked', 'value'), dash.dependencies.Input('zspec-slider', 'value'), dash.dependencies.Input('zspec-checked', 'value'), dash.dependencies.Input('id-input', 'value') ]) def update_selection(plot_type, color_type, mag_filter, mag_range, mag_checked, mass_range, mass_checked, chi2_range, chi2_checked, nfilt_range, nfilt_checked, zphot_range, zphot_checked, zspec_range, zspec_checked, id_input): """ Apply slider selections """ sel = np.isfinite(self.df['z_phot']) if 'checked' in zphot_checked: sel &= (self.df['z_phot'] > zphot_range[0]) sel &= (self.df['z_phot'] < zphot_range[1]) if 'checked' in zspec_checked: sel &= (self.df['z_spec'] > zspec_range[0]) sel &= (self.df['z_spec'] < zspec_range[1]) if 'checked' in mass_checked: sel &= (self.df['mass'] > mass_range[0]) sel &= (self.df['mass'] < mass_range[1]) if 'checked' in chi2_checked: sel &= (self.df['chi2'] >= chi2_range[0]) sel &= (self.df['chi2'] <= chi2_range[1]) if 'checked' in nfilt_checked: sel &= (self.df['nusefilt'] >= nfilt_range[0]) sel &= (self.df['nusefilt'] <= nfilt_range[1]) #print('redshift: ', sel.sum()) if mag_filter is None: mag_filter = self.DEFAULT_FILTER #self.self.df['mag'] = self.ABZP #self.self.df['mag'] -= 2.5*np.log10(self.photoz.cat[mag_filter]) mag_col = 'mag_' + mag_filter if 'checked' in mag_checked: sel &= (self.df[mag_col] > mag_range[0]) sel &= (self.df[mag_col] < mag_range[1]) self.df['mag'] = self.df[mag_col] #print('mag: ', sel.sum()) if plot_type == 'zphot-zspec': sel &= self.df['z_spec'] > 0 #print('zspec: ', sel.sum()) if id_input is not None: id_i, dr_i = parse_id_input(id_input) if id_i is not None: self.df['is_selected'] = self.df['id'] == id_i sel |= self.df['is_selected'] else: self.df['is_selected'] = False else: self.df['is_selected'] = False dff = self.df[sel] # Color-coding by color-type pulldown if color_type == 'z_phot': color_kwargs = dict(color=np.clip(dff['z_phot'], *zphot_range), color_continuous_scale='portland') elif color_type == 'z_spec': color_kwargs = dict(color=np.clip(dff['z_spec'], *zspec_range), color_continuous_scale='portland') elif color_type == 'mass': color_kwargs = dict(color=np.clip(dff['mass'], *mass_range), color_continuous_scale='magma_r') elif color_type == 'chi2': color_kwargs = dict(color=np.clip(dff['chi2'], *chi2_range), color_continuous_scale='viridis') else: color_kwargs = dict(color=np.clip(dff['ssfr'], -12., -8.), color_continuous_scale='portland_r') # Scatter plot plot_defs = { 'Mass-redshift': ('z_phot', 'mass', 'z<sub>phot</sub>', 'log Stellar mass', (-0.1, self.ZMAX), (7.5, 12.5)), 'Mag-redshift': ('z_phot', 'mag', 'z<sub>phot</sub>', f'AB mag ({mag_filter})', (-0.1, self.ZMAX), (18, 28)), 'RA/Dec': ('ra', 'dec', 'R.A.', 'Dec.', self.ra_bounds, self.dec_bounds), 'zphot-zspec': ('z_spec', 'z_phot', 'z<sub>spec</sub>', 'z<sub>phot</sub>', (0, 4.5), (0, 4.5)), 'UVJ': ('vj', 'uv', '(V-J)', '(U-V)', (-0.1, 2.5), (-0.1, 2.5)), 'UV-redshift': ('z_phot', 'uv', 'z<sub>phot</sub>', '(U-V)<sub>rest</sub>', (0, 4), (-0.1, 2.50)), 'chi2-redshift': ('z_phot', 'chi2', 'z<sub>phot</sub>', 'chi<sup>2</sup>', (0, 4), (0.1, 30)) } if plot_type in self.extra_plots: args = (*self.extra_plots[plot_type], {}, color_kwargs) elif plot_type in plot_defs: args = (*plot_defs[plot_type], {}, color_kwargs) else: args = (*plot_defs['zphot-zspec'], {}, color_kwargs) fig = update_sample_scatter(dff, *args) # Update ranges for some parameters if ('Mass' in plot_type) & ('checked' in mass_checked): fig.update_yaxes(range=mass_range) if ('Mag' in plot_type) & ('checked' in mag_checked): fig.update_yaxes(range=mag_range) if ('redshift' in plot_type) & ('checked' in zphot_checked): fig.update_xaxes(range=zphot_range) if ('zspec' in plot_type) & ('checked' in zspec_checked): fig.update_yaxes(range=zspec_range) return fig def update_sample_scatter(dff, xcol, ycol, x_label, y_label, x_range, y_range, extra, color_kwargs): """ Make scatter plot """ import plotly.graph_objects as go fig = px.scatter( data_frame=dff, x=xcol, y=ycol, custom_data=['id', 'z_phot', 'mass', 'ssfr', 'mag'], **color_kwargs) htempl = '(%{x:.2f}, %{y:.2f}) <br>' htempl += 'id: %{customdata[0]:0d} z_phot: %{customdata[1]:.2f}' htempl += '<br> mag: %{customdata[4]:.1f} ' htempl += 'mass: %{customdata[2]:.2f} ssfr: %{customdata[3]:.2f}' fig.update_traces(hovertemplate=htempl, opacity=0.7) if dff['is_selected'].sum() > 0: dffs = dff[dff['is_selected']] _sel = go.Scatter(x=dffs[xcol], y=dffs[ycol], mode="markers+text", text=[f'{id}' for id in dffs['id']], textposition="bottom center", marker=dict(color='rgba(250,0,0,0.5)', size=20, symbol='circle-open')) fig.add_trace(_sel) fig.update_xaxes(range=x_range, title_text=x_label) fig.update_yaxes(range=y_range, title_text=y_label) fig.update_layout(template=template, autosize=True, showlegend=False, margin=dict(l=0, r=0, b=0, t=20, pad=0, autoexpand=True)) if plot_height is not None: fig.update_layout(height=plot_height) fig.update_traces(marker_showscale=False, selector=dict(type='scatter')) fig.update_coloraxes(showscale=False) if (xcol, ycol) == ('z_spec', 'z_phot'): _one2one = go.Scatter(x=[0, 8], y=[0, 8], mode="lines", marker=dict(color='rgba(250,0,0,0.5)')) fig.add_trace(_one2one) fig.add_annotation(text=f'N = {len(dff)} / {len(self.df)}', xref="x domain", yref="y domain", x=0.98, y=0.05, showarrow=False) return fig def sed_cutout_figure(id_i): """ SED cutout """ from plotly.subplots import make_subplots if cutout_data is not None: ix = np.where(self.df['id'] == id_i)[0] ri, di = self.df['ra'][ix], self.df['dec'][ix] xi, yi = np.squeeze(cutout_wcs.all_world2pix([ri], [di], 0)) xp = int(np.round(xi)) yp = int(np.round(yi)) slx = slice(xp - cutout_size, xp + cutout_size + 1) sly = slice(yp - cutout_size, yp + cutout_size + 1) try: cutout = cutout_data[sly, slx] except: cutout = np.zeros((2 * cutout_size, 2 * cutout_size)) fig = px.imshow(cutout, color_continuous_scale='gray_r') fig.update_coloraxes(showscale=False) fig.update_layout(width=120, height=120, margin=dict(l=0, r=0, b=0, t=0, pad=0, autoexpand=True)) fig.update_xaxes(range=(0, 2 * cutout_size), visible=False, showticklabels=False) fig.update_yaxes(range=(0, 2 * cutout_size), visible=False, showticklabels=False) return fig def parse_id_input(id_input): """ Parse input as id or (ra dec) """ if id_input in ['None', None, '']: return None, None inp_split = id_input.replace(',', ' ').split() if len(inp_split) == 1: return int(inp_split[0]), None ra, dec = np.cast[float](inp_split) cosd = np.cos(self.df['dec'] / 180 * np.pi) dx = (self.df['ra'] - ra) * cosd dy = (self.df['dec'] - dec) dr = np.sqrt(dx**2 + dy**2) * 3600. imin = np.nanargmin(dr) return self.df['id'][imin], dr[imin] @app.callback([ dash.dependencies.Output('object-sed-figure', 'figure'), dash.dependencies.Output('object-info', 'children'), dash.dependencies.Output('match-sep', 'children'), dash.dependencies.Output('cutout-figure', cutout_target) ], [ dash.dependencies.Input('sample-selection-scatter', 'hoverData'), dash.dependencies.Input('sed-unit-selector', 'value'), dash.dependencies.Input('id-input', 'value') ]) def update_object_sed(hoverData, sed_unit, id_input): """ SED + p(z) plot """ id_i, dr_i = parse_id_input(id_input) if id_i is None: id_i = hoverData['points'][0]['customdata'][0] else: if id_i not in self.zout['id']: id_i = hoverData['points'][0]['customdata'][0] if dr_i is None: match_sep = '' else: match_sep = f'{dr_i:.1f}"' show_fnu = {'Fλ': 0, 'Fν': 1, 'νFν': 2} layout_kwargs = dict(template=template, autosize=True, showlegend=False, margin=dict(l=0, r=0, b=0, t=20, pad=0, autoexpand=True)) fig = self.photoz.show_fit_plotly(id_i, show_fnu=show_fnu[sed_unit], vertical=True, panel_ratio=[0.6, 0.4], show=False, layout_kwargs=layout_kwargs) if plot_height is not None: fig.update_layout(height=plot_height) ix = self.df['id'] == id_i if ix.sum() == 0: object_info = 'ID: N/A' else: ix = np.where(ix)[0][0] ra, dec = self.df['ra'][ix], self.df['dec'][ix] object_info = [ f'ID: {id_i} | α, δ = {ra:.6f} {dec:.6f} ', ' | ', html.A('ESO', href=utils.eso_query(ra, dec, radius=1.0, unit='s')), ' | ', html.A('CDS', href=utils.cds_query(ra, dec, radius=1.0, unit='s')), ' | ', html.A('LegacySurvey', href=utils.show_legacysurvey(ra, dec, layer='ls-dr9')), html.Br(), f"z_phot: {self.df['z_phot'][ix]:.3f} ", f" | z_spec: {self.df['z_spec'][ix]:.3f}", html.Br(), f"mag: {self.df['mag'][ix]:.2f} ", f" | mass: {self.df['mass'][ix]:.2f} ", f" | sSFR: {self.df['ssfr'][ix]:.2f}", html.Br() ] if cutout_data is None: cutout_fig = [''] else: cutout_fig = sed_cutout_figure(id_i) return fig, object_info, match_sep, cutout_fig if server_mode is not None: app.run_server(mode=server_mode, port=port) return app
def graph(G, mode="external", **kwargs): """ G: a multidirectional graph kwargs are passed to the Jupyter_Dash.run_server() function. Some usefull arguments are: mode: "inline" to run app inside the jupyter nodebook, default is external debug: True or False, Usefull to catch errors during development. """ import dash from jupyter_dash import JupyterDash import dash_cytoscape as cyto from dash.dependencies import Output, Input import dash_html_components as html import dash_core_components as dcc import dash_table import networkx as nx import scConnect as cn import plotly.graph_objs as go import plotly.io as pio import pandas as pd import numpy as np import json import matplotlib import matplotlib.pyplot as plt pio.templates.default = "plotly_white" cyto.load_extra_layouts() JupyterDash.infer_jupyter_proxy_config() app = JupyterDash(__name__) server = app.server # Add a modified index string to change the title to scConnect app.index_string = ''' <!DOCTYPE html> <html> <head> {%metas%} <title>scConnect</title> {%favicon%} {%css%} </head> <body> {%app_entry%} <footer> {%config%} {%scripts%} {%renderer%} </body> </html> ''' # Add colors to each node nodes = pd.Categorical(G.nodes()) # make a list of RGBA tuples, one for each node colors = plt.cm.tab20c(nodes.codes / len(nodes.codes), bytes=True) # zip node to color color_map_nodes = dict(zip(nodes, colors)) # add these colors to original graph for node, color in color_map_nodes.items(): G.nodes[node]["color"] = color[0:3] # Save only RGB # Add colors to edges(source node color) for G for u, v, k in G.edges(keys=True): G.edges[u, v, k]["color"] = color_map_nodes[u][0:3] # load graph into used formes def G_to_flat(G, weight): G_flat = cn.graph.flatten_graph(G, weight=weight, log=True) # Add colors to edges(source node color) for G_flat for u, v, in G_flat.edges(): G_flat.edges[u, v]["color"] = color_map_nodes[u][0:3] return G_flat # produce full graph variante to extract metadata G_flat = G_to_flat(G, weight="score") G_split = cn.graph.split_graph(G) # find and sort all found interactions interactions = list(G_split.keys()) interactions.sort() G_cyto = nx.cytoscape_data(G_flat) # get min and max weight for all edges for flat and normal graph #weights = [d["weight"] for u, v, d in G_flat.edges(data=True)] scores = [d["score"] for u, v, d in G.edges(data=True)] cent = [d["centrality"] for n, d in G.nodes(data=True)] # prepare data for network graph nodes = G_cyto["elements"]["nodes"] elements = [] # collect all available genes genes = list(nodes[0]["data"]["genes"].keys()) # Styling parameters font_size = 20 # Style for network graph default_stylesheet = [{ 'selector': 'node', 'style': { 'background-color': 'data(color)', 'label': 'data(id)', 'shape': 'ellipse', 'opacity': 1, 'font-size': f'{font_size}', 'font-weight': 'bold', 'text-wrap': 'wrap', 'text-max-width': "100px", 'text-opacity': 1, 'text-outline-color': "white", 'text-outline-opacity': 1, 'text-outline-width': 2 } }, { 'selector': 'node:selected', 'style': { 'background-color': 'data(color)', 'label': 'data(id)', 'shape': 'ellipse', 'opacity': 1, 'border-color': "black", 'border-width': "5" } }, { 'selector': 'edge', 'style': { 'line-color': 'data(color)', "opacity": 0.7, "curve-style": "unbundled-bezier", "width": "data(weight)", "target-arrow-shape": "vee", "target-arrow-color": "black", 'z-index': 1, 'font-size': f'{font_size}' } }, { 'selector': 'edge:selected', 'style': { 'line-color': 'red', 'line-style': "dashed", 'opacity': 1, 'z-index': 10, } }] app.layout = html.Div( className="wrapper", children=[ # wrapper html.Div( className="header", children=[ # header html.Img(src="assets/logo.png", alt="scConnect logo"), html.Div( className="graph-info", id="graph-stat", children=[ html. H3(f'Loaded graph with {len(G.nodes())} nodes and {len(G.edges())} edges' ) ]) ]), html.Div( className="network-settings", children=[ # network settings html.H2("Network settings", style={"text-align": "center"}), html.Label("Interactions"), dcc.Dropdown(id="network-interaction", options=[{ 'label': "all interactions", 'value': "all" }] + [{ 'label': interaction, 'value': interaction } for interaction in interactions], value="all"), # select if only significant ligands and receptors should be shown html.Label("Graph weight:"), dcc.RadioItems(id="weight-select", options=[{ "label": "Score", "value": "score" }, { "label": "Log score", "value": "log_score" }, { "label": "Specificity", "value": "specificity" }, { "label": "Importance", "value": "importance" }], value="importance", labelStyle={ 'display': 'block', "margin-left": "50px" }, style={ "padding": "10px", "margin": "auto" }), html.Label("Graph Layout"), dcc.Dropdown( id="network-layout", options=[{ 'label': name.capitalize(), 'value': name } for name in [ 'grid', 'random', 'circle', 'cose', 'concentric', 'breadthfirst', 'cose-bilkent', 'cola', 'euler', 'spread', 'dagre', 'klay' ]], value="circle", clearable=False), html.Label("Weight Filter", style={ "paddingBottom": 500, "paddingTop": 500 }), dcc. Slider( # min, max and value are set dynamically via a callback id="network-filter", step=0.001, updatemode="drag", tooltip={ "always_visible": True, "placement": "right" }, ), html.Label("Node size"), dcc.RangeSlider(id="node-size", value=[10, 50], min=0, max=100, updatemode="drag"), html.Label("Select gene"), dcc.Dropdown( id="gene_dropdown", options=[{ "label": gene, "value": gene } for gene in genes], clearable=True, placeholder="Color by gene expression", ), # Store node colors "hidden" for gene expresison html.Div(id="node-colors", style={"display": "none"}, children=[""]), html.Div(id="min-max", children=[]), # Click to download image of network graph html.Button(children="Download current view", id="download-network-graph", style={"margin": "10px"}) ]), # end network settings html.Div( id="network-graph", className="network-graph", children=[ # network graph html.H2("Network graph", style={"text-align": "center"}), cyto.Cytoscape(id="cyto-graph", style={ 'width': '100%', 'height': '80vh' }, stylesheet=default_stylesheet, elements=elements, autoRefreshLayout=True, zoomingEnabled=False) ]), # end network graph html.Div( className="sankey-settings", children=[ # network settings html.H2("Sankey Settings", style={"text-align": "center"}), html.Label("Weight Filter"), dcc.Slider(id="sankey-filter", min=min(scores), max=max(scores), value=0.75, step=0.001, updatemode="drag", tooltip={ "always_visible": True, "placement": "right" }), html.Label("Toggle weighted"), dcc.RadioItems(id="sankey-toggle", options=[{ "label": "Score", "value": "score" }, { "label": "Log score", "value": "log_score" }, { "label": "Specificity", "value": "specificity" }, { "label": "Importance", "value": "importance" }], value="importance", labelStyle={"display": "block"}) ]), # end network settings html.Div( className="sankey", id="sankey", children=[ # sankey graph html.H2("Sankey graph", style={"text-align": "center"}), dcc.Graph(id="sankey-graph") ]), # end sankey graph html.Div( className="interaction-list", children=[ # interaction list html.Div(id="selection", children=[ html.H2("Interactions", style={"text-align": "center"}), html.H3(id="edge-info", style={"text-align": "center"}), dcc.Graph(id="interaction-scatter"), html.Div(id="interaction-selection", style={"display": "none"}, children=[""]) ]), html.Div(children=[ dash_table.DataTable( id="edge-selection", page_size=20, style_table={ "overflowX": "scroll", "overflowY": "scroll", "height": "50vh", "width": "95%" }, style_cell_conditional=[{ "if": { "column_id": "interaction" }, "textAlign": "left" }, { "if": { "column_id": "receptorfamily" }, "textAlign": "left" }, { "if": { "column_id": "pubmedid" }, "textAlign": "left" }], style_header={ "fontWeight": "bold", "maxWidth": "200px", "minWidth": "70px" }, style_data={ "maxWidth": "200px", "minWidth": "70px", "textOverflow": "ellipsis" }, sort_action="native", fixed_rows={ 'headers': True, 'data': 0 }) ]) ]), # end interaction list html.Div( className="L-R-scores", children=[ # ligand and receptor lists html.H2("Ligand and receptors", style={"text-align": "center"}), html.Div(children=[ html.H3( id="selected-node", style={"text-align": "center"}, children=["Select a node in the notwork graph"]), html.Label("Search for ligands and receptors:", style={"margin-right": "10px"}), dcc.Input(id="filter_l_r", type="search", value="", placeholder="Search") ]), dcc.Tabs([ dcc.Tab(label="Ligands", children=[ dcc.Graph(id="ligand-graph", config=dict(autosizable=True, responsive=True)), dash_table.DataTable( id="ligand-table", page_size=20, style_table={ "overflowX": "scroll", "overflowY": "scroll", "height": "50vh", "width": "95%" }, style_cell_conditional=[{ "if": { "column_id": "Ligand" }, "textAlign": "left" }], style_header={ "fontWeight": "bold", "maxWidth": "200px", "minWidth": "70px" }, style_data={ "maxWidth": "200px", "minWidth": "70px", "textOverflow": "ellipsis" }, sort_action="native", fixed_rows={ 'headers': True, 'data': 0 }) ]), dcc.Tab(label="Receptors", children=[ dcc.Graph(id="receptor-graph", config=dict(autosizable=True, responsive=True)), dash_table.DataTable( id="receptor-table", page_size=20, style_table={ "overflowX": "scroll", "overflowY": "scroll", "height": "50vh", "width": "95%" }, style_cell_conditional=[{ "if": { "column_id": "Receptor" }, "textAlign": "left" }], style_header={ "fontWeight": "bold", "maxWidth": "200px", "minWidth": "70px" }, style_data={ "maxWidth": "200px", "minWidth": "70px", "textOverflow": "ellipsis" }, sort_action="native", fixed_rows={ 'headers': True, 'data': 0 }) ]) ]) ]) # end ligand receptor list ]) # end wrapper # Instantiate the graph and produce the bounderies for filters @app.callback([ Output("cyto-graph", "elements"), Output("network-filter", "min"), Output("network-filter", "max"), Output("network-filter", "value") ], [ Input("network-interaction", "value"), Input("weight-select", "value") ]) def make_graph(interaction, score): G_flat = G_to_flat(G, score) if interaction == "all": # if no interaction is selected, use full graph G_cyto = nx.cytoscape_data(G_flat) weights = [d["weight"] for u, v, d in G_flat.edges(data=True)] # prepare data for network graph nodes = G_cyto["elements"]["nodes"] edges = G_cyto["elements"]["edges"] elements = nodes + edges return elements, min(weights), max(weights), np.mean(weights) else: # an interaction is selected, select only that interaction G_split = cn.graph.split_graph(G) G_split_flat = G_to_flat(G_split[interaction], score) G_cyto = nx.cytoscape_data(G_split_flat) weights = [ d["weight"] for u, v, d in G_split_flat.edges(data=True) ] # prepare data for network graph nodes = G_cyto["elements"]["nodes"] edges = G_cyto["elements"]["edges"] elements = nodes + edges return elements, min(weights), max(weights), np.mean(weights) # Change layout of network graph @app.callback(Output("cyto-graph", "layout"), [Input("network-layout", "value")]) def update_network_layout(layout): return {"name": layout, "automate": True, "fit": True} # Choose gene to color nodes by @app.callback( [Output("node-colors", "children"), Output("min-max", "children")], [Input("gene_dropdown", "value")]) def calculate_colors(gene): if gene is None: return [None, ""] # get all gene expression values for selected gene gene_data = { celltype["data"]["id"]: celltype["data"]["genes"][gene] for celltype in nodes } min_value = min(gene_data.values()) max_value = max(gene_data.values()) # package min max expression information to a list that will be returned expression = html.Ul(children=[ html.Li(f"minimum gene expression: {min_value}"), html.Li(f"maximum gene expression: {max_value}") ]) cmap = matplotlib.cm.get_cmap("coolwarm") color_dict = dict() for k, v in gene_data.items(): color_dict[k] = {"rgb": cmap(v, bytes=True)[0:3], "expression": v} color = pd.Series(color_dict) return color.to_json(), expression # Select visible edges of network graph depending on filter value # node color depending on selected gene # width of edges @app.callback(Output("cyto-graph", "stylesheet"), [ Input("network-filter", "value"), Input("network-filter", "min"), Input("network-filter", "max"), Input("node-size", "value"), Input("node-colors", "children") ]) def style_network_graph(th, min_weight, max_weight, size, colors): # create a filter for edges filter_style = [{ "selector": f"edge[weight < {th}]", "style": { "display": "none" } }, { "selector": "node", "style": { 'height': f'mapData(centrality, {min(cent)}, {max(cent)}, {size[0]}, {size[1]})', 'width': f'mapData(centrality, {min(cent)}, {max(cent)}, {size[0]}, {size[1]})' } }] # create a color style for nodes based on gene expression if isinstance(colors, str): colors = pd.read_json(colors, typ="series", convert_dates=False) color_style = [{ 'selector': f'node[id = "{str(index)}"]', 'style': { 'background-color': f'rgb{tuple(colors[index]["rgb"])}' } } for index in colors.index] filter_style += color_style else: color_style = { "selector": "node", "style": { 'background-color': 'BFD7B5' } } # Map edges width to a set min and max value (scale for visibility) edge_style = [{ "selector": "edge", "style": { "width": f"mapData(weight, {min_weight}, {max_weight}, 1, 10)" } }] return default_stylesheet + filter_style + edge_style # download an image of current network graph view @app.callback(Output("cyto-graph", "generateImage"), Input("download-network-graph", "n_clicks")) def download_networkgraph_image(get_request): if get_request == None: return dict() return {"type": "svg", "action": "download"} # Produce a table of all edge data from tapped edge @app.callback([ Output("edge-info", "children"), Output("edge-selection", "columns"), Output("edge-selection", "data") ], [ Input("cyto-graph", "tapEdgeData"), Input("interaction-selection", "children") ]) def update_data(edge, selection): import pandas as pd import json # check if an edge has really been clicked, return default otherwise if edge is None: return ["", None, None] info = f"Interactions from {edge['source']} to {edge['target']}." # map visible names for columns with columns in edge[interaction] columns = [{ "name": "Interaction", "id": "interaction" }, { "name": "Receptor Family", "id": "receptorfamily" }, { "name": "Score", "id": "score" }, { "name": "Log10(score)", "id": "log_score" }, { "name": "Specificity", "id": "specificity" }, { "name": "Importance", "id": "importance" }, { "name": "Ligand z-score", "id": "ligand_zscore" }, { "name": "Ligand p-value", "id": "ligand_pval" }, { "name": "Receptor z-score", "id": "receptor_zscore" }, { "name": "Receptor p-value", "id": "receptor_pval" }, { "name": "PubMed ID", "id": "pubmedid" }] interactions = pd.DataFrame(edge["interactions"])[[ "interaction", "receptorfamily", "score", "log_score", "specificity", "importance", "ligand_zscore", "ligand_pval", "receptor_zscore", "receptor_pval", "pubmedid" ]] # Sort values based on score interactions.sort_values(by="score", ascending=False, inplace=True) # round values for scores to two decimals interactions[[ "score", "log_score", "specificity", "importance", "ligand_zscore", "receptor_zscore" ]] = interactions[[ "score", "log_score", "specificity", "importance", "ligand_zscore", "receptor_zscore" ]].round(decimals=2) interactions[["ligand_pval", "receptor_pval" ]] = interactions[["ligand_pval", "receptor_pval"]].round(decimals=4) # if selection from interaction graph, filter dataframe if selection != "": selection = json.loads(selection) interactions = interactions.loc[interactions["interaction"].isin( selection)] records = interactions.to_dict("records") return [info, columns, records] @app.callback([Output("interaction-scatter", "figure")], [Input("cyto-graph", "tapEdgeData")]) def interaction_scatter_plot(edge): import plotly.express as px fig = go.Figure() if not isinstance(edge, dict): return [ fig, ] interactions = pd.DataFrame(edge["interactions"])[[ "interaction", "receptorfamily", "score", "log_score", "ligand_zscore", "ligand_pval", "receptor_zscore", "receptor_pval", "specificity", "importance", "pubmedid" ]] # add 10% to the min and max value to not clip the datapoint range_x = (-max(interactions["log_score"]) * 0.1, max(interactions["log_score"]) * 1.1) range_y = (-max(interactions["specificity"]) * 0.1, max(interactions["specificity"]) * 1.1) #interactions["specificity"] = np.log10( interactions["specificity"]) fig = px.scatter(interactions, x="log_score", range_x=range_x, y="specificity", range_y=range_y, color="importance", hover_name="interaction", hover_data=[ "ligand_pval", "receptor_pval", "score", "specificity", "receptorfamily" ], color_continuous_scale=px.colors.sequential.Viridis_r, labels={ "ligand_zscore": "Ligand Z-score", "receptor_zscore": "Receptor Z-score", "log_score": "log(Interaction score)", "score": "Interaction score", "specificity": "Specificity", "importance": "Importance", "receptorfamily": "Receptor family", "pubmedid": "PubMed ID", "ligand_pval": "Ligand p-value", "receptor_pval": "Receptor p-value" }) return [ fig, ] @app.callback(Output("interaction-selection", "children"), [Input("interaction-scatter", "selectedData")]) def interaction_select(selected_data): import json if isinstance(selected_data, dict): interactions = [ point["hovertext"] for point in selected_data["points"] ] else: return "" return json.dumps(interactions) # Produce ligand and receptor graphs based on tapped node @app.callback([ Output("ligand-graph", "figure"), Output("receptor-graph", "figure"), Output("selected-node", "children") ], [Input("cyto-graph", "tapNodeData"), Input("filter_l_r", "value")]) def plot_l_r_expression(node, filter_text): # set output variables to empty figures ligand_fig = go.Figure() receptor_fig = go.Figure() node_id = "Select a node in the network graph" if isinstance(node, dict): import plotly.express as px node_id = node["id"] ligands_score = pd.DataFrame.from_dict(node["ligands_score"], orient="index", columns=["Score"]) ligands_zscore = np.log2( pd.DataFrame.from_dict(node["ligands_zscore"], orient="index", columns=["Z-score"])) ligands_corr_pval = pd.DataFrame.from_dict( node["ligands_corr_pval"], orient="index", columns=["p-value"]) ligands_merge = ligands_score.merge(ligands_zscore, how="left", left_index=True, right_index=True) ligands_merge = ligands_merge.merge(ligands_corr_pval, how="left", left_index=True, right_index=True) ligands_merge["log(score + 1)"] = np.log10(ligands_merge["Score"] + 1) ligands_merge["Significant"] = [ True if p_val < 0.05 else False for p_val in ligands_merge["p-value"] ] ligands_merge["-log(p-value)"] = -np.log10( ligands_merge["p-value"]) if filter_text != "": ligands_merge = ligands_merge.filter(like=filter_text, axis=0) ligand_fig = px.scatter(ligands_merge, x="log(score + 1)", y="-log(p-value)", color="Significant", hover_name=ligands_merge.index, hover_data=["Score", "Z-score", "p-value"]) receptors_score = pd.DataFrame.from_dict(node["receptors_score"], orient="index", columns=["Score"]) receptors_zscore = np.log2( pd.DataFrame.from_dict(node["receptors_zscore"], orient="index", columns=["Z-score"])) receptors_corr_pval = pd.DataFrame.from_dict( node["receptors_corr_pval"], orient="index", columns=["p-value"]) receptors_merge = receptors_score.merge(receptors_zscore, how="left", left_index=True, right_index=True) receptors_merge = receptors_merge.merge(receptors_corr_pval, how="left", left_index=True, right_index=True) receptors_merge["log(score + 1)"] = np.log10( receptors_merge["Score"] + 1) receptors_merge["Significant"] = [ True if p_val < 0.05 else False for p_val in receptors_merge["p-value"] ] receptors_merge["-log(p-value)"] = -np.log10( receptors_merge["p-value"]) if filter_text != "": receptors_merge = receptors_merge.filter(like=filter_text, axis=0) receptor_fig = px.scatter( receptors_merge, x="log(score + 1)", y="-log(p-value)", color="Significant", hover_name=receptors_merge.index, hover_data=["Score", "Z-score", "p-value"]) return [ligand_fig, receptor_fig, node_id] # Builds a sankey graph based on the tapped node (store in global G_s) G_s = nx.MultiDiGraph() #variable holding sankey graph @app.callback([ Output("sankey-filter", "min"), Output("sankey-filter", "max"), Output("sankey-filter", "value") ], [Input("cyto-graph", "tapNodeData"), Input("sankey-toggle", "value")]) def build_sankey_graph(node, score): import numpy as np # If no node has been selected, dont try to build graph if node is None: return (0, 0, 0) node = node["id"] # Find all interactions where node is target or source node nonlocal G_s G_s = nx.MultiDiGraph() # reset content weight = list( ) # list to store all weights (used to set min and max for the filter) for n, nbrs in G.adj.items( ): # graph has been modified by network graph before for nbr, edict in nbrs.items(): if n == node: for e, d in edict.items(): G_s.add_edge(n, " Post " + nbr, **d) weight.append(d[score]) if nbr == node: for e, d in edict.items(): G_s.add_edge("Pre " + n, nbr, **d) weight.append(d[score]) if len(weight) == 0: weight = [0, 1] if score == "specificity": # set default start value to specificity value for ligand and receptor # p-value of (0.05 and 0.05)/2 = 1.3 return (min(weight), max(weight), 1.3) return (min(weight), max(weight), np.mean(weight)) @app.callback(Output("sankey-graph", "figure"), [ Input("sankey-filter", "value"), Input("sankey-toggle", "value"), Input("cyto-graph", "tapNodeData") ]) def filter_sankey_graph(th, score, node): if node: node = node["id"] _G_s = nx.MultiDiGraph() for u, v, n, d in G_s.edges(data=True, keys=True): if d[score] > th: _G_s.add_edge(u, v, n, **d) _G_s.add_nodes_from(G_s.nodes(data=True)) edges = nx.to_pandas_edgelist(_G_s) if len(edges) < 1: fig = dict() return fig # add same color scheme as network graph for node_s in _G_s.nodes(): if " Post" in node_s: original_node = str(node_s).split(sep=" Post")[1] elif "Pre " in node_s: original_node = str(node_s).split(sep="Pre ")[1] else: original_node = str(node_s) new_color = color_map_nodes[original_node.strip()] G_s.nodes[node_s]["color"] = new_color nodes = G_s.nodes() node_map = {cluster: id for id, cluster in enumerate(list(nodes))} sankey = go.Sankey(node=dict(pad=15, thickness=20, line=dict(color="black", width=0.5), label=list(nodes), color=[ f'rgb{tuple(d["color"][0:3])}' for n, d in G_s.nodes(data=True) ]), link=dict( source=list(edges["source"].map(node_map)), target=list(edges["target"].map(node_map)), value=list(edges[score]), label=edges["interaction"])) data = [sankey] layout = go.Layout(autosize=True, title=f"Interactions: {node}", font=dict(size=font_size)) fig = go.Figure(data=data, layout=layout) return fig @app.callback( [Output("ligand-table", "columns"), Output("ligand-table", "data")], [ Input("ligand-graph", "figure"), Input("ligand-graph", "selectedData") ]) def select_ligands(figure, selected): import json ligands = [] score = [] zscore = [] pval = [] for group in figure["data"]: for ligand in group["hovertext"]: ligands.append(ligand) for data in group["customdata"]: score.append(data[0]) zscore.append(data[1]) pval.append(data[2]) df = pd.DataFrame({ "Ligand": ligands, "Score": score, "Z-score": zscore, "P-value": pval }) df.index = df["Ligand"] df.sort_values(by="Score", ascending=False, inplace=True) if isinstance(selected, dict): filt = [] for point in selected["points"]: filt.append(point["hovertext"]) df = df.loc[filt] columns = [{ "name": "Ligand", "id": "Ligand" }, { "name": "Score", "id": "Score" }, { "name": "Z-score", "id": "Z-score" }, { "name": "P-value", "id": "P-value" }] data = df.to_dict("records") return columns, data @app.callback([ Output("receptor-table", "columns"), Output("receptor-table", "data") ], [ Input("receptor-graph", "figure"), Input("receptor-graph", "selectedData") ]) def select_ligands(figure, selected): import json receptors = [] score = [] zscore = [] pval = [] for group in figure["data"]: for receptor in group["hovertext"]: receptors.append(receptor) for data in group["customdata"]: score.append(data[0]) zscore.append(data[1]) pval.append(data[2]) df = pd.DataFrame({ "Receptor": receptors, "Score": score, "Z-score": zscore, "P-value": pval }) df.index = df["Receptor"] df.sort_values(by="Score", ascending=False, inplace=True) if isinstance(selected, dict): filt = [] for point in selected["points"]: filt.append(point["hovertext"]) df = df.loc[filt] columns = [{ "name": "Receptor", "id": "Receptor" }, { "name": "Score", "id": "Score" }, { "name": "Z-score", "id": "Z-score" }, { "name": "P-value", "id": "P-value" }] data = df.to_dict("records") return columns, data # Run server app.run_server(**kwargs)
for feature in counties["features"]: feature['id'] = str(feature['properties']['COUNTY']) # Build App app = JupyterDash(__name__) app.layout = html.Div([ html.H1("RHEAS-DSSAT Demo"), dcc.Dropdown(id='fcst-dropdown', clearable=False, value='fcst_dates', options=[{ 'label': f, 'value': f } for f in df['fcst_date'].unique()]), dcc.Graph(id='map'), dcc.Graph(id='graph'), dcc.Dropdown(id='cnty-dropdown', clearable=False, value='fcst_dates', options=[{ 'label': c, 'value': c } for c in df['County'].unique()]), dcc.Graph(id='plot'), ]) # Define callback to update graph @app.callback(Output('map', 'figure'), [Input("fcst-dropdown", "value")]) def update_figure(fcst_date): filtered_df = df[df.fcst_date == fcst_date]
app.layout = html.Div( children=[ html.Div(className="w3-bar w3-top w3-large w3-amber", style={"z-index":4}, children=[ html.Button(" Menu", id="open-menu-button", n_clicks=0, className= "w3-bar-item w3-button w3-hide-large w3-hover-none w3-hover-text-light-grey fa fa-bars"), html.Span(' กัมมันตภาพรังสีในสิ่งแวดล้อมรอบ สทน. ทั้ง 3 แห่ง', className='w3-bar-item w3-right fa fa-dashboard fa-lg')] ), html.Nav(id="mySidebar", className="w3-mobile w3-sidebar w3-collapse w3-sand w3-animate-left", style={"z-index":4, "width":"200px"}, children=[ # html.Button("Close ×", id="close-menu-button", n_clicks=0, className="w3-bar-item w3-button w3-large w3-hide-large"), html.Div(className="w3-container", children=[ # html.I(className="fa fa-institution"), html.Span(" สาขา",className="fa fa-institution") ]), html.Div(className="w3-bar-block", children=[ html.Div(className="w3-bar-item", children=[ dcc.RadioItems( id='site-radio', options=[{'label': i, 'value': i} for i in all_options.keys()], value='คลองห้า', labelStyle={'display':'block'} ) ]), html.Div(className="w3-container", children=[ # html.I(className="fa fa-flask"), html.Span(" ชนิดตัวอย่าง",className="fa fa-flask") ]), html.Div(className='w3-bar-block w3-padding', children=[ dcc.Dropdown(id='sample-dropdown',clearable=False) ]) ]) ]), html.Div(className="w3-main",style={'margin-left':200, 'margin-top':43}, children=[ html.Div(className="w3-row-padding w3-margin-bottom", children=[ html.Div(className="w3-half", children=[ html.Div(className="w3-container w3-card w3-animate-top w3-padding-16", children=[ dcc.Graph(config=config,id='fig_1') ]) ]), html.Div(className="w3-half", children=[ html.Div(className="w3-container w3-card w3-animate-top w3-padding-16", children=[ dcc.Graph(config=config,id='fig_2') ]) ]) ]), html.Div(className="w3-card w3-animate-right w3-margin-top w3-margin-bottom w3-padding-small",children=[dcc.Graph(figure=place_map)]), html.Div( html.Span(className="w3-bar-item w3-text-grey w3-light-grey w3-right", children= "สำรวจและจัดทำโดย: ฝ่ายความปลอดภัยด้านนิวเคลียร์ สถาบันเทคโนโลยีนิวเคลียร์แห่งชาติ (องค์การมหาชน)"), className="w3-bar w3-panel w3-bottom" ) ]) ])
# # Dash creates an app server that hosts the plot. The server is typically found on port 8050, but can be configured by the user. Host is set to 0.0.0.0 to allow access externally or via an ssh tunnel. # %% external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css'] app = JupyterDash(__name__, external_stylesheets=external_stylesheets) styles = { 'pre': { 'border': 'thin lightgrey solid', 'overflowX': 'scroll' } } app.layout = html.Div(children=[ html.H1(children='HDB resale data by sector'), filter_buttons, plot_buttons, dcc.Graph(id='choropleth_element', figure=chorofig, style={'width': '60%', 'display': 'inline-block'}), dcc.Graph(id='timeseries_element', figure=tsfig, style={'width': '38%','display': 'inline-block'}), ]) if __name__ == '__main__': app.run_server(debug=True, host='0.0.0.0', port='8050') # %% [markdown] # ## Configure callback # # Callback determines how a figure changes when user input changes. Any function can be designated as a callback function using the decorator `@app.callback`. The argumernts and outputs of the function should match the inputs, states and outputs of the decorator as we discuess below. Note that each output callback can only be linked to a single function, i.e. Dash does not allow multiple callback functions to share the same output. # # `Input` triggers the callback function whenever it detects a change in a target element property. `State` on the other hand 'stores' the changes, but does not trigger the callback. `Output` write the output of the function to a target HTML element. `Output`, `Input` and `State` accepts two arguments, the first is 'id' element, and the second is a property of the element to read or write from. The number of arguments in the callback function should be the sum of `Input` and `State` in the same order, no more no less. The equality must hold even if we don't use the values (such as `'n_clicks'` from buttons) from the inputs. Likewise, the number of values returned by the function should equal the number of `Output` in the callback. # # # For callback functions with multiple inputs, it may be necessary to identify the input that triggered the callback. We can use dash.callback_context to identify the specific input element and property that triggered the most recent callback, and tailor the response accordingly.
def create_app(available_indicators, df): external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css'] app = JupyterDash(__name__, external_stylesheets=external_stylesheets) # Create server variable with Flask server object for use with gunicorn server = app.server app.layout = html.Div([ html.Div( [ html.Div([ dcc.Dropdown( id='crossfilter-xaxis-column', options=[{ 'label': i, 'value': i } for i in available_indicators], value='Fertility rate, total (births per woman)'), dcc.RadioItems(id='crossfilter-xaxis-type', options=[{ 'label': i, 'value': i } for i in ['Linear', 'Log']], value='Linear', labelStyle={'display': 'inline-block'}) ], style={ 'width': '49%', 'display': 'inline-block' }), html.Div([ dcc.Dropdown( id='crossfilter-yaxis-column', options=[{ 'label': i, 'value': i } for i in available_indicators], value='Life expectancy at birth, total (years)'), dcc.RadioItems(id='crossfilter-yaxis-type', options=[{ 'label': i, 'value': i } for i in ['Linear', 'Log']], value='Linear', labelStyle={'display': 'inline-block'}) ], style={ 'width': '49%', 'float': 'right', 'display': 'inline-block' }) ], style={ 'borderBottom': 'thin lightgrey solid', 'backgroundColor': 'rgb(250, 250, 250)', 'padding': '10px 5px' }), html.Div([ dcc.Graph(id='crossfilter-indicator-scatter', hoverData={'points': [{ 'customdata': 'Japan' }]}) ], style={ 'width': '49%', 'display': 'inline-block', 'padding': '0 20' }), html.Div([ dcc.Graph(id='x-time-series'), dcc.Graph(id='y-time-series'), ], style={ 'display': 'inline-block', 'width': '49%' }), html.Div(dcc.Slider( id='crossfilter-year--slider', min=df['Year'].min(), max=df['Year'].max(), value=df['Year'].max(), marks={str(year): str(year) for year in df['Year'].unique()}, step=None), style={ 'width': '49%', 'padding': '0px 20px 20px 20px' }) ]) @app.callback( dash.dependencies.Output('crossfilter-indicator-scatter', 'figure'), [ dash.dependencies.Input('crossfilter-xaxis-column', 'value'), dash.dependencies.Input('crossfilter-yaxis-column', 'value'), dash.dependencies.Input('crossfilter-xaxis-type', 'value'), dash.dependencies.Input('crossfilter-yaxis-type', 'value'), dash.dependencies.Input('crossfilter-year--slider', 'value') ]) def update_graph(xaxis_column_name, yaxis_column_name, xaxis_type, yaxis_type, year_value): dff = df[df['Year'] == year_value] return { 'data': [ dict( x=dff[dff['Indicator Name'] == xaxis_column_name]['Value'], y=dff[dff['Indicator Name'] == yaxis_column_name]['Value'], text=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'], customdata=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'], mode='markers', marker={ 'size': 25, 'opacity': 0.7, 'color': 'orange', 'line': { 'width': 2, 'color': 'purple' } }) ], 'layout': dict(xaxis={ 'title': xaxis_column_name, 'type': 'linear' if xaxis_type == 'Linear' else 'log' }, yaxis={ 'title': yaxis_column_name, 'type': 'linear' if yaxis_type == 'Linear' else 'log' }, margin={ 'l': 40, 'b': 30, 't': 10, 'r': 0 }, height=450, hovermode='closest') } def create_time_series(dff, axis_type, title): return { 'data': [dict(x=dff['Year'], y=dff['Value'], mode='lines+markers')], 'layout': { 'height': 225, 'margin': { 'l': 20, 'b': 30, 'r': 10, 't': 10 }, 'annotations': [{ 'x': 0, 'y': 0.85, 'xanchor': 'left', 'yanchor': 'bottom', 'xref': 'paper', 'yref': 'paper', 'showarrow': False, 'align': 'left', 'bgcolor': 'rgba(255, 255, 255, 0.5)', 'text': title }], 'yaxis': { 'type': 'linear' if axis_type == 'Linear' else 'log' }, 'xaxis': { 'showgrid': False } } } @app.callback(dash.dependencies.Output('x-time-series', 'figure'), [ dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData'), dash.dependencies.Input('crossfilter-xaxis-column', 'value'), dash.dependencies.Input('crossfilter-xaxis-type', 'value') ]) def update_y_timeseries(hoverData, xaxis_column_name, axis_type): country_name = hoverData['points'][0]['customdata'] dff = df[df['Country Name'] == country_name] dff = dff[dff['Indicator Name'] == xaxis_column_name] title = '<b>{}</b><br>{}'.format(country_name, xaxis_column_name) return create_time_series(dff, axis_type, title) @app.callback(dash.dependencies.Output('y-time-series', 'figure'), [ dash.dependencies.Input('crossfilter-indicator-scatter', 'hoverData'), dash.dependencies.Input('crossfilter-yaxis-column', 'value'), dash.dependencies.Input('crossfilter-yaxis-type', 'value') ]) def update_x_timeseries(hoverData, yaxis_column_name, axis_type): dff = df[df['Country Name'] == hoverData['points'][0]['customdata']] dff = dff[dff['Indicator Name'] == yaxis_column_name] return create_time_series(dff, axis_type, yaxis_column_name) return app
app.layout = html.Div(children=[ # TODO1: Add title to the dashboard html.H1('US Travel Dash', style={ 'textAlign': 'center', 'color': '#503D36', 'font-size': 24 }), # REVIEW2: Dropdown creation # Create an outer division html.Div([ # Add an division html.Div( [ # Create an division for adding dropdown helper text for report type html.Div([ html.H2('US State:', style={'margin-right': '2em'}), ]), # TODO2: Add a dropdown dcc.Dropdown(id='input-state', options=[{ 'label': i, 'value': i } for i in states_list], placeholder='Select State', style={ 'width': '80%', 'padding': '3px', 'font-size': '20px', 'text-align-last': 'center' }) # Place them next to each other using the division style ], style={'display': 'flex'}), ]), # Add Computed graphs # REVIEW3: Observe how we add an empty division and providing an id that will be updated during callback html.Div(dcc.Graph(figure=fig)), html.Div([ html.Div([ html.H2('Cell Service:', style={'margin-right': '2em'}), html.H2( [], id='plot1', style={ 'textAlign': 'center', 'color': '#503D36', 'font-size': 24, 'margin-right': '2em' }) ]), html.Div([ html.H2('Unique Venue Types:', style={'margin-right': '2em'}), html.H2( [], id='plot2', style={ 'textAlign': 'center', 'color': '#503D36', 'font-size': 24, 'margin-right': '2em' }) ]) ], style={'display': 'flex'}), html.Div([], style={'display': 'flex'}) ])
def __init__(self, model, N_handles=4): self.model = model # Generate an initial state init_state = dict( signal_mode='sin', # sin, am, fm, qpsk_bb, or qpsk_if fc=20000, fm=2000, agc_ref=0.7, agc_alpha=0.6, agc_window=6, agc_graph_mode='time', # time, const, freq t=self.model.t, N_handles=N_handles, handle_pos=[ ((i + 1) * self.model.N / self.model.fs / (N_handles + 1), 1) for i in range(N_handles) ], ) (init_state['i'], init_state['q']) = model.ref_signal(init_state['signal_mode'], init_state['fc'], init_state['fm']) model.agc_cfg(1, init_state['agc_window'], init_state['agc_ref'], init_state['agc_alpha']) (init_state['agc_i'], init_state['agc_q'], init_state['agc_g']) = model.agc_loopback(init_state['i'], init_state['q']) # Set preset configurations init_state['presets'] = { 'Default': { 'signal_mode': 'sin', 'fm': 2000, 'fc': 20000, 'agc_ref': 0.7, 'agc_alpha': 0.7, 'agc_window': 64, 'agc_bypass': False, 'agc_graph_mode': 'time', 'handle_pos': [(x * self.model.N / self.model.fs, y) for (x, y) in [(0.2, 1.0), (0.4, 1.0), (0.6, 1.0), (0.8, 1.0)] ], }, 'Slow fading': { 'signal_mode': 'sin', 'fm': 2000, 'fc': 40000, 'agc_ref': 0.7, 'agc_alpha': 1.0, 'agc_window': 64, 'agc_bypass': False, 'agc_graph_mode': 'time', 'handle_pos': [(x * self.model.N / self.model.fs, y) for (x, y) in [(0.1, 1.0), (0.4, 0.2), (0.5, 0.2), (0.9, 1.0)] ], }, 'AM envelope preservation': { 'signal_mode': 'am', 'fm': 8000, 'fc': 80000, 'agc_ref': 0.4, 'agc_alpha': 0.9, 'agc_window': 256, 'agc_bypass': False, 'agc_graph_mode': 'time', 'handle_pos': [(x * self.model.N / self.model.fs, y) for (x, y) in [(0.1, 1.0), (0.105, 0.1), (0.6, 0.1), (0.62, 1.0)]], }, 'Packet preambles with QPSK': { 'signal_mode': 'qpsk_bb', 'fm': 8000, 'fc': 80000, 'agc_ref': 0.7, 'agc_alpha': 0.5, 'agc_window': 64, 'agc_bypass': False, 'agc_graph_mode': 'time', 'handle_pos': [(x * self.model.N / self.model.fs, y) for (x, y) in [(0.18, 0), (0.181, 1.0), (0.68, 1.0), (0.681, 0)]], }, } self.init_state = init_state view = view_template(init_state) # Make Dash app app = JupyterDash( __name__, external_stylesheets=[ dbc.themes.BOOTSTRAP, 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css' ]) app.layout = view self.app = app @app.callback(Output('agc-ref-label', 'children'), [Input('agc-ref', 'value')]) def update_data_rate_label(f): return f'{int(f*100)} %' @app.callback(Output('agc-window-label', 'children'), [Input('agc-window', 'value')]) def update_data_rate_label(f): return f'{int(2**f)} Samples' @app.callback(Output('agc-alpha-label', 'children'), [Input('agc-alpha', 'value')]) def update_data_rate_label(f): return str(f) @app.callback(Output('in-f-data-label', 'children'), [Input('in-f-data', 'value')]) def update_data_rate_label(f): return f'{int(f)} Hz' @app.callback(Output('in-f-carrier-label', 'children'), [Input('in-f-carrier', 'value')]) def update_carrier_label(f): return f'{int(f)} kHz' @app.callback([ Output('in-sig-type', 'value'), Output('in-f-carrier', 'value'), Output('in-f-data', 'value'), Output('agc-ref', 'value'), Output('agc-alpha', 'value'), Output('agc-window', 'value'), Output('agc-bypass', 'value'), Output('agc-graph-mode', 'value'), Output('new-env-preset', 'value'), ], [Input('preset-option', 'value')]) def set_to_preset(preset_name): preset = self.init_state['presets'][preset_name] # Return new GUI values return (preset['signal_mode'], preset['fc'] / 1000, preset['fm'], preset['agc_ref'], preset['agc_alpha'], int(np.log2(preset['agc_window'])), preset['agc_bypass'], preset['agc_graph_mode'], str(preset['handle_pos'])) @app.callback([ Output('graph-inputs', 'figure'), Output('new-input-signal', 'children') ], [ Input('graph-inputs', 'relayoutData'), Input('btn-add-handle', 'n_clicks'), Input('btn-rm-handle', 'n_clicks'), Input('in-sig-type', 'value'), Input('in-f-carrier', 'value'), Input('in-f-data', 'value'), Input('new-env-preset', 'value'), ], [State('graph-inputs', 'figure')]) def input_stage_callback(_, _btnadd, _btnrm, in_sig_type, in_f_carrier, in_data_rate, env_preset, fig_in): changed_ids = [ p['prop_id'] for p in dash.callback_context.triggered ] if 'btn-add-handle' in changed_ids[0]: add_envelope_handle(fig_in['layout']['shapes'], max(self.model.t)) if 'btn-rm-handle' in changed_ids[0]: rm_envelope_handle(fig_in['layout']['shapes']) if any(map(lambda x: 'new-env-preset' in x, changed_ids)): h_template = get_envelope_handle(fig_in['layout']['shapes'], 0) points = ast.literal_eval(env_preset) if points: new_shapes = [] for (i, (x, y)) in enumerate(points): p = dict(h_template) p.update({ 'name': 'envelope_' + str(i), 'xanchor': x, 'yanchor': y, }) new_shapes.append(p) fig_in['layout']['shapes'] = new_shapes in_f_carrier = in_f_carrier * 1000 (ref_i, ref_q) = self.model.ref_signal(in_sig_type, in_f_carrier, in_data_rate) handles = get_envelope_handles(fig_in['layout']['shapes']) env = self.model.envelope(handles) (trace_i, trace_q) = self.model.test_input((ref_i, ref_q), env) trace_t = self.model.t fig_in['data'][0]['x'] = trace_t fig_in['data'][0]['y'] = trace_i fig_in['data'][1]['x'] = trace_t fig_in['data'][1]['y'] = trace_q return fig_in, [ f'{in_sig_type} {in_f_carrier} {in_data_rate}, {handles}' ] @app.callback(Output('graph-agc', 'figure'), [ Input('new-input-signal', 'children'), Input('agc-ref', 'value'), Input('agc-alpha', 'value'), Input('agc-window', 'value'), Input('agc-bypass', 'value'), Input('agc-graph-mode', 'value') ], [State('graph-inputs', 'figure'), State('graph-agc', 'figure')]) def agc_stage_callback(_, agc_ref, agc_alpha, agc_window, agc_bypass, graph_mode, fig_in, fig_agc): # TODO Check if State uses client... if so, remove the graph-inputs state arg to avoid round trip for no reason agc_en = 0 if agc_bypass else 1 self.model.agc_cfg(agc_en, agc_window, agc_ref, agc_alpha) (trace_i, trace_q) = (fig_in['data'][0]['y'], fig_in['data'][1]['y']) (agc_i, agc_q, agc_g) = self.model.agc_loopback(trace_i, trace_q) trace_t = self.model.t if graph_mode == 'time': fig_agc['data'][0]['x'] = trace_t fig_agc['data'][0]['y'] = agc_i fig_agc['data'][1]['x'] = trace_t fig_agc['data'][1]['y'] = agc_q fig_agc['data'][2]['x'] = trace_t fig_agc['data'][2]['y'] = agc_g fig_agc['layout']['xaxis']['title'] = "Time (s)" fig_agc['layout']['yaxis']['title'] = "Normalised Amplitude" fig_agc['layout']['shapes'] = [ dict( visible=True, type='rect', editable=False, layer='below', opacity=0.6, fillcolor='#DCD8EA', xref='x', x0=self.model.t[-1] - (2**agc_window / self.model.fs), x1=self.model.t[-1], yref='y', y0=-1, y1=1, line={'width': -1}, ) ] if graph_mode == 'const': fig_agc['data'][0]['x'] = agc_i fig_agc['data'][0]['y'] = agc_q fig_agc['data'][1]['x'] = [] fig_agc['data'][1]['y'] = [] fig_agc['data'][2]['x'] = [] fig_agc['data'][2]['y'] = [] fig_agc['layout']['xaxis']['title'] = "I Amplitude" fig_agc['layout']['yaxis']['title'] = "Q Amplitude" fig_agc['layout']['shapes'] = [] if graph_mode == 'freq': (freq_x, freq_y) = self.model.calc_fft(agc_i, agc_q) fig_agc['data'][0]['x'] = freq_x fig_agc['data'][0]['y'] = freq_y fig_agc['data'][1]['x'] = [] fig_agc['data'][1]['y'] = [] fig_agc['data'][2]['x'] = [] fig_agc['data'][2]['y'] = [] fig_agc['layout']['xaxis']['title'] = "Frequency (Hz)" fig_agc['layout']['yaxis']['title'] = "Power dB" fig_agc['layout']['shapes'] = [] return fig_agc
def show_task(jeditaskid, verbose=False, mode='inline'): # get task task = queryPandaMonUtils.query_tasks(23518002, verbose=False)[-1][0] # get tasks of the user tasks = queryPandaMonUtils.query_tasks(username=task['username'], verbose=False)[-1] tids = set([x['jeditaskid'] for x in tasks]) tids.add(jeditaskid) # Build App app = JupyterDash(__name__) app.layout = html.Div([ html.Div([ html.H2("TaskID: "), dcc.Dropdown( id='dropdown_taskid', options=[{'label': i, 'value': i} for i in tids], value=jeditaskid ),], style={'display': 'inline-block', 'width': '20%'} ), html.Div([ html.Div([ html.H2('Task Attributes'), dash_table.DataTable(id='00_table', columns=[{'id': 'attribute', 'name': 'attribute'}, {'id': 'value', 'name': 'value'}], page_action='none', style_table={'height': '330px', 'overflowY': 'auto'}, style_cell_conditional=[ { 'if': {'column_id': 'value'}, 'textAlign': 'left' }, ]),], style={'display': 'inline-block', 'width': '49%', 'float': 'left', 'padding-top': '30px'} ), html.Div([ dcc.Graph(id='01_graph'),], style={'display': 'inline-block', 'width': '49%'} ), ],), html.Div([ html.Div([ dcc.Graph(id='10_graph')], style={'display': 'inline-block', 'width': '49%'}), html.Div([ dcc.Graph(id='11_graph')], style={'display': 'inline-block', 'width': '49%'}) ],), ]) # Run app and display result inline in the notebook app.run_server(mode=mode) @app.callback( Output('00_table', 'data'), Output('01_graph', 'figure'), Output('10_graph', 'figure'), Output('11_graph', 'figure'), Input('dropdown_taskid', "value") ) def make_elements(jeditaskid): verbose = False task = queryPandaMonUtils.query_tasks(jeditaskid, verbose=verbose)[-1][0] jobs = queryPandaMonUtils.query_jobs(jeditaskid, drop=False, verbose=verbose)[-1]['jobs'] jobs = pd.DataFrame(jobs) # task data task_data = [{'attribute': k, 'value': task[k]} for k in task if isinstance(task[k], (str, type(None)))] # figures site_fig = px.histogram(jobs, x="computingsite", color="jobstatus") ram_fig = px.histogram(jobs, x="maxrss") exectime_fig = go.Figure() legend_set = set() for d in jobs.itertuples(index=False): if d.jobstatus == 'finished': t_color = 'green' elif d.jobstatus == 'failed': t_color = 'red' else: t_color = 'orange' if d.jobstatus not in legend_set: show_legend = True legend_set.add(d.jobstatus) exectime_fig.add_trace( go.Scatter( x=[d.creationtime, d.creationtime], y=[d.pandaid, d.pandaid], mode="lines", line=go.scatter.Line(color=t_color), showlegend=True, legendgroup=d.jobstatus, name=d.jobstatus, hoverinfo='skip' ) ) exectime_fig.add_trace( go.Scatter( x=[d.creationtime, d.endtime], y=[d.pandaid, d.pandaid], mode="lines", line=go.scatter.Line(color=t_color), showlegend=False, legendgroup=d.jobstatus, name="", hovertemplate="PandaID: %{y:d}") ) exectime_fig.update_xaxes(range=[jobs['creationtime'].min(), jobs['endtime'].max()], title_text='Job Lifetime') exectime_fig.update_yaxes(range=[jobs['pandaid'].min() * 0.999, jobs['pandaid'].max() * 1.001], title_text='PandaID') return task_data, site_fig, ram_fig, exectime_fig
app.layout = html.Div(children=[ # TODO1: Add title to the dashboard html.H1('US Domestic Airline Flights Performance', style={'textAlign': 'center', 'color': '#503D36', 'font-size': 24}), # REVIEW2: Dropdown creation # Create an outer division html.Div([ # Create an division for adding dropdown helper text for report type html.Div( [ html.H2('Report Type:', style={'margin-right': '2em'}) ] ), # TODO2: Add a dropdown dcc.Dropdown(id='input-type', options=[ {'label': 'Yearly Airline Performance Report', 'value': 'OPT1'}, {'label': 'Yearly Airline Delay Report', 'value': 'OPT2'} ], placeholder='Select a report type', style={'width':'80%', 'padding':'3px', 'font-size': '20px', 'text-align-last' : 'center'}) # Place them next to each other using the division style ], style={'display':'flex'}), # Add next division html.Div([ # Create an division for adding dropdown helper text for choosing year html.Div( [ html.H2('Choose Year:', style={'margin-right': '2em'}) ] ), dcc.Dropdown(id='input-year', # Update dropdown values using list comphrehension options=[{'label': i, 'value': i} for i in year_list], placeholder="Select a year", style={'width':'80%', 'padding':'3px', 'font-size': '20px', 'text-align-last' : 'center'}), # Place them next to each other using the division style ], style={'display': 'flex'}), # Add Computed graphs # REVIEW3: Observe how we add an empty division and providing an id that will be updated during callback html.Div([ ], id='plot1'), html.Div([ html.Div([ ], id='plot2'), html.Div([ ], id='plot3') ], style={'display': 'flex'}), # TODO3: Add a division with two empty divisions inside. See above disvision for example. html.Div([ html.Div([ ], id='plot4'), html.Div([ ], id='plot5') ], style={'display':'flex'}) ])
sort_action="native", style_cell={ 'textAlign': 'center', 'font-family': 'sans-serif' }, editable=False)) ]) content = html.Div([ html.H2('Transcript Review Tool', style=TEXT_STYLE), html.Hr(), content_row ], style=CONTENT_STYLE) app = JupyterDash(external_stylesheets=[dbc.themes.BOOTSTRAP]) app.layout = html.Div([sidebar, content]) @app.callback(Output( component_id='bee_data_table', component_property='data'), [ Input(component_id='submit_button', component_property='n_clicks'), State(component_id='state_dropdown', component_property='value'), State(component_id='range_slider', component_property='value') ]) def update_dash_table(n_clicks, state, date_range): dash_table_data = (grouped_df.loc[grouped_df["State"] == state].loc[ grouped_df["Year"] >= date_range[0]].loc[ grouped_df["Year"] <= date_range[1]].to_dict('records')) return dash_table_data
def main(): # collect stocks ticks = [] while True: boof = input('Add stock to portfolio: ') if boof: ticks.append(boof) else: break # create portfolio object port = Portfolio(ticks) W, R, V, S, K = port.build(port.coskew(), port.cokurt()) #make a dataframe weights = pd.DataFrame({ticks[i] : W[:,i] for i in range(len(ticks))}) stats = pd.DataFrame({'Return':R, 'Volatility':V, 'Skew':S, 'Kurtosis':K}) df = weights.join(stats) #create a graph object graph = port.graph(R, V, S, K) # initialize app app = JupyterDash(__name__, external_stylesheets=[dbc.themes.FLATLY]) PLOTLY_LOGO = 'https://images.plot.ly/logo/new-branding/plotly-logomark.png' percent = FormatTemplate.percentage(2) decimal = Format(precision=2, scheme=Scheme.fixed) app.layout = html.Div([ html.Div([ html.Img( src=PLOTLY_LOGO, style={ 'width':'40px', 'margin-right':'auto' } ) ], style={ 'grid-area':'nav', 'background':'#58d5f6', 'padding':'10px', 'display':'flex', 'align-items':'center', 'justify-content':'flex-end' } ), html.Div([ dcc.Graph( id='graph', figure=graph ) ], style={ 'grid-area':'scatter', 'background':'#236fc8', 'padding':'10px', 'color':'white' } ), html.Div([ DataTable( id='table', data=df.to_dict('records'), columns=[ {'id':i, 'name':i, 'type':'numeric', 'hideable':True, 'format':decimal} if i == 'Skew' or i == 'Kurtosis' else {'id':i, 'name':i, 'type':'numeric', 'hideable':True, 'format':percent} for i in df.columns ], filter_action='native', sort_action='native', page_current=0, page_size=10, cell_selectable=False, style_as_list_view=True, style_table={'overflowX': 'auto'}, style_header={ # header style 'backgroundColor': 'rgb(230, 230, 230, 0.15)', 'fontWeight': 'bold' }, style_filter={ # header filter 'backgroundColor': 'rgb(230, 230, 230, 0)' }, style_cell={ # style each individual cell 'minWidth': '65px', 'color':'white' }, style_data={ # same as above, exclude header and filter cells 'whiteSpace': 'normal', 'backgroundColor': 'rgb(248, 248, 248, 0)', 'height': 'auto' }, style_data_conditional=[{ 'if': {'row_index': 'even'}, 'backgroundColor': 'rgb(248, 248, 248, 0.15)' }] ) ], style={ 'grid-area':'datatable', 'background':'#236fc8', 'padding':'10px', } ) ], style={ # main wrapper 'height':'100vh', 'width':'97%', 'margin':'0 auto', 'display':'grid', 'grid-gap':'5px', 'grid-template-columns':'5fr 2fr', 'grid-template-rows':'1fr 12fr', 'grid-template-areas':'"nav nav"\ "datatable scatter"' } ) app.run_server(mode='external', debug=True, port=140)
result_card = dbc.Card([dbc.CardBody([dbc.Row([result_blurb])])]) survey_card = dbc.Card( [dbc.CardBody(dbc.Row([html.Embed(src=form, height=900, width=750)]))], style={ 'width': 'auto', 'height': 'auto' }) app = JupyterDash(external_stylesheets=[dbc.themes.LITERA]) server = app.server top_cell = dbc.Col([html.H2('Politics of Earth Dashboard')], width=12) right_col = dbc.Col([survey_card], width=6) left_col = dbc.Col([result_card], width=6) app.layout = html.Div([dbc.Row([top_cell]), dbc.Row([left_col, right_col])]) @app.callback( Output("fade-transition", "is_in"), [Input("fade-transition-button", "n_clicks")], [State("fade-transition", "is_in")], ) def toggle_fade(n_clicks, is_in): if n_clicks != 0: return fade else: return None if __name__ == '__main__':
shell = '' try: shell = get_ipython().__class__.__name__ if shell == 'ZMQInteractiveShell': app = JupyterDash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP]) elif shell == 'TerminalInteractiveShell': app = dash.Dash(__name__) # , external_stylesheets =[dbc.themes.BOOTSTRAP] else: app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP]) except NameError: app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP]) app.layout = layout # app.layout = html.Div([layout]) register_callbacks(app) app.config.suppress_callback_exceptions = True if __name__ == '__main__': if os.environ.get("USERNAME") == 'john': # app.run_server(host="127.0.0.1", debug=False, port=int(os.environ['CDSW_APP_PORT'])) # app.run_server(host="127.0.0.1", debug=False, port=int(os.environ['CDSW_APP_PORT'])) # app.run_server(host="0.0.0.0", debug=False, port=int(os.environ['CDSW_APP_PORT'])) app.run_server(host="127.0.0.1", port='8052', debug=True) # app.run_server(debug=True) else: ##### Only do Google Analytics if hosted online ##### app.scripts.config.serve_locally = False
def DashBoard(self, pos): #creating web app name app = JupyterDash(__name__) #colors and style colors = {'background': "darkslategrey", 'text': "cyan"} style = {'textAlign': 'right', 'color': "cyan"} app.layout = html.Div( style={'backgroundColor': colors['background']}, children=[ html.H1( children="Backtesting Forex Strategy", #header style={ 'textAlign': 'center', 'color': colors['text'] }), html.Div([ #division for plotting html.Label(['Forex strategy type'], style=style), dcc.Dropdown( # dropdown method id='my_dropdown', options=[ { 'label': 'Long only', 'value': 'P&L_Buy' }, #dropdown labels { 'label': 'Short only', 'value': 'P&L_Sell' }, { 'label': 'Long-Short', 'value': 'P&L' }, ], value='P&L', multi=False, clearable=False, style={"width": "50%"}), ]), html.Div([ html.Label( ["Strategy Report"], #label for the each division style=style), html.Label(["P&L for the strategy"], style=style), dcc.Graph(id='the_graph') ]), #we plot here by taking the id of that plot ]) @app.callback( #callback function for chnage in input of dropdown Output(component_id='the_graph', component_property='figure'), [Input(component_id='my_dropdown', component_property='value')]) def update_graph(my_dropdown): if (my_dropdown == "P&L"): df = pos fig_ = go.Figure() fig_.add_traces(data=go.Scatter(y=pos['P&L'], name="P&L_")) fig_.update_layout(title="P&L from both long and short", title_x=0.5, plot_bgcolor=colors['background'], paper_bgcolor=colors['text'], xaxis_title="Toatal Data", yaxis_title="Profit", width=1300, height=500, xaxis={'showgrid': False}, yaxis={'showgrid': False}) elif (my_dropdown == "P&L_Buy"): df = pos fig_ = go.Figure() fig_.add_traces(data=go.Scatter(y=pos['P&L'].loc[pos.loc[ pos['Pred'] == 1].index], name="P&L_")) fig_.update_layout(title="P&L from long only", title_x=0.5, plot_bgcolor=colors['background'], paper_bgcolor=colors['text'], xaxis_title="Total Data", yaxis_title="Profit", width=1300, height=500, xaxis={'showgrid': False}, yaxis={'showgrid': False}) elif (my_dropdown == "P&L_Sell"): df = pos fig_ = go.Figure() fig_.add_traces(data=go.Scatter(y=pos['P&L'].loc[pos.loc[ pos['Pred'] == 0].index], name="P&L_")) fig_.update_layout(title="P&L from short only", title_x=0.5, plot_bgcolor=colors['background'], paper_bgcolor=colors['text'], xaxis_title="Total Data", yaxis_title="Profit", width=1300, height=500, xaxis={'showgrid': False}, yaxis={'showgrid': False}) return (fig_) app.run_server(mode='external', port=9181) return
import dash import dash_html_components as html import dash_core_components as dcc from jupyter_dash import JupyterDash # Create a dash application app = JupyterDash(__name__) JupyterDash.infer_jupyter_proxy_config() # Get the layout of the application and adjust it. # Create an outer division using html.Div and add title to the dashboard using html.H1 component # Add description about the graph using HTML P (paragraph) component # Finally, add graph component. app.layout = html.Div(children=[ html.H1('Airline Dashboard', style={ 'textAlign': 'center', 'color': '#503D36', 'font-size': 40 }), html. P('Proportion of distance group (250 mile distance interval group) by month (month indicated by numbers).', style={ 'textAlign': 'center', 'color': '#F57241' }), dcc.Graph(figure=fig), ]) if __name__ == '__main__': app.run_server(mode="inline", host="localhost")