Hi Dash Community,
I’m new to the Dash and Plotly ecosystem and am very impressed with the functionality. I’m trying to build a simple web dashboard. The workflow is:
- the user uploads a CSV file
- a Pandas data frame is created from the data in the file in step 1
- a bar chart is created from the data frame in step 2
The data in my CSV file looks similar to the following:
df = pd.DataFrame({'Make':['Ford', 'Ford', 'Ford', 'Buick', 'Buick', 'Buick', 'Mercedes', 'Mercedes', 'Mercedes'],
'Score':['88.6', '76.6', '86.', '79.1', '86.8', '96.4', '97.3', '98.7', '98.5'],
'Dimension':['Speed', 'MPG', 'Styling', 'Speed', 'MPG', 'Styling', 'Speed', 'MPG', 'Styling'],
'Month':['Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19', 'Apr-19']})
My code is as follows:
import base64
import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
import dash_core_components as dcc
import dash_table
import datetime
from datetime import datetime as dt
import io
import os
import pandas as pd
import plotly.figure_factory as ff
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import re
# import the data
file_name = 'the_source_data.xlsx'
df = pd.read_excel(file_name)
# get a list of dimensions
dimensions = df[(df['Dimension'] != '<null>') & (df['Make'].isin(['Ford', 'Buick', 'Mercedes', 'BMW']))]['Dimension'].unique().tolist()
# get the scores
ford_scores = df[(df['Make'].isin(['Ford']))]['Score'].tolist()
buick_scores = df[(df['Make'].isin(['Buick']))]['Score'].tolist()
mercedes_scores = df[(df['Make'].isin(['Mercedes']))]['Score'].tolist()
bmw_scores = df[(df['Make'].isin(['BMW']))]['Score'].tolist()
# define the figures
fig_01 = go.Figure(data=[
go.Bar(name='Ford', x=dimensions, y=ford_scores, text=ford_scores, textposition='auto'),
go.Bar(name='Buick', x=dimensions, y=buick_scores, text=buick_scores, textposition='auto'),
go.Bar(name='Mercedes', x=dimensions, y=mercedes_scores, text=mercedes_scores, textposition='auto')
])
fig_01.update_layout(barmode='group',
title='Dimensions by Car Maker',
xaxis_title='Dimension',
yaxis_title='Score')
# initialize the application
app = dash.Dash()
# define the layout of the app
app.layout = html.Div([
html.Div([
dcc.Upload(
id='upload-data',
children=html.Div([
'Drag and Drop or ',
html.A('Select Files')
]),
style={
'width' : '50%',
'height' : '60px',
'lineHeight' : '60px',
'borderWidth' : '1px',
'borderStyle' : 'dashed',
'borderRadius' : '5px',
'textAlign' : 'center',
'margin' : '10px'
},
multiple=True
),
html.Div(id='output-data-upload'),
]),
# add the bar plot
dcc.Graph(id='dash_graph_01',
figure = fig_01),
])
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 'txt' or 'tsv' in filename:
# assume that the user uploaded a TXT file
df = pd.read_csv(io.StringIO(decoded.decode('utf-8')), delimiter = r'\s+')
except Exception as e:
print(e)
return html.Div([
'There was an error processing this file.'
])
return html.Div([
html.H5(filename),
html.H6(datetime.datetime.fromtimestamp(date)),
dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'name': i, 'id': i} for i in df.columns]
),
html.Hr(), # horizontal line
# for debugging, display the raw contents provided by the web browser
html.Div('Raw Content'),
html.Pre(contents[0:10] + '...', style={
'whiteSpace': 'pre-wrap',
'wordBreak': 'break-all'
})
])
@app.callback(Output('output-data-upload', 'children'),
[Input('upload-data', 'contents')],
[State('upload-data', 'filename'),
State('upload-data', 'last_modified')])
def update_output(list_of_contents, list_of_names, list_of_dates):
if list_of_contents is not None:
children = [
parse_contents(c, n, d) for c, n, d in
zip(list_of_contents, list_of_names, list_of_dates)]
return children
if __name__ == '__main__':
app.run_server(debug = True)
I’m able to upload and view the contents of the CSV file.
However, the CSV file has no effect on the bar plot because the data frame is defined by the df
object created from the call to the pd.read_excel(file_name)
function.
How do I get Dash to build the bar plot based on the data in the CSV file that’s uploaded using the parse_contents(contents, filename, date)
function?
I tried to follow along in Using dash upload component to upload csv file and generate a graph, but was unable to implement that example successfully.
Thanks in advance for helping a newbie get this toy example working!
1 post - 1 participant