I am building dashboard for plotting graphs with an opportunity to exclude outliers by clicking on points on graph and change that data with interpolated values.
The main idea of this dashboard - make data preparation faster and easier for people that does not use python. Also this dash will be used for simple data visualisation (kinda power BI handmade). After all iterations new file will be writen as .csv without outliers.
Working on this task i ran into 2 problems:
- How to connect imported by dashboard interface data with plot layout. (and it is the main problem)
- How to choose points on the graph or choose time period in datePickerRange, delete values and interpolate ( scipy.interpolate.interp1d ) missing(deleled) values or change them with moving mean ( pd.rolling_mean() ).
There is code block for data parsing data:
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('cp1251')), sep = ';' )
elif 'tsv' in filename:
# Assume that the user uploaded a TSV file
df = pd.read_csv(io.StringIO(decoded.decode('utf-8')), sep = '\t')
elif 'xls' in filename:
# Assume that the user uploaded an excel file
df = pd.read_excel(io.BytesIO(decoded))
elif 'xlsx' in filename:
# Assume that the user uploaded an excel file
df = pd.read_excel(io.BytesIO(decoded))
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('rows'),
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'
})
])
and callback function for input box:
@dashboard.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
This part of code literally was taken from official documentation. It is really cool that i can look on uploaded data, but i would like to use columns names and date from these cols for plotting, like i do it in pandas.
For col name choosing i create two dropdown components:
#Create dropdown for X-axis
html.Div([
dcc.Dropdown(
id = 'xaxis-column',
options = [{'label': i, 'value': i} for i in df.columns],
value = 'Xdate')],
style = {'width': '48%', 'display': 'inline-block'}),
#Create dropdown for Y-axis
html.Div([
dcc.Dropdown(
id = 'yaxis-column',
options = [{'label': i, 'value': i} for i in df.columns],
value = 'Yval')],
style = {'width': '48%', 'float': 'right', 'display': 'inline-block'})
And the part of code for graph drowing:
dcc.Graph(id = 'graph')
@dashboard.callback(
Output('graph', 'figure'),
[Input('xaxis-column', 'value'),
Input('yaxis-column', 'value'),
Input('xaxis-type', 'value'),
Input('yaxis-type', 'value'),
Input('XYeardate--slider', 'value')])
def update_graph(xaxis_column_name, yaxis_column_name,
xaxis_type, yaxis_type, Year_value):
dff = df[df['XYeardate'] == Year_value]
return {
'data': [go.Scatter(
x = dff[dff['Xval'] == xaxis_column_name]['Xdate'],
y = dff[dff['Xval'] == yaxis_column_name]['Yval'],
text = dff[dff['Xval'] == yaxis_column_name]['ID'],
mode = 'markers',
marker = {
'size': 10, #was 'size': 15
'opacity': 0.5,
'line': {'width': 0.5, 'color': 'white'}})],
'layout': go.Layout(
xaxis = {
'title': xaxis_column_name,
'type': 'linear' if xaxis_type == 'Linear'},
yaxis = {
'title': yaxis_column_name,
'type': 'linear' if yaxis_type == 'Linear'},
margin = {'l': 40, 'b': 40, 't': 10, 'r': 0},
hovermode = 'closest')}
I can add other parts of code in comments if needed.
Any comments would be appreciated!