def parse_contents(contents, filename, date): content_type, content_string = contents.split(',') decoded = base64.b64decode(content_string) try: if 'csv' in filename: # Assume that the user uploaded a CSV file df = pd.read_csv(io.StringIO(decoded.decode('utf-8'))) elif 'xls' in filename: # Assume that the user uploaded an excel file df = pd.read_excel(io.BytesIO(decoded)) elif 'json' in filename: df = pd.read_json(io.StringIO(decoded.decode('utf-8')), orient='records') except Exception as e: print(e) return html.Div([ 'There was an error processing this file.' ]) model = visual_plot.HistoryVisualiser(df) model.preprocess_df() model.gen_ngrams() fig = model.get_fig() return html.Div([ html.Div([ html.H2('Summary'), html.Plaintext('Loaded file: {}'.format(filename)), html.Plaintext('Time of Load: {}'.format(datetime.datetime.fromtimestamp(date))), html.Plaintext('Found {} entries'.format(len(df))), html.H2('Visualisation'), html.Hr() # horizontal line ]), dcc.Graph( id='test', figure=fig ) ])
def df_to_csv(n_clicks, n_intervals, dataset, s): output = html.Plaintext( "The data has been saved to your PostgreSQL database.", style={ 'color': 'green', 'font-weight': 'bold', 'font-size': 'large' }) no_output = html.Plaintext("", style={'margin': "0px"}) input_triggered = dash.callback_context.triggered[0]["prop_id"].split( ".")[0] if input_triggered == "save_to_postgres": s = 6 pg = pd.DataFrame(dataset) pg.to_sql("productlist", con=db.engine, if_exists='replace', index=False) return output, s elif input_triggered == 'interval' and s > 0: s = s - 1 if s > 0: return output, s else: return no_output, s elif s == 0: return no_output, s
def df_to_csv(n_clicks, n_intervals, dataset, s): output = html.Plaintext("The data has been saved to your folder.", style={ 'color': 'green', 'font-weight': 'bold', 'font-size': 'large' }) no_output = html.Plaintext("", style={'margin': "0px"}) input_triggered = dash.callback_context.triggered[0]["prop_id"].split( ".")[0] if input_triggered == "save_to_csv": s = 6 df = pd.DataFrame(dataset) df.to_csv(CONFIG.data / "intermediate" / "Your_Sales_Data.csv") return output, s elif input_triggered == 'interval' and s > 0: s = s - 1 if s > 0: return output, s else: return no_output, s elif s == 0: return no_output, s
def label_image(Healthy_btn, Mild_btn, Moderate_btn, Severe_btn, Proliferative_btn): global df_table_content, current_img_index, progress_percentage changed_id = [p['prop_id'] for p in dash.callback_context.triggered][0] class_name = None noImages_placeholder = '' if 'Healthy' in changed_id: class_name = 'Healthy' elif 'Mild' in changed_id: class_name = 'Mild' elif 'Moderate' in changed_id: class_name = 'Moderate' elif 'Severe' in changed_id: class_name = 'Severe' elif 'Proliferative' in changed_id: class_name = 'Proliferative' if class_name: if current_img_index < len(images) and len(df_table_content) < len(images): df_table_content = df_table_content.append({'Image File Name': images[current_img_index]['Key'], 'Class': class_name}, ignore_index=True) labeled_count = current_img_index + 1 total_count = len(images) progress = labeled_count / total_count progress_percentage = int(progress * 100) # to display next image if len(df_table_content) < len(images): current_img_index += 1 else: current_img_index = -1 noImages_placeholder = html.Plaintext("No more Images to Label.", style={'color': 'red', 'font-weight': 'bold', 'font-size': 'large'}) return dbc.Table.from_dataframe(df_table_content, bordered=True, responsive=True, ), images[current_img_index][ 'ImgURL'], \ images[current_img_index]['Key'], progress_percentage, f"{progress_percentage} %", noImages_placeholder
def save_to_csv(n_clicks, n_intervals, sec): no_notification = html.Plaintext("", style={'margin': "0px"}) notification_text = html.Plaintext("The Shown Table Data has been saved to the excel sheet.", style={'color': 'green', 'font-weight': 'bold', 'font-size': 'large'}) input_triggered = dash.callback_context.triggered[0]["prop_id"].split(".")[0] if input_triggered == "excel_btn" and n_clicks: sec = 10 return send_data_frame(df_table_content.to_csv, filename="Labeled_Eye_Images.csv"), notification_text, sec elif input_triggered == 'excel_notification_interval' and sec > 0: sec = sec - 1 if sec > 0: return None, notification_text, sec else: return None, no_notification, sec elif sec == 0: return None, no_notification, sec
def build_layout(): return html.Div([ html.Div([ html.H1("Exploring Pokémon Data") ], style={'text-align': 'center'}), html.Div([ html.Label("Dimensionality Reduction Features:"), build_dim_reduction_feats_selector(), html.Plaintext( 'Note, that updates to these inputs reruns the dimensionality' 'reduction and can take significant time.' ), html.Label("Highlight Feature:"), build_highlight_stat_dropdown(), ]), html.Div([ dcc.Loading(dcc.Graph( id='pokemon-scatter' )) ],style={'width': '60%', 'display': 'inline-block', 'padding': '0 20'}), html.Div([ html.Div() ], id='pokemon-stats',style={'width': '40%', 'display': 'inline-block', 'padding': '0 20'}), html.Div([ dcc.Graph( id='pokemon-sankey', figure=build_sankey() ) ]), ])
def save_to_db(n_clicks, n_intervals, sec): no_notification = html.Plaintext("", style={'margin': "0px"}) notification_text = html.Plaintext("The Shown Table Data has been saved to the database.", style={'color': 'green', 'font-weight': 'bold', 'font-size': 'large'}) input_triggered = dash.callback_context.triggered[0]["prop_id"].split(".")[0] if input_triggered == 'submit_btn': sec = 10 df_table_content.to_sql('labeling-results', con=db.engine, if_exists='replace', index_label=False) return notification_text, sec elif input_triggered == 'db_notification_interval' and sec > 0: sec = sec - 1 if sec > 0: return notification_text, sec else: return no_notification, sec elif sec == 0: return no_notification, sec
def host_view(host): sys_info = host.GetSysInfo() cpu_count = sys_info.cpu_info.cpu_count load_average = sys_info.cpu_info.load_average data = { 'host': host.name, 'cpu count': cpu_count, 'load average': load_average, 'load': f'{(load_average[-1]/cpu_count *100):.1f}', } return html.Div([ html.Div( [html.Plaintext(f'{key}: {value}') for key, value in data.items()]) ])
def update_metrics(n): db, crsr = get_cursor() cmd = '''select * from alerts group by `timestamp` desc''' crsr.execute(cmd) alert = crsr.fetchall() alerts = "" for a in alert: if alerts: alerts = alerts + " \n" else: alerts = alerts dt = a[0] status = a[1] start = a[2] end = a[3] duration = a[4] peak = a[5] if status == 'high': alerts = alerts + '''%s : Temperature exceeded maximum limit from %s to %s for %s, and peak value was %s''' % ( str(dt), str(start), str(end), str(duration), str(peak)) elif status == 'low': alerts = alerts + '''%s : Temperature is less than minimum limit from %s to %s for %s, and peak value was %s''' % ( str(dt), str(start), str(end), str(duration), str(peak)) cmd = '''select * from toggle''' crsr.execute(cmd) check = crsr.fetchall() if check: status = check[0][0] start = check[0][1] current = check[0][3] stamp = datetime.now().strftime("%d/%m/%Y %I:%M%p") if status == 'high': a = '''%s : Temperature exceeded maximum limit at %s and current value is %s degrees''' % ( str(stamp), str(start), str(current)) alerts = a + "\n" + alerts if status == 'low': a = '''%s : Temperature is less than minimum limit at %s and current value is %s degrees''' % ( str(stamp), str(start), str(current)) alerts = a + "\n" + alerts print(alerts) return [ html.H2(children='Alerts'), html.Plaintext(alerts) ]
def display_images(entity_1, entity_2, entity_3, entity_4, entity_5, entity_6): images = [] list_images = get_images(entity_3, entity_4, entity_5, entity_6) len_list = len(list_images) start = (entity_1 - 1) * entity_2 end = entity_1 * entity_2 list_images = list_images[start:end] for i in range(int(entity_2)): images.append( html.Div([ html.Div([ html.Plaintext(i + 1) ], style={'width': '3%', 'text-align': 'center', 'vertical-align': 'middle', 'display': 'inline-block', 'fontWeight': 'bold', 'text-decoration': 'underline', 'font-family': 'Arial, Helvetica, sans-serif'}), html.Div([ html.Video(src=list_images[i], autoPlay=True, loop=True) ], style={'width': '20%', 'text-align': 'center', 'vertical-align': 'middle', 'display': 'inline-block', 'fontWeight': 'bold', 'text-decoration': 'underline', 'font-family': 'Arial, Helvetica, sans-serif'}) ], style={ #'borderWidth': 'medium', #'borderColor': 'blue', 'borderTop': 'thin lightgrey solid', 'borderLeft': 'thin lightgrey solid', 'borderRight': 'thin lightgrey solid', 'borderBottom': 'thin lightgrey solid', 'backgroundColor': 'rgb(250, 250, 250)', 'padding': '40px 40px', 'border-radius': '15px', 'margin-bottom': ' 5px', }), ) return html.Div(images), [{'label': i, 'value': i} for i in range(1, (int((len_list) / int(entity_2))) + 2)]
def _display_page(pathname): if pathname is not None and pathname.startswith( _server.DASH_BASE_PATHNAME): pathname = pathname[len(_server.DASH_BASE_PATHNAME):] if pathname is None or pathname == '' or pathname == 'index': children = _generate_dash_index_page() elif pathname == 'shutdown': _shutdown_server() children = 'Server shutting down...' elif pathname in _get_apps(include_dev=True): children = _get_dash_app_content(pathname) else: # TODO: return a 404 "URL not found" page here children = _html.Div( [_html.Plaintext('404: {} not found'.format(pathname))]) return children
def parse_contents(contents, filename, date): if contents is not None: content_type, content_string = contents.split(',') script = get_transcript(filename, content_type) return html.Div([ html.H5(filename), html.H6(datetime.datetime.fromtimestamp(date)), html.Audio(id="player", src=contents, controls=True, style={"width": "50%"}), html.Hr(), html.Div('Transcript'), html.Plaintext(script), ])
def _generate_dash_index_page(): """Set up index page. Returns: Index page. """ _app.title = 'Jinder' app_info_list = [] dash_apps = _get_apps(is_dash=True, include_dev=False) if dash_apps: for app in dash_apps: category, description = _get_app_info(app, is_dash=True) link = _server.DASH_BASE_PATHNAME + app app_info_list.append( dict(category=category, description=description, link=link)) flask_apps = _get_apps(is_dash=False, include_dev=False) if dash_apps: for app in flask_apps: category, description = _get_app_info(app, is_dash=False) link = '/' + app + '/' app_info_list.append( dict(category=category, description=description, link=link)) if app_info_list: app_info_list.sort(key=lambda x: [x['category'], x['description']]) # group links based on category divs = [] current_category = app_info_list[0]['category'] divs.append(_html.H2(current_category)) for i, app in enumerate(app_info_list): if app['category'] == current_category: if i != 0: divs.append(_html.Br()) else: current_category = app['category'] divs.append(_html.H2(current_category)) divs.append( _dcc.Link(app['description'], href=app['link'], refresh=True)) index_page = _html.Div(divs, style={'margin': '10px'}) else: index_page = _html.Div([ _html.Plaintext( 'Website under maintenance. Please come back later.') ], style={'margin': '10px'}) return index_page
def upload_file(f_name, f_content, last_modified): c_t, c_s = f_content.split(',') # print('c_s: ',c_s) try: if 'xls' in f_name: df = pd.read_excel(io.BytesIO(base64.b64decode(c_s))) elif 'csv' in f_name: df = pd.read_csv(io.StringIO( base64.b64decode(c_s).decode('utf-8'))) else: return html.Div(['Only xls or csv file format allowed.']), ['N'] # print('df: ',df.head()) # df=df.to_json(date_format='iso',orient='split') # print('type df: ',type(df)) return html.Div([ html.Plaintext( f'file name: {f_name}\t last modified: {datetime.datetime.fromtimestamp(last_modified)}' ), ]), df except OSError: return html.Div(['File not found / cannot be uploaded.']), ['N']
import symbols external_stylesheets = [dbc.themes.BOOTSTRAP] app = dash.Dash(__name__, external_stylesheets=external_stylesheets, suppress_callback_exceptions=True) server = app.server app.layout = dbc.Container( [ dcc.Store(id="store"), dbc.Row([ html.H1("EIA: Weekly Petroleum Status Report"), html.Plaintext(" Last Update: "), dbc.Badge(id='last_update_tag', color="primary", className="ml-1") ]), html.Hr(), html.Div(id='none', children=[], style={'display': 'none'}), dbc.Tabs( [ dbc.Tab(label="Overview", tab_id="Overview"), # dbc.Tab(label="Crude", tab_id="Crude"), # dbc.Tab(label="Gasoline", tab_id="Gasoline"), dbc.Tab(label="Config", tab_id="Config"), ], id="tabs", active_tab="Overview", ), html.Div(id="tab-content", className="p-4"),
def Body(cache): return html.Div([ html.Br(), html.Br(), html.Br(), components.PaletteModal('density', 1), components.PaletteModal('conservation', 2), components.PaletteModal('custom', 3), components.PaletteModal('disorder', 4), components.PaletteModal('membranetopology', 5), components.PaletteModal('msa', 6), components.PaletteModal('secondarystructure', 7), components.PaletteModal('hydrophobicity', 8), components.PaletteModal('heatmap', 9), components.GdprPolicyModal(), components.TutorialOneModal(), components.TutorialTwoModal(), components.TutorialThreeModal(), components.TutorialFourModal(), # components.TutorialFiveModal(), components.CustomFormatDescriptionModal(), dbc.Row([ dbc.Col([ dbc.Card([ dbc.CardBody([ html.H2('ConPlot help page', className="card-text", style={'text-align': "center"}), html.Br(), html.Br(), html.P([ 'Welcome to the ConPlot help page: here you can read how to use ConPlot and take ' 'full advantage of all its features. This page is divided in a series of sections ' 'that will guide you through the process of understanding what data files you need ' 'to create a plot, how to adjust the layout of a plot and even store these plots ' 'in your user storage area. If you came here looking for an example of the data ' 'files used as an input, you can download them ', html.A(html.U('here'), href=UrlIndex.EXAMPLE_DATA.value), '.' ], style={ "font-size": "110%", "text-align": "justify" }), html.Br(), html.H4('1. ConPlot layout', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), html.P([ "To create a plot, you will need to understand first the layout of ConPlot's ", html.I('Plot'), ' page. The layout of the application has been divided into four panels that will ' 'allow you to interact with ConPlot:' ], style={ "font-size": "110%", 'text-align': "justify" }), components.PanelLayoutHelpList(), html.Br(), html.Img(src=UrlIndex.HELP_FIG1.value, height='700vh', style={ 'border': '5px solid', 'display': 'block', 'margin-left': 'auto', 'margin-right': 'auto' }), html.Br(), html.Br(), dbc.Alert([ 'TIPS:', html.Ul([ html.Br(), html.Li([ "Note the difference between the ", html.I('Generate Plot'), ' and the ', html.I('Adjust Plot'), " buttons. Use the former to create plots for the first time or after you " "upload new data files into the current session, and the latter to adjust " "the way the plot looks after tweaking the settings on the display " "control panel." ]), html. Li("If you hover to the top right of the plot panel, the plot's mode bar will " "appear. Use the buttons on this bar to control the behaviour of the " "hovering tool, zoom in and out, change the scale of the plot or to " "download the plot image as a png file.") ]) ], style={'text-align': "justify"}, color='info'), dbc.Alert( "WARNING: Do not click on the refresh button in your browser! Depending on your " "browser, doing this may cause your session to expire and you will lose any " "unsaved data and plots. Instead, use ConPlot's navigation bar on the top panel " "to safely browse through the website.", style={'text-align': "justify"}, color='danger'), html.Br(), html.H4('2. Required input', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), html. P("ConPlot requires the following inputs to be able to create a plot.", style={ "font-size": "110%", 'text-align': "justify" }), components.MandatoryInputHelpList(), html.P([ 'After you upload at least one file for each of these datasets you will be able to ' 'generate a plain contact map plot by clicking on the ', html.I('Generate Plot'), ' button. Note that it is possible to upload as many contact map files as you ' 'wish, as it is possible to compare them or dynamically change which contact file ' 'is loaded in the plot. More on how to do this will be explained later on.' ], style={ "font-size": "110%", 'text-align': "justify" }), dbc.Alert([ 'TIPS:', html.Ul([ html. Li('If you wish to remove a file that you have uploaded, simply close the ' 'banner with its name and ConPlot will do the rest.' ), html.Li([ 'You can repeat the process of uploading a residue contact prediction ' 'file using the ', html.I('Upload Contact'), ' as many times as you wish in order to upload multiple contact maps.' ]) ]) ], style={'text-align': "justify"}, color='info'), dbc.Alert( 'WARNING: It is important that the numbering used in all the uploaded contact ' 'map files matches the sequence of residues present in the ' 'provided FASTA file. If this numbering does not match, this could result in ' 'misrepresentations of data or even failure to create a plot.', style={'text-align': "justify"}, color='danger'), html.Br(), html.H4('3. Additional tracks', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), html.P( "It is possible to add coloured tracks on the diagonal of the contact maps by " "uploading a series of prediction files associated to the sequence of " "interest. ConPlot is able to parse automatically the information contained in the " "following formats:", style={ "font-size": "110%", "text-align": "justify" }), components.AdditionalFormatsHelpList(), dbc.Alert([ 'TIPS:', html.Ul([ html.Br(), html. Li('You will not be able to upload a file until you first select its format ' 'in the dropdown selection menu.'), html.Li([ 'You can only upload one file at a time when you use the ', html.I('Add track'), ' button, but you can do this as many times as you wish in order to add ' 'multiple tracks to the plot.' ]), html.Li([ 'If you would like to upload a sequence prediction that is not ' 'included in the list of supported formats, you can always create a ' 'custom file and add the information manually. If you think it would be ' 'very useful to be able to read this format automatically with ConPlot, ' 'you can try to ', dbc.CardLink(html.U('get in touch'), href=UrlIndex.CONTACT.value), ' and let us know.' ]) ]) ], style={'text-align': "justify"}, color='info'), html.P([ 'There is no limit on the number of files you can upload, the only requirement is ' 'that all the files correspond with the residue sequence that has been uploaded. ' 'If these files do not match, this could result in data misrepresentation or ' 'Conplot not being able to create a plot. Please note that if you upload multiple ' 'files for a given format, the default behaviour of ConPlot is to include only the ' 'first one to the plot. If you wish to visualise the other files, you will need to ' 'select them in the track content selection menus as described in the next ' 'section.' ], style={ "font-size": "110%", "text-align": "justify" }), html.Br(), html.H4('4. Adjust the plot layout', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), html.P([ 'Once you have uploaded all the files of interest you can create your first plot ' 'by clicking on ', html.I('Generate Plot'), '. Then, ConPlot will create a plot with the default layout settings. We tried to ' 'make sure that by default ConPlot will generate plots where the provided data is ' 'shown clearly, but this is a difficult task as it is something that is highly ' 'dependent on your data. Thus, you are likely to need to adjust the settings on ' 'the display control panel to get your data shown in the best possible way. To ' 'help you do this, this panel has been divided into 4 sections:' ], style={ "font-size": "110%", "text-align": "justify" }), components.AdjustPlotHelpList(), html.Br(), dbc.Alert([ 'TIPS: ', html.Ul([ html.Br(), html.Li([ 'Remember that the ', html.I('L/N'), ' selector will not affect any data being shown for PDB files. ' 'Similarly, data will also not be affected if the ', html.I('Create heatmap'), ' switch is turned on.' ]), html.Li([ 'If you have just created a plot with the ', html.I('Generate Plot'), ' button and you can see individual squared tiles in the diagonal ' 'tracks, try increasing the default value of the additional track ' 'marker size.' ]), html.Li([ 'If you have just uploaded a file, it may be that this file is ' 'not listed on the track selection layout. You may need to ' 'click on the ', html.I('Generate Plot'), ' button before being able to choose it in the dropdown menu.' ]), html.Li([ 'You may notice that when you zoom into a contact map, the contact ' 'markers retain their size. There are two ways you can get around ' 'this, we recommend using the ', html.I('Create heatmap'), ' to create a heatmap where contact markers increase in size when ' 'you zoom in. Alternatively, you can also change the contact ' 'marker size with the ', html.I("Size selector"), ' and click on ', html.I("Adjust Plot"), ' and then zoom-in. This can be done repeatedly until the desired ' 'size is chosen.' ]), html.Li([ 'Sometimes it is difficult to map a specific contact with its ' 'annotations at the diagonal. Try turning on the ', html.I('Verbose labels'), ' switch.' ]), html.Li([ 'If you have just created a plot with the ', html.I('Generate Plot'), ' button and the diagonal tracks overlap with each other, try ' 'increasing the default value of the additional track separation.' ]) ]) ], style={'text-align': "justify"}, color='info'), html.Br(), html.H4('5. Colour Palettes', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), html. P('Here is a list of the different palettes available for each dataset that you ' 'can use in ConPlot'), components.PaletteList(), html.Br(), html.Br(), html.H4('6. User Accounts', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), html.P([ 'By creating a user account in ConPlot, you will be able to access a series of ' 'additional features that will enable you to store sessions indefinitely and share ' 'them with other users. You can access the user account menu with the ', html.I('LOGIN'), ' dropdown menu on the top right of the navigation bar -panel 1 in Figure 1.' ], style={ "font-size": "110%", "text-align": "justify" }), components.UserAccountHelpList(), html.Br(), dbc.Alert( 'TIP: Interactive sessions expire after 60 minutes of inactivity. If you ' 'wish to permanently save the data and plots, create a user account and store ' 'the session before it expires.', style={'text-align': "justify"}, color='info'), html.Br(), html.H4('7. Tutorials', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), html.P([ "Here is a list of tutorials that will help you understand better how to use " "ConPlot. We strongly encourage you to complete them before using ConPlot for the " "first time, as they will guide you through the basic ConPlot features. We also " "recommend completion of these tutorials in the specified order as each of them " "will require you to understand concepts learned in the preceding one. To follow " "them, you will need to download the example data ", html.A(html.U('here'), href=UrlIndex.EXAMPLE_DATA.value) ], style={ "font-size": "110%", "text-align": "justify" }), html.Br(), components.TutorialList(), html.Br(), html.Br(), html.H4('8. Using ConPlot locally', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), html.P([ 'ConPlot is a web-based application, and as such we recommend you make use of it ' 'through this website. However, it is also possible to use ConPlot locally on your ' 'personal machine using the localhost. There are two possible ways to achieve ' 'this.', html.Br(), html.Br(), html.H5('8.1 Using Docker image at DockerHub'), "ConPlot is distributed as a docker image on the project's ", html.A(html.U('Docker hub repository'), href=UrlIndex.DOCKER_HUB.value), '. To use it, you will need to link it with a Redis container:' ]), dbc.Col([ html.Plaintext( '$ docker pull filosanrod/conplot:latest\n$ docker run --name ' 'redis_db -d redis:latest \n$ docker run --name conplot_app \ \n ' '-d filosanrod/conplot:latest gunicorn app:server -p 80:80 -b :80 \ ' '\n -e KEYDB_TIMEOUT=3600 -e KEYDB_URL="redis://redis_db:6379" \ \n' ' --link redis_db:redis --preload --workers=6 --timeout 120 \ \n' ' --graceful-timeout 120 --max-requests 5 --log-level=info' ) ], style={'background-color': '#EAEAEA'}, align='center'), html.P([ 'After you set up running the docker container, you will be able to access the ' 'app on http://0.0.0.0:80/home.', html.Br(), html.Br(), html.H5( '8.2 Locally using Flask development server'), 'It is also possible to use Flask development server to run ConPlot on your ' 'localhost. To do this you will first need to install redis, which is the cache ' 'memory server used by ConPlot.' ]), dbc.Col([ html.Plaintext( '$ sudo apt update\n$ sudo apt install redis-server\n$ sudo ' 'service redis start') ], style={'background-color': '#EAEAEA'}, align='center'), html. P('Once you have installed `redis`, you will need to start the service by running:' ), dbc.Col( [html.Plaintext('$ sudo service redis start')], style={'background-color': '#EAEAEA'}, align='center'), html. P('Now you will need to clone the repository, install the requirements and ' 'setup environment variables. Please note that ConPlot requires at least ' 'python 3.6.'), dbc.Col([ html.Plaintext( '$ git clone https://github.com/rigdenlab/conplot\n' '$ cd conplot\n$ python3.6 -m pip install -r requirements\n$ ' 'echo "KEYDB_URL=0://localhost:6379" > .env\n$ echo "KEYDB_TIME' 'OUT=3600" >> .env') ], style={'background-color': '#EAEAEA'}, align='center'), html. P('With the last two commands you will also have created an .env file with a ' 'variable named KEYDB_URL pointing to the redis server and a KEYDB_TIMEOUT ' 'variable with the session timeout value. This is the time at which a session ' 'expires after inactivity. By default in www.conplot.org this has a value of 3600 ' 'minutes, but if running locally you can set this time to any other value. ' 'The only thing left to do is to start the Flask development server on your ' 'machine:'), dbc.Col([html.Plaintext('$ python3.6 app.py')], style={'background-color': '#EAEAEA'}, align='center'), html.P([ 'Now you will be able to access the app on ', html.A(html.U('http://127.0.0.1:8050/home'), href='http://127.0.0.1:8050/home'), '. Please note that when running locally, ConPlot will not be able to establish a ' 'connection with our database, so all the user account related features will be ' 'disabled. Similarly, you will not be able to get in touch with us using the ' '"Get in touch" tab.' ]), html.Br(), html.H4('9. Server status', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), components.ServerStatusList(cache), html.Br(), html.Br(), html.H4('10. Privacy Policy', className="card-text", style={'text-align': "center"}), html.Hr(), html.Br(), components.GdprPolicyAlert(False) ]) ]) ], width=10), ], align='center', justify='center', className='m-0') ])
#initialize var_data var_name = "rs11257655" with urllib.request.urlopen(vv.rsid_url(var_name)) as url: var_data = json.loads(url.read()) all_annotations = [key for key in var_data.keys()] #initialize number of button clicks: rsid_button_clicks = 0 #dash app layout app.layout = html.Div(children=[ html.Div( children=[ #rsid search bar html.Plaintext('search rsid'), dcc.Input(id='rsid-input', value=var_name, type="text"), #update button html.Button('update', id='rsid-button'), dcc.RadioItems( id='expand-radio', options=[{ 'label': "more", 'value': "more" }, { 'label': "less", 'value': "less" }], value="more", ),
children=[html.Div( id='prediction', style={'text-align': 'center'}, children=[ html.Div( style={'width': 'fit-content', 'display': 'inline-block'}, id='prediction-input', children=[ html.H1( id='prediction-header', children='Ile przetrwa twój biznes?', style={'font-weight': 'bold', 'padding': '18px'} ), html.Plaintext("Jestem ", style={ 'display': 'inline-block', 'font-size': '12pt'}), dcc.Dropdown( id='sex', options=SEX_MAPPING, value='M', style=dict( width=100, display='inline-block', verticalAlign="middle", textAlign="left" ) ), html.Plaintext(", mam ", style={ 'display': 'inline-block', 'font-size': '12pt'}), dcc.Dropdown(
edu.reset_index(inplace=True) locations = np.arange(edu.shape[0]) app.config.suppress_callback_exceptions = True app.layout = html.Div( [dcc.Location(id='url', refresh=False), html.Div(id='page-content')]) index_page = html.Div([ html.Hr(), html.H1(children='NYC Crime Dashboard', style={'textAlign': 'center'}), html.Hr(), html.Plaintext( children= 'This dashboard is purposed with displaying the relationship between crime in New York City\nand various factors such as the time of day and the population.\nClick on a page below to compare crime in NYC to a specific factor. Use the options on these pages\nto manipulate the graphs and draw your own conclusions about crime in NYC', style={ 'fontSize': '18px', 'textAlign': 'center' }), html.Hr(), html.Div(style={ 'width': '20%', 'display': 'inline-block' }), html.Div(dcc.Link('NYC Crime vs Time of Day', href='/page-1'), style={ 'width': '15%', 'display': 'inline-block', 'textAlign': 'center' }), html.Div(dcc.Link('NYC Crime vs Income', href='/page-2'),
def get_inputs(submit, av_locs, num_rooms, sqmtr): if submit is not None: # use input for every location dash_numerical_features['rooms'] = num_rooms dash_numerical_features['sqmtr'] = sqmtr # finding location of user input user_input_loc_in_preds = dash_pred_input[dash_pred_input['location'] == av_locs].index[0] #additional info for user input add_n_schools = dash_pred_input[dash_pred_input['location'] == av_locs]['n_schools'].get_values()[0] add_n_kindergts = dash_pred_input[ dash_pred_input['location'] == av_locs]['n_kindergartens'].get_values()[0] add_distance_from_cc = dash_pred_input[ dash_pred_input['location'] == av_locs]['distance_from_cc'].get_values()[0] add_crime_score = dash_pred_input[ dash_pred_input['location'] == av_locs]['crime_score'].get_values()[0] avg_crimes_per_h1000s = dash_pred_input['crime_score'].mean() # now we need to concat numerical features with categorical(one hot encoded) features deployment_input = pd.concat( [dash_numerical_features, dash_dummies_cat_features], axis=1) upper_int = my_model.predict(deployment_input, quantile=75) upper_int_main_pred = upper_int[user_input_loc_in_preds] mid_int = my_model.predict(deployment_input, quantile=50) mid_int_main_pred = mid_int[user_input_loc_in_preds] lower_int = my_model.predict(deployment_input, quantile=25) lower_int_main_pred = lower_int[user_input_loc_in_preds] ### Output htmls prediction_interval_html = html.Div( [ html.Div([ html.P('Max price'), html.Div(children='₮ {}'.format( comma_me(str(round(upper_int_main_pred)))), style={ 'background': '#ff4e4e', 'padding': '5px 10px', 'border-radius': '10px', 'color': 'whitesmoke', 'margin': '10px auto' }) ], style={ 'display': 'grid', 'grid-template-columns': '1fr 1fr' }), html.Div([ html.P('Mid price'), html.Div(children='₮ {}'.format( comma_me(str(round(mid_int_main_pred)))), style={ 'background': '#9ee3e9', 'padding': '5px 10px', 'border-radius': '10px', 'color': 'whitesmoke', 'margin': '10px auto' }) ], style={ 'display': 'grid', 'grid-template-columns': '1fr 1fr' }), html.Div([ html.P('Min price'), html.Div(children='₮ {}'.format( comma_me(str(round(lower_int_main_pred)))), style={ 'background': '#3dff6f', 'padding': '5px 10px', 'border-radius': '10px', 'color': 'whitesmoke', 'margin': '10px auto' }) ], style={ 'display': 'grid', 'grid-template-columns': '1fr 1fr' }), ], style={ "float": 'left', 'padding': '0 10%', 'grid-area': 'first_con', 'display': 'block', 'border': '1px solid red', 'border-radius': '10px' }) additional_info_html = html.Div( [ html.Div( [ html.Div(children=add_n_kindergts, style={ 'text-align': 'center', 'font-size': '25px', 'margin': 'auto 0' }), html.Div([ html.I(className='fas fa-baby', title='Kindergartens', style={'font-size': '30px'}), html.Plaintext('kindergartens') ], style={'text-align': 'right'}) ], style={ 'background': 'rgb(145, 245, 164)', 'font-size': '18px', 'padding': '10px', 'border-radius': '14px', 'display': 'grid', 'grid-template-columns': '1fr 1fr', 'height': '65px' }), html.Div( [ html.Div(children=add_n_schools, style={ 'text-align': 'center', 'font-size': '25px', 'margin': 'auto 0' }), html.Div([ html.I(className='fas fa-school', title='schools', style={'font-size': '30px'}), html.Plaintext('schools') ], style={'text-align': 'right'}) ], style={ 'background': 'rgb(218, 251, 0)', 'font-size': '18px', 'padding': '10px', 'border-radius': '14px', 'display': 'grid', 'grid-template-columns': '1fr 1fr', 'height': '65px' }), html.Div( [ html.Div(children='{} vs avg {}'.format( round(add_crime_score, 0), round(avg_crimes_per_h1000s)), style={}), html.I(className='fas fa-fist-raised', title='crime', style={'font-size': '30px'}), html.Div([html.Plaintext('crimes per 100,000 ')], style={'text-align': 'right'}) ], style={ 'background': 'rgb(245, 55, 95)', 'font-size': '18px', 'padding': '10px', 'border-radius': '14px', 'display': 'grid', 'grid-template-columns': '1fr 1fr', 'height': '70%' }), html.Div( [ html.Div(children='{} km'.format(add_distance_from_cc), style={ 'text-align': 'center', 'font-size': '25px' }), html.I(className='fas fa-map-marked-alt', title='dfcc', style={'font-size': '30px'}), html.Div([html.Plaintext('from city center')], style={'text-align': 'right'}) ], style={ 'background': 'rgb(145, 245, 234)', 'font-size': '18px', 'padding': '10px', 'border-radius': '14px', 'display': 'grid', 'grid-template-columns': '1fr 1fr', 'height': '70%' }) ], style={ 'grid-area': 'second_con', 'display': 'grid', 'grid-template-columns': '1fr 1fr' }) my_colors = [] for i in range(len(dash_pred_input)): if dash_pred_input['location'][i] == dash_pred_input['location'][ user_input_loc_in_preds]: my_colors.append('rgb(245, 55, 95)') else: my_colors.append('rgb(7, 119, 106)') all_locs_graph = html.Div( [ dcc.Graph( figure={ 'data': [ go.Bar(y=mid_int, x=dash_pred_input['location'], marker={'color': my_colors} # orientation='h' ) ], 'layout': go.Layout(autosize=True, title='Prediction on all locations', yaxis={'ticklen': 10}) }) ], style={'grid-area': 'third_con'}) return prediction_interval_html, additional_info_html, all_locs_graph
html.Div([ html.Button('Buy', id='submit-buy', n_clicks=0), dcc.Input(id="buy-price", type="number", placeholder="Price"), dcc.Input(id="buy-quant", type="number", placeholder="Quantity") ]), html.Div([ html.Button('Sell', id='submit-sell', n_clicks=0), dcc.Input(id="sell-price", type="number", placeholder="Price"), dcc.Input(id="sell-quant", type="number", placeholder="Quantity") ]) ]), html.Plaintext("No buy or sell order", id="result"), html.Div(id='table'), dcc.Interval( id='interval-component-live', interval=1000, # in milliseconds n_intervals=0), dcc.Interval( id='interval-component', interval=10000, # in milliseconds n_intervals=0) ])) live_data = {'time': [], 'price': []} def post_huobi(url, data, api_key, secret_key):
def display_images(entity_1, entity_2): images = [] list_images = get_images() len_list = len(list_images) start = (entity_1 - 1) * entity_2 end = entity_1 * entity_2 list_images = list_images[start:end] for i in range(int(entity_2)): images.append( html.Div([ html.Div( [ html.Div( [html.Plaintext(i + 1)], style={ 'width': '3%', 'text-align': 'center', 'vertical-align': 'middle', 'display': 'inline-block', 'fontWeight': 'bold', 'text-decoration': 'underline', 'font-family': 'Arial, Helvetica, sans-serif' }), html.Div( [ html.Video(src=list_images[i], autoPlay=True, muted=True, loop=True) ], style={ 'width': '20%', 'text-align': 'center', 'vertical-align': 'middle', 'display': 'inline-block', 'fontWeight': 'bold', 'text-decoration': 'underline', 'font-family': 'Arial, Helvetica, sans-serif' }) ], style={ #'borderWidth': 'medium', #'borderColor': 'blue', 'width': '40%', 'display': 'inline-block', 'borderTop': 'thin lightgrey solid', 'borderLeft': 'thin lightgrey solid', 'borderRight': 'thin lightgrey solid', 'borderBottom': 'thin lightgrey solid', 'backgroundColor': 'rgb(250, 250, 250)', 'padding': '40px 40px', 'border-radius': '15px', 'margin-bottom': ' 5px', }), html.Div( [ html.Div( [ # html.Plaintext('Verb Options'), html.Plaintext("1"), html.Hr(), html.Plaintext("2"), html.Hr(), html.Plaintext("3"), ], style={ 'width': '3%', 'display': 'inline-block' }), html.Div( [ # html.Plaintext('Verb Options'), dcc.Dropdown( id={ 'type': 'filter-dropdown', 'id': 'verb_' + str(i) + '_1', }, # id={ # 'type': 'filter-dropdown', # 'index': n_clicks # }, # id='verb_' + str(i) + '_1', options=[{ 'label': i, 'value': i } for i in available_verbs], placeholder="Select a verb", ), html.Hr(), dcc.Dropdown( id={ 'type': 'filter-dropdown', 'id': 'verb_' + str(i) + '_2', }, options=[{ 'label': i, 'value': i } for i in available_verbs], placeholder="Select a verb", ), html.Hr(), dcc.Dropdown( id={ 'type': 'filter-dropdown', 'id': 'verb_' + str(i) + '_3', }, options=[{ 'label': i, 'value': i } for i in available_verbs], placeholder="Select a verb", ), ], style={ 'width': '40%', 'display': 'inline-block' }), html.Div( [ # html.Plaintext('Noun Options'), dcc.Dropdown( id={ 'type': 'filter-dropdown', 'id': 'noun_' + str(i) + '_1', }, options=[{ 'label': i, 'value': i } for i in available_nouns], placeholder="Select a noun", ), html.Hr(), dcc.Dropdown( id={ 'type': 'filter-dropdown', 'id': 'noun_' + str(i) + '_2', }, options=[{ 'label': i, 'value': i } for i in available_nouns], placeholder="Select a noun", ), html.Hr(), dcc.Dropdown( id={ 'type': 'filter-dropdown', 'id': 'noun_' + str(i) + '_3', }, options=[{ 'label': i, 'value': i } for i in available_nouns], placeholder="Select a noun", ) ], style={ 'width': '40%', 'display': 'inline-block', 'float': 'right' }) ], style={ 'width': '40%', 'display': 'inline-block', 'float': 'right', 'borderTop': 'thin lightgrey solid', 'borderLeft': 'thin lightgrey solid', 'borderRight': 'thin lightgrey solid', 'borderBottom': 'thin lightgrey solid', 'backgroundColor': 'rgb(250, 250, 250)', 'padding': '40px 40px', 'border-radius': '15px', 'margin-bottom': ' 5px', }) ])) return html.Div(images)
{'label': 'Thursday', 'value': 'Thursday'}, {'label': 'Friday', 'value': 'Friday'}, {'label': 'Saturday', 'value': 'Saturday'}, {'label': 'Sunday', 'value': 'Sunday'}, ], placeholder="workout day"), dcc.Input(id="time-input", type="text", placeholder="workout time"), dcc.Dropdown(id='focus-dropdown', options=[ {'label': 'Chest', 'value': 'Chest'}, {'label': 'Triceps', 'value': 'Triceps'}, {'label': 'Biceps', 'value': 'Biceps'}, {'label': 'Back', 'value': 'Back'}, {'label': 'Legs', 'value': 'Legs'}, {'label': 'Core', 'value': 'Core'}, {'label': 'Cardio', 'value': 'Cardio'} ], placeholder="workout focus area", multi=True), html.Button('submit', id='submit-button', value='submit')]) status_message = html.Div(className="status-message", children=[html.Plaintext(id="status-text", children="No communication")]) def define_layout(): return \ html.Div(children=[ workout_inputs, status_message ])
def _generate_page(): layout_ = _html.Div( _html.Div([ _html.Div([ _html.Div([ _html.H4('Job Title'), ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div([ _dcc.Input( id='job_title', placeholder='Job Title...', type='text', value='', style={'display': 'inline-block', 'width': '100%'}, ) ], style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div(style={'display': 'table-row', 'width': '100%', 'height': '20px'}), _html.Div([ _html.Div([ _html.H4('Purpose of the role') ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div([ _dcc.Textarea( placeholder='Enter a value...', value=_purpose_of_the_role, style={'width': '100%', 'height': '100px'} ) ], style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div(style={'display': 'table-row', 'width': '100%', 'height': '20px'}), _html.Div([ _html.Div([ _html.H4('Main Duties / Responsibilities'), ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div(style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div([ _html.Div([ _dcc.Dropdown( id='duty_selector', options=[], value='', multi=True, style={'margin-right': '10px'} ), _html.P('*Suggestions are based on common descriptions extracted from ' + 'historical posts that received successful job placement.') ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div([ _dcc.Textarea( id='duties', placeholder='Main Duties / Responsibilities...', value=''.join(_duties.values()), style={'width': '100%', 'height': '120px'} ) ], style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div(style={'display': 'table-row', 'width': '100%', 'height': '20px'}), _html.Div([ _html.Div([ _html.H4('Skills'), ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div(style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div([ _html.Div([ _dcc.Dropdown( id='skill_selector', options=[], value='', multi=True, style={'margin-right': '10px'} ), _html.P('*Suggestions are based on common descriptions extracted from ' + 'historical posts that received successful job placement.') ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div([ _dcc.Textarea( id='skills', placeholder='Skills...', value='', style={'width': '100%', 'height': '120px'} ) ], style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div(style={'display': 'table-row', 'width': '100%', 'height': '20px'}), _html.Div([ _html.Div([ _html.H4('Qualifications & Experience'), ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div(style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div([ _html.Div([ _dcc.Dropdown( id='qual_selector', options=[], value='', multi=True, style={'margin-right': '10px'} ), _html.P('*Suggestions are based on common descriptions extracted from ' + 'historical posts that received successful job placement.') ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div([ _dcc.Textarea( id='qualifications', placeholder='Qualifications & Experience...', value='', style={'width': '100%', 'height': '120px'} ) ], style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div(style={'display': 'table-row', 'width': '100%', 'height': '20px'}), _html.Div([ _html.Div([ _html.H4('Salary Range'), ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div(style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div([ _html.Div([ _html.Div( _dcc.Dropdown( id='state_selector', options=[ {'label': 'NSW', 'value': 'NSW'}, {'label': 'ACT', 'value': 'ACT'}, {'label': 'VIC', 'value': 'VIC'}, {'label': 'QLD', 'value': 'QLD'}, {'label': 'WA', 'value': 'WA'}, {'label': 'NT', 'value': 'NT'}, {'label': 'TAS', 'value': 'TAS'}, ], value='NSW', multi=False, clearable=False, style={'width': '100px'} ), style={'margin-right': '10px', 'display': 'inline-block'} ), _html.Div( _dcc.Dropdown( id='area_selector', options=[ {'label': 'All Sydney', 'value': 'Sydney'}, {'label': 'All ACT', 'value': 'ACT'}, ], value='Sydney', multi=False, clearable=False, style={'width': '250px'} ), style={'display': 'inline-block'} ) ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div([ _html.Div( _dcc.Dropdown( id='salary_low', options=[ {'label': '$100,000', 'value': 100000}, {'label': '$110,000', 'value': 110000}, {'label': '$120,000', 'value': 120000}, {'label': '$130,000', 'value': 130000}, {'label': '$140,000', 'value': 140000}, {'label': '$150,000', 'value': 150000}, ], value=100000, style={'width': '200px'} ), style={'display': 'inline-block', 'margin-right': '10px'} ), _html.Plaintext('-', style={'display': 'inline-block', 'margin-right': '10px', 'vertical-align': 'top'}), _html.Div( _dcc.Dropdown( id='salary_high', options=[ {'label': '$100,000', 'value': 100000}, {'label': '$110,000', 'value': 110000}, {'label': '$120,000', 'value': 120000}, {'label': '$130,000', 'value': 130000}, {'label': '$140,000', 'value': 140000}, {'label': '$150,000', 'value': 150000}, ], value=130000, style={'width': '200px'} ), style={'display': 'inline-block', 'margin-right': '10px'} ), _html.P('*Suggestion is based on ATO\'s personal income statistics of the selected region ' + 'and industry, adjusted for LMIP\'s regional employment statistics by industry.'), ], style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div(style={'display': 'table-row', 'width': '100%', 'height': '20px'}), _html.Div([ _html.Div([ _html.H4('Other'), ], style={'display': 'table-cell', 'width': '40%', 'vertical-align': 'top'}), _html.Div([ _dcc.Textarea( placeholder='(Optional)', value='', style={'width': '100%', 'height': '120px'} ) ], style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), _html.Div(style={'display': 'table-row', 'width': '100%', 'height': '20px'}), _html.Div([ _html.Div(style={'display': 'table-cell', 'width': '40%'}), _html.Div([ _html.Button('Preview', id='preview_button') ], style={'display': 'table-cell', 'width': '60%'}), ], style={'display': 'table-row', 'width': '100%'}), ], style={'display': 'table', 'width': '100%'}), id='template_div', style={'width': '1200px', 'margin': '0 auto'} ) return layout_
def serve_layout(): return html.Div( [ # Overall header html.H1( children='Covid-19 : Data Analysis and Forecasting for India', style={ 'textAlign': 'center', 'margin-top': '20px' }), # header html.Div([ html.P( [ '''Dashboard for analysing and forecasting the spread of the pandemic using Mathematical curve fitting, Time-Series forecasting and Supervised Machine Learning models and metrics. The metrics and forecasts update on app load and any subjective analysis was written in the first week of September.''', html.Br(), html.B('Disclaimer : '), '''The authors of the dashboard are not epidemiologists and any analysis and forecasting is not be taken seriously.''' ], style={ 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), ]), # Div - Nationwide Analysis html.Div([ html.H4('Nation-wide Statistics', style={ 'textAlign': 'left', 'margin-top': '25px', 'margin-left': '15px', 'margin-right': '15px' }), dcc.Graph(id='national-stats'), html.Div([ dcc.Dropdown( id='nat-graph-selector', options=[{ 'label': i, 'value': i } for i in [ 'Daily Statistics', 'Cumulative Statistics', 'Weekly Moving Average', 'Relative Recovery, Death rate' ]], value='Daily Statistics', style={ 'width': '50%', 'align-items': 'left', 'justify-content': 'center', 'margin-left': '10px', 'margin-right': '15px' }), dcc.RadioItems(options=[ { 'label': 'Linear', 'value': 'linear' }, { 'label': 'Log', 'value': 'log' }, ], value='linear', labelStyle={ 'display': 'inline-block', 'margin': 'auto' }, id='radio-national-scale-selector', style={ 'width': '50%', 'display': 'inline-block', 'align-items': 'center', 'justify-content': 'center', 'margin-left': '30px', 'margin-right': '15px' }) ]), html.P( [ """There is a weekly seasonal pattern to the number of new cases reported which can be smoothed by taking a 7-day moving average. The relative increase in confirmed cases, recoveries and deaths can be better visualised by viewing the graphs on the log scale. Looking at the relative recovery and death rate graph, the death rate appears to be much lower than the worldwide rate of 4%.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), ]), # Div - Testing Analysis html.Div(children=[ html.H4(children='Testing Statistics', style={ 'textAlign': 'left', 'margin-top': '25px', 'margin-left': '15px', 'margin-right': '15px' }), dcc.Graph(id='testing-national'), html.Div([ dcc.Dropdown(id='Testing-graph-drop', options=[{ 'label': i, 'value': i } for i in [ 'Daily Testing and Cases', 'Moving Average', 'Relative Metrics' ]], value='Daily Testing and Cases', style={ 'width': '50%', 'align-items': 'left', 'justify-content': 'center', 'margin-left': '10px', 'margin-right': '15px' }), dcc.RadioItems(options=[ { 'label': 'Linear', 'value': 'linear' }, { 'label': 'Log', 'value': 'log' }, ], value='linear', labelStyle={ 'display': 'inline-block', 'margin': 'auto' }, id='radio-national-test-scale', style={ 'width': '50%', 'display': 'inline-block', 'align-items': 'center', 'justify-content': 'center', 'margin-left': '30px', 'margin-right': '15px' }) ]), html.P( [ """The Seasonality in the data seems to be due to a decrease in the collection of Testing Samples on the weekends. The positivity rate tracks the percentage of tests that results in a positive and is used to determine whether enough tests are being done. The tests per 1000 people is useful for tracking the penetration of the testing relative to the population size.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), ]), # Modelling state-wise statistics html.Div( [ html.H4(children='State-Wise Statistics ', style={ 'textAlign': 'left', 'margin-top': '15px', 'margin-left': '15px', 'margin-right': '15px' }), dcc.Dropdown(id='states-xaxis-column', options=[{ 'label': i, 'value': i } for i in states], value='Maharashtra'), dcc.Graph(id='state-stats'), html.P([ """Data and metrics for states; drop-down list sorted by the the total number of new cases in the state for the last week. The Growth Factor is a metric used to track the exponential growth of a pandemic and has been discussed later. Observe that some states like Delhi show clear evidence of multiple waves of cases.""" ]), ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), # Div - Modelling Cumulative Growth as a logistic function html.Div(children=[ html.H4(children='Modeling Epidemic Growth : Logistic curve', style={ 'textAlign': 'left', 'margin-top': '25px', 'margin-left': '15px', 'margin-right': '15px' }), html.P( [ """The Logistic function is an example of a sigmoid curve and was devised as a model of population growth. Epidemic growth is also observed to follow a logistic curve where the number of infected rises exponentially and reaches an inflection point before gradually decreasing.""", """The logistic function is defined as : \\begin{gather} f{(x)} = \\frac{L}{1 + e^{-k(x - x_0)}} \end{gather} $ \\text{Where, } x_0 = x\\text{ is the value of the sigmoids midpoint, }$""", html.Br(), """ $ L =\\text{the curve's maximum value and, }$""", html.Br(), """ $ k =\\text{the logistic growth rate or steepness of the curve}$ """, html.Br(), html.Br(), """The presence of multiple waves of exponential growth can be a problem for such a simple model and is just used as a starting point. For confirmed cases in India an important task is to determine whether the initial exponential growth has slowed down and whether the inflection point of the pandemic has been reached.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), html.P( [ html.H5("Fitting a Logistic curve to forecast cases"), """Using only the 'days since first case' as a dependent variable and SciPy's optimise module we use non-linear least squares to fit a general logistic function and estimate the parameters :""", html.Br(), """L = Predicted total number of cumulative cases of of the virus.""", html.Br(), """x0 = Predicted date the inflection point of the virus growth is reached.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify', 'margin-bottom': '5px' }), # Actual plot with the forecast dcc.Graph(id='fit-logistic', figure=figure_log_curve), html.P( [ """A simple logistic curve fit will not be able to account for seasonality or complex interactions. Since this is time-series data, the samples are not independent and the data was not shuffled before being split into train-validation sets. The evaluation metrics have been calculated on the daily predictions and the transformation from total to daily cases loses a data point.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify', 'margin-bottom': '15px' }), html.Div([ dash_table.DataTable( id='Logistic-fit-table', columns=[{ 'name': 'Model', 'id': 'Model' }, { 'name': 'R^2', 'id': 'R^2' }, { 'name': 'MAPE(%)', 'id': 'MAPE' }, { 'name': 'RMSE(Cases)', 'id': 'RMSE' }, { 'name': 'Predicted Cumulative Cases (L)', 'id': 'L' }, { 'name': 'Predicted Date of Inflection Point ($x_0$)', 'id': 'x0' }], data=log_fit_metrics, style_cell={ 'whiteSpace': 'normal', 'height': 'auto', }, sort_action="native", style_header={'fontWeight': 'bold'}) ], style={ 'margin-left': '25%', 'margin-right': '25%' }), html.Div([ html.P( [ html.B('Evaluation Metrics reported:'), html.Br(), """1. The R-Squared ($R^2$) score is not particularly useful for forecast quality evaluation but is useful for comparing to the null model ( which always predicts the mean of the data) and across models.""", html.Br(), """2. The Mean Absolute Percentage Error (MAPE) is a simple metric that can be interpreted as a percentage and favors forecasts that underestimate cases rather than ones that will overestimate it. It is unbounded for large positive errors.""", html.Br(), """3. The Root Mean Squared Error (RMSE) penalises larger errors more severely and can be interpreted in the target or 'cases' scale. """ ], style={ 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }) ]) ]), # Modelling growth factor/rate of virus. html.Div(children=[ html.H4( children= 'Growth Factor of Epidemic : Finding the Inflection Point', style={ 'textAlign': 'left', 'margin-top': '15px', 'margin-left': '15px', 'margin-right': '15px' }), html.P( [ """The growth factor is the factor by which a quantity multiplies itself over time, in our case the growth factor would measure the factor by which the daily new cases grow. It can be used to find insights into the exponential growth of an epidemic. The Growth Factor on day n is defined as : \\begin{gather} Gf_{n} = \\frac{\Delta{C_{n}}}{\Delta{C_{n-1}}} \end{gather} I.e. the ratio of change in total or cumulative confirmed cases on day n and day n-1. This can also be framed as the ratio of the number of new cases on day n and day n-1. The metric has a few helpful properties : """, html.Br(), """ 1. A $ Gf > 1 $ signifies exponential growth in the number of new cases.""", html.Br(), """ 2. A $ Gf < 1 $ signifies decline or decay in the number of new cases.""", html.Br(), """3. A $ Gf = 1 $ is the inflection point and signifies the point where exponential growth of the epidemic has plateaued.""" ], style={ 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), dcc.Graph(id='national-growth-factor'), dcc.Dropdown(id='radio-growth-factor-selector', options=[{ 'label': i, 'value': i } for i in [ 'Growth Factor Weekly Moving Average', 'Comparison of Growth Factor', 'Daily Growth Factor' ]], value='Growth Factor Weekly Moving Average', style={ 'width': '50%', 'align-items': 'left', 'justify-content': 'center', 'margin-left': '10px', 'margin-right': '15px' }), html.P( [ """ If the current growth factor is much lower than median growth factor and also consistently below the inflection point, it might indicate that the initial exponential growth of cases is over. The comparison of growth factor graph can also be useful for identifying subsequent waves of cases by comparing the mean growth factor of the last week, month and overall mean growth factor. """, html.Br(), html.H5('Forecasting Growth Factor'), """A SARIMA(1, 1, 1)x(0, 1, 1, 7) model that takes into account the weekly seasonality is used as a traditional time-series forecasting baseline. The mean growth factor of the last month before validation split is also provided as a baseline.""", html.Br(), html.B('Forecasting as a ' 'Supervised Learning ' 'Problem'), html.Br(), """To use traditional supervised learning algorithms with time-series, features are extracted that take into account the time aspect of the data, such as the """, html.B('lag'), """ of the Growth Factor for the last 7 days and """, html.B('date features'), """ ( day of the month, day of the week). A Linear Regression and a Ridge Regression model are used here to forecast the growth factor. The Ridge Regression model is used with second-degree polynomial features and $l_2$ regularization.""", html.Br(), html.B('Recursive Multi-step Forecasting'), html.Br(), """The regression models use multiple lags of the target (t-1 to t-n) as input features. This is a problem at inference and validation time as predictions at t+2 would need lags of the target that aren't available. A solution is to recursively predict the growth factor for the next data and use it as a lag feature on the next day. The validation performance has been evaluated with this recursive approach.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), dcc.Graph(id='forecast-growth-factor', figure=figure_forecast_gf), html.Div([ dash_table.DataTable(id='growth-factor-table', columns=[ { 'name': 'Model', 'id': 'Model' }, { 'name': 'R^2', 'id': 'R^2' }, { 'name': 'MAPE(%)', 'id': 'MAPE' }, { 'name': 'RMSE', 'id': 'RMSE' }, ], data=eval_metrics_gf, sort_action="native", style_header={'fontWeight': 'bold'}) ], style={ 'margin-left': '25%', 'margin-right': '25%' }), html.P( [ """ Growth Factor as a transformation is destructive and cannot be used to directly estimate the number of cases or forecast the cumulative cases. It is still an important metric for understand the pattern of the growth in the number of cases.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }) ]), # Forecasting Daily Cases. html.Div(children=[ html.H4('Forecasting Daily New Cases', style={ 'textAlign': 'left', 'margin-top': '15px', 'margin-left': '15px', 'margin-right': '15px' }), html.P( [ """A SARIMA(1, 1, 0)x(0, 1, 1, 7) is used as a traditional time-series forecasting baseline. For the supervised learning approach, A Lasso regression model with sliders for feature extraction and hyper-parameter tuning is provided below. A Lasso regression model applies $l_1$ regularisation to create sparse models that automatically perform feature selection. Date features in addition to the lagged target features are used and a recursive approach is used for the forecast when using lag features.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), ], style={'padding': '5px'}), dbc.Container( fluid=True, children=[ dbc.Row([ dbc.Col([ dbc.Label('Features and Hyper-parameters:', size='md', style={'margin-top': 20}), html.Div([ dbc.Label('Target Lags:'), dcc.Slider( id='cases-lag-sel', min=1, max=21, value=7, marks={ 7: { 'label': '7-Lags', 'style': { 'color': '#77b0b1' } }, 14: { 'label': '14-Lags' }, 21: { 'label': '21-Lags' }, }, ) ], style={'margin-top': 20}), html.Div([ dbc.Label('L1 Regularisation:'), dcc.Slider(id='cases-regularisation-sel', min=1, max=9000, value=4500, marks={ 1: { 'label': '1 (Default)', 'style': { 'color': '#77b0b1' } }, 4500: { 'label': '4500' }, 9000: { 'label': '9000' }, }) ], style={'margin-top': 20}), html.Div([ dbc.Label('Polynomial Features:'), dcc.Slider(id='cases-poly-sel', min=1, max=3, value=1, marks={ 1: { 'label': '1 (None)', 'style': { 'color': '#77b0b1' } }, 2: { 'label': '2nd Degree' }, 3: { 'label': '3rd Degree' }, }) ], style={'margin-top': 20}), ], width=2), dbc.Col([dcc.Graph(id="national-pred-cases")], width=6), dbc.Col([dcc.Graph(id="national-pred-feat-imp")], width=4) ]), html.Plaintext("""* Not all features shown in figure.""", style={ 'margin-top': '0px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'right' }), ]), html.Div([ dash_table.DataTable(id='Cases-fit-table', columns=[{ 'name': 'Model', 'id': 'Model' }, { 'name': 'R^2', 'id': 'R^2' }, { 'name': 'MAPE(%)', 'id': 'MAPE' }, { 'name': 'RMSE(Cases)', 'id': 'RMSE' }], style_cell={ 'whiteSpace': 'normal', 'height': 'auto', }, sort_action="native", style_header={'fontWeight': 'bold'}) ], style={ 'margin-left': '25%', 'margin-right': '25%' }), # Modelling growth ratio of virus. html.Div([ html. H4(children= 'Growth Ratio of Epidemic : A Non-Destructive Transformation', style={ 'textAlign': 'left', 'margin-top': '15px', 'margin-left': '15px', 'margin-right': '15px' }), html.P( [ """The growth ratio is a metric that represents the percentage Increase in total cumulative cases from one day to the next. The growth ratio on day n is defined as : \\begin{gather} Gr_{n} = \\frac{{C_{n}}}{{C_{n-1}}} \end{gather} I.e. the ratio of total or cumulative confirmed cases on day n and day n-1. The transformation is not that interesting in itself but can be used to forecast the number of new cases.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), dcc.Graph(id="national-growth-ratio", figure=fig_gr), html.P( [ """For the growth ratio of cumulative cases, a decaying trend is observed. As the number of reported new cases of the virus becomes negligible the ratio of cumulative cases will tend to its lower bound of 1.""", html. H5('Forecasting Growth Ratio Using Generalized Linear Models' ), """ Looking at the decaying trend, it could be useful to fit a Generalized Linear Models (GLM) with a suitable link function to the data. GLMs are used to model a relationship between predictors $(X)$ and a non-normal target variable $(y)$. For a GLM with parameters $(w)$, the predicted values $(\hat{y})$ are linked to a linear combination of the input variables $(X)$ via an inverse link function $h$ as : \\begin{gather} \hat{y}(w, X) = h(Xw). \end{gather} So, the resulting model is still linear in parameters even though a non-linear relationship between the predictors and target is being modelled.""", html.Br(), html.B("Poisson Regression"), html.Br(), """Assumes the target to be from a Poisson distribution, typically used for data that is a count of occurrences of something in a fixed amount of time. The Poisson process is also commonly used to describe and model exponential decay. The inverse link function $h$ used in Poisson regression is $h = \exp(Xw)$ and the target domain is $y \in [0, \infty)$. A value of 1 is subtracted from the growth ratio almost meet this constraint.""", html.Br(), html.B("Gamma Regression"), html.Br(), """ Assumes the target to be from a Gamma distribution, which is typically used to model exponential target data. The inverse link function $h$ used in Gamma regression is $h = -(Xw)^{-1}$ and the target domain is $y \in (0, \infty)$. Shifting the growth ratio by 1 meets this constraint.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), html.P( [ """A traditional forecasting Autoregressive AR(7) model has been used as a baseline. No regularisation has been used. Degree 2 polynomial transformed and scaled Lag of growth ratio for the previous 7-days along with date features has been used as features for the GLMs. The forecasts are performed and evaluated with a recursive multi-step approach. As the train-test split was done before creating lag features the first 7 data points have been dropped.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), dcc.Graph(id="national-growth-ratio-preds", figure=figure_forecast_gr), html.Div([ dash_table.DataTable(id='growth-ratio-table', columns=[ { 'name': 'Model', 'id': 'Model' }, { 'name': 'R2', 'id': 'R2' }, { 'name': 'MAPE(%)', 'id': 'MAPE' }, { 'name': 'RMSE(GR)', 'id': 'RMSE' }, ], data=eval_metrics_gr, sort_action="native", style_header={'fontWeight': 'bold'}) ], style={ 'margin-left': '25%', 'margin-right': '25%' }), html.Plaintext( """* Click on the legend and toggle visibility for other forecasts.""", style={ 'margin-top': '0px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'right' }), html.P( [ html.H5('Using Growth Ratio to Forecast Cases'), """ The predicted Growth Ratio for day n can simply be multiplied with the Total cases of the previous day to get the predicted Total confirmed cases on day n: \\begin{gather} \hat{C_{n}} = C_{n-1}\\times{\hat{Gr_{n}}}\end{gather} The predictions can then be differenced to get the predicted Daily cases on day n+1. This approach will lead to the loss of a couple of data points at validation time.""" ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), dcc.Graph(id="national-growth-ratio-cases-preds", figure=figure_forecast_cases_gr), html.Div([ dash_table.DataTable(id='growth-ratio-cases-table', columns=[{ 'name': 'Model', 'id': 'Model' }, { 'name': 'R^2', 'id': 'R^2' }, { 'name': 'MAPE(%)', 'id': 'MAPE' }, { 'name': 'RMSE(GR)', 'id': 'RMSE' }], data=eval_metrics_cases_gr, sort_action="native", style_header={'fontWeight': 'bold'}) ], style={ 'margin-left': '25%', 'margin-right': '25%' }), html.Div( [ html.P([ html.H5('Insights and Summary'), """Multiple different metrics for tracking the spread of the Coronavirus pandemic are presented here. Looking at the performance of the different forecasting methods it is evident that traditional forecasting models prove to be good baseline models in data-starved situations. Supervised machine learning models can outperform the traditional models after careful feature extraction and tuning but generally provide less stable results.""" ]) ], style={ 'margin-top': '10px', 'margin-left': '25px', 'margin-right': '25px', 'textAlign': 'justify' }), html.Div([ html.P([ html.B('References and Data Sources: '), html.Br(), html. A('[1] 3Blue1Brown', href='https://www.youtube.com/watch?v=Kas0tIxDvrg'), html.Br(), html. A('[2] Journal of Medical Academics', href='https://www.maa.org/book/export/html/115630'), html.Br(), html.A( '[3] Daily Case Statistics: covid19india.org API', href='https://github.com/covid19india/api'), html.Br(), html.A('[4] Daily ICMR Testing Data: Data Meet', href='https://github.com/datameet/covid19') ]) ], style={ 'margin-left': '25px', 'margin-right': '25px' }) ]), ###### important for latex ###### axis_latex_script, ###### important for latex ###### mathjax_script, ], style={ 'margin-left': '25px', 'margin-right': '25px' })
if __name__ == "__main__": app = dash.Dash() voting_history = VotingHistory( "csv_files") # Voting history is a container for all votes options = voting_history.get_selection_options( ) # All votes you can choose from. # Define the layout of the app. # Source: https://pythonprogramming.net/vehicle-data-visualization-application-dash-python-tutorial/ app.layout = html.Div(children=[ html.Plaintext( 'Note that the app might be quite slow, you might need to wait a minute for things to happen. Do not select more than 10 votes because this makes it really slow.', className='row', style={'padding-top': '20px'}), dcc.Dropdown( id='input', options=voting_history.get_selection_options(), value=[441, 393, 392, 391 ], # Some random votes to initialze the figure. multi=True), dcc.Graph(id='output') ]) # The update function: # Source: https://pythonprogramming.net/dynamic-data-visualization-application-dash-python-tutorial/ @app.callback(Output(component_id='output', component_property='figure'), [Input(component_id='input', component_property='value')]) def update_value(input_data):