How to refresh the dataframe when uploading new file in dash or reloading the page

#1

Unable to reload the dataframe object on page reload or refreshor everytime a new data file is being uploaded

I have created a python dash web application which filters out a dataframe (pre-loaded in the backend) based on user uploaded input file and displays the filtered dataframe as a dash table.

The problem is that the display does no go away on page upload or page refresh. Also, if the user uploads a new data file, the new results are appended in the old one.

This is not I want. I want to have a new result - everytime

  • when new data is uploaded
    or

  • the page is refreshed or reloaded

    import base64
    import io
    import pandas as pd
    import dash
    from dash.dependencies import Input, Output
    import dash_core_components as dcc
    import dash_html_components as html
    import dash_table

    gene_coverage_dictionary = {}
    gene_names , coverage_values = [], []

    try:
    coverage_file = open(“gene_coverage.csv”)
    for gene in coverage_file:
    gene = gene.rstrip().split(",")
    gene_coverage_dictionary[gene[0]] = gene[1]

    except IOError:
    print(“gene_coverage.csv cannot be opened !”)

    external_stylesheets = [‘https://codepen.io/chriddyp/pen/bWLwgP.css’]

    app = dash.Dash(name, external_stylesheets=external_stylesheets)
    server = app.server

    gene_list_imagename = ‘gene_list.gif’
    gene_list_encoded_image = base64.b64encode(open(gene_list_imagename, ‘rb’).read())

    app.layout = html.Div([
    html.H1(“Coverage-App”, style={‘textAlign’:‘center’, ‘color’:’#2f0975’, ‘font-size’:‘50px’,‘font-family’:‘Comic Sans, Comic Sans MS, cursive’}),
    html.H6(“A web app for observing coverage”, style={‘textAlign’:‘center’}),

      dcc.Upload(
          id='upload-data',
          children=html.Div([
              'Drag and Drop gene list or ',
              html.A('Select gene list')
          ]),
          style={
              'width': '99%',
              'height': '60px',
              'lineHeight': '60px',
              'borderWidth': '2px',
              'borderStyle': 'solid',
              'borderRadius': '5px',
              'textAlign': 'center',
              'margin': '5px',
              'backgroundColor': '#e5e5e5'
    
    
          },
          multiple=False
      ),
      # adding space between drag drop button and the output table
      
      html.Img(src='data:image/png;base64,{}'.format(gene_list_encoded_image.decode()), style={'width':'320px','height':'190px'}),
      html.Label([' Got a CSV file? Use this ', html.A('tool', href='https://convert.town/comma-separated-list-to-column') ],style={'borderRadius': '5px','backgroundColor' : '#FFDB00', 'width':'12%', 'font-weight': 'bold','padding': '5px'}),
      html.Div(id='output-data-upload'),
    
    ])
    
    
    
      def parse_contents(contents):
    
      content_type, content_string = str(contents).split(',')
      decoded = base64.b64decode(content_string)
    
      gene_list =  io.StringIO(decoded.decode('utf-8'))
      # unique list from user provided set
      gene_list = set([str(i.strip()) for i in gene_list])
      gene_list = list(gene_list)
      for gene in gene_list:
          gene = str(gene.strip())
          if gene in gene_coverage_dictionary:
              gene_names.append(gene)
              coverage_values.append(float(gene_coverage_dictionary[gene]))
    
      data={ 'Coverage': coverage_values, 'Gene': gene_names}
    
      df = pd.DataFrame(data) 
      cols = sorted(list(df.columns.values), reverse = True)
      
      return html.Div([
      	   html.Div('Coverage ( %age of gene covered ) >= 90 %',style={'padding': '20px', 'color' : '#77bf5f','font-weight': 'bold','margin': '0px','padding': '0px'}),
             html.Div('Coverage ( %age of gene covered ) < 90 % ',style={'padding': '20px', 'color' : '#f96868','font-weight': 'bold','margin': '0px','padding': '0px'}),
      
              dash_table.DataTable(
              data=df.to_dict('records'),
              sorting=True,
              filtering=True,
              columns=[{'name': i, 'id': i} for i in cols],
              style_cell={'padding': '8   px', 'textAlign': 'left'},
              style_header={'backgroundColor': 'white','fontWeight': 'bold', 'color': 'black'},
              style_table={'maxHeight': '470px','overflowY': 'scroll','border': 'thin lightgrey solid'},
              n_fixed_rows=1,
              style_cell_conditional=[
    
              {   'if': {'column_id': 'Coverage'},
                  'width': '10%'},
              {   'if': {'column_id': 'Gene'},
                  'width': '2%'},
    
              { 
                  'if': {
                  'row_index': 'odd'
                  },
                  'backgroundColor': 'rgb(248, 248, 248)'
                  },
              {
                  'if': {
                  'column_id': 'Coverage',
                  'filter' : 'Coverage >= num(90)'
                  },
                  'backgroundColor':'#ecffe0',
                  'color': 'black',
                  }, 
              
              
              {
                  'if': {
                  'column_id': 'Coverage',
                  'filter' : 'Coverage < num(90)'
                  },
                  'backgroundColor':'#ffe0e0',
                  'color': 'black',
                  } 
    
              ]
    
          ) 
          ])
    

    @app.callback(Output(‘output-data-upload’, ‘children’),
    [Input(‘upload-data’, ‘contents’)])

    def update_output(contents):
    if contents is not None:
    children = parse_contents(contents)
    return children

    if name == ‘main’:
    app.run_server(debug=True)