✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Unable to present a line graph from Table in a callback

Hello, Im working on a national project and Dash seems to be the perfect solution for data presentation.
However, I have a problem with creating a line graph from a datatable.
my data table contains 17 columns of chemical information and from the 18th column I have wavelengths 350 until 2500 nm… its a big data set.
The chemical data is easy to present, however, I have encountered few problems with displaying the spectral data (350-2500 nm)
I would like to select rows in the datatable and for each selected row, I would like it to read the information from columns 18 until the end (xaxis = the column names and yaxis = the value in the selected rows).

my problems are:

  1. when I try to display the entire data, the web app get stuck/slow down because its a lot of data.
    is it possible to show only certain columns in the datatable (0-18) but still use the rest of the columns for the callback?
  2. I have a problem to do a callback (relate the table to the line graph)

I’m trying to solve this problem for over two weeks so I need some assistance here, please.
Thank you

p.s - The last callback I copied from somewhere but it doesn’t work anyway…

import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt
import pandas as pd
import plotly
from plotly import graph_objs as go
from plotly.graph_objs import *
from dash.dependencies import Input, Output, State, Event

app = dash.Dash(name)
server = app.server
app.title = ‘SSL’

API key and dataset

map_access_token = ‘pk.eyJ1IjoieWFyb25vZ2VuIiwiYSI6ImNqbDY5YjJ0OTJ1eWkza2w3cjBpeTM5cWQifQ.9G16xR4pgEW9_aJ1sm7_rw’
df = pd.read_csv(‘test.csv’)

Selecting the required columns

map_data1 = df.iloc[:,0:]
#map_data1.set_index(map_data1[‘Name’], inplace = True)

#spec_data = df.iloc[:,18:]
#spec_data.set_index(map_data1[‘Name’], inplace = True)

#wavelengths = spec_data.columns.tolist()
df_columns = df.columns
print(df_columns)
#wl = [float(i) for i in wavelengths]
#print(wl)
features = map_data1.columns

#objectID = df[‘OBJECTID’].unique()

Bootstrap CSS

app.css.append_css({‘external_url’: ‘https://codepen.io/amyoshino/pen/jzXypZ.css’})

layout_table = dict(
autosize = True,
height = 500,
font = dict(color = ‘#191A1A’),
titlefont = dict(color = ‘#191A1A’, size = ‘14’),
margin = dict(
l = 35,
r = 35,
b = 35,
t = 45
),
hovermode = ‘closest’,
plot_bgcolor = ‘#fffcfc’,
paper_bgcolor = ‘#fffcfc’,
legend = dict(font=dict(size = 10), orientation = ‘h’),
)
layout_table[‘font-size’] = ‘12’
layout_table[‘margin-top’] = ‘20’

layout_map = dict(
autosize = True,
height = 500,
font = dict(color=’#191A1A’),
titlefont = dict(color = ‘#191A1A’, size = ‘20’),
margin = dict(
l=35,
r=35,
b=35,
t=45),
hovermode = ‘closest’,
plot_bgcolor = ‘#fffcfc’,
paper_bgcolor = ‘#fffcfc’,
legend = dict(font = dict(size=10), orientation = ‘h’),
title = ‘Soil Spectral Library Map’,
mapbox = dict(
accesstoken = map_access_token,
style = ‘satellite-streets’, # the color of the map. you can write ‘dark’ also
center = dict(
lon = 35.087,
lat = 31.7056),
zoom = 6,))

functions

def gen_map(map_data1):
return {
‘data’: [{
‘type’: ‘scattermapbox’,
‘lat’: list(df[‘Latitude’]),
‘lon’: list(df[‘Longitude’]),
‘hoverinfo’: ‘text’,
‘hovertext’: [[‘Name: {}
YoelDan: {}
WRB: {}
USDA: {}’.format(i,j,k,m)] # These are the columns names and the break to another line
for i,j,k,m in zip(map_data1[‘Name’], map_data1[‘YoelDan’], map_data1[‘WRB’], map_data1[‘USDA’])],
‘mode’: ‘markers’,
‘name’: list(map_data1[‘Name’]),
‘marker’: {
‘size’: 8,
‘color’: ‘rgb(10, 10, 10)’,
‘opacity’: 0.7}}],
‘layout’: layout_map}

app.layout = html.Div([ #1
html.Div([ #2
html.Div([#3
html.H1(children = ‘Test version’,
style = {‘textAlign’: ‘center’, ‘fontsize’: 24, ‘font-weight’: ‘bold’},
className = ‘nine columns’),
html.Img(
src = ‘’,
className = ‘three columns’,
style = {
‘height’: ‘20%’,
‘width’: ‘20%’,
‘float’: ‘right’,
‘position’: ‘relative’,
‘padding-top’: 12,
‘padding-right’: 12},),
html.Div(children = ‘’’
The test version
‘’’,
className = ‘nine columns’)],
style = {‘textAlign’: ‘center’, ‘fontsize’: 40,‘font-weight’: ‘bold’})
], className = ‘row’),
html.Div([ #2
html.Div([ #3
html.P('Select the geographic regions: ')],
style = {‘font-weight’:‘bold’, ‘textAlign’: ‘left’}),
dcc.Checklist(
id = ‘Zones’,
options = [
{‘label’: ‘Golan’, ‘value’: ‘Golan’},
{‘label’: ‘Galilee’, ‘value’: ‘Galil’},
{‘label’: ‘The Central Mountains’, ‘value’: ‘Central_Mnt’},
{‘label’: ‘The Jordan Valley’, ‘value’: ‘J_Valley’},
{‘label’: ‘The Coastal Region’, ‘value’: ‘Coast’},
{‘label’: ‘The Central/Southern Negev’, ‘value’: ‘Negev’},
{‘label’: ‘The Northern Negev’, ‘value’: ‘N_Negev’}],
values = [‘Golan’,‘Galil’,‘Central_Mnt’,‘J_Valley’,‘Coast’, ‘Negev’, ‘N_Negev’],
labelStyle = {‘display’: ‘inline-block’},
className = ‘eight columns’,
style = {‘font-weight’:‘bold’,‘margin-top’: ‘10’}),
html.Div([ #3
html.P('Select the Soil Type: ',
style = {‘font-weight’:‘bold’,‘margin-top’: ‘10’}),
dcc.Dropdown(
id = ‘type’,
options = [{‘label’: str(item),
‘value’: str(item)}
for item in set(map_data1[‘YoelDan’])],
multi = True,
value = list(set(map_data1[‘YoelDan’])))],
className = ‘six columns’,
style = {‘margin-top’: ‘10’})],
className = ‘row’),
html.Div([ #2
html.Div([ #3
dcc.Graph(id = ‘map-graph’,
animate = True,
style = {‘margin-top’: ‘20’})],
className = ‘six columns’),
html.Div([ #3
dt.DataTable(
rows = map_data1.to_dict(‘records’),
columns = map_data1.columns,
row_selectable = True,
filterable = True,
sortable = True,
selected_row_indices = [],
id = ‘datatable’),],
style = layout_table,
className = ‘six columns’)]),

            html.Div([ #2
                html.Div([ #3
                    dcc.Graph(
                        id = 'bar-graph')],
                        className = 'three columns',
                        style = {'display': 'inline-block'}),

                html.Div( #3
                    #className='container',
                    children=[
                    html.H2('Violin Plots of Soil properties'),
                    html.Hr(),
                    html.Div( #4
                        className='two columns', children=[
                        dcc.RadioItems(
                            id='items',
                            options=[
                                {'label': 'Sand', 'value': 'Sand'},
                                {'label': 'Silt', 'value': 'Silt'},
                                {'label': 'Clay', 'value': 'Clay'},
                                {'label': 'OC', 'value': 'OC'},
                                {'label': 'OM', 'value': 'OM'},
                                {'label': 'CaCO3', 'value': 'CaCO3'},
                            ],
                            value='Sand',
                            style={'display': 'block'}
                        ),
                        html.Hr(),
                        dcc.RadioItems(
                            id='points',
                            options=[
                                {'label': 'Display All Points', 'value': 'all'},
                                {'label': 'Hide Points', 'value': False},
                                {'label': 'Display Outliers', 'value': 'outliers'},
                                {'label': 'Display Suspected Outliers', 'value': 'suspectedoutliers'},
                            ],
                            value='all',
                            style={'display': 'block'}
                        ),
                        html.Hr(),
                        html.Label('Jitter'),
                        dcc.Slider(
                            id='jitter',
                            min=0,
                            max=1,
                            step=0.1,
                            value=0.5,
                            updatemode='drag'
                        )
                    ]),
                    html.Div( #4
                        dcc.Graph(id='graph'), className='six columns')
                ])]),

            html.Div([ #2
                html.Div([ #3
                    dcc.Dropdown(
                         id='yaxis',
                         options=[{'label': i.title(), 'value': i} for i in features],
                         value='Clay')],
                         style={'width': '15%','margin-top': '30', 'margin-left': '200', 'display': 'inline-block'}),
                html.Div([ #3
                    dcc.Dropdown(
                         id='xaxis',
                         options=[{'label': i.title(), 'value': i} for i in features],
                         value='Sand')],
                         style={'width': '15%', 'margin-top': '30', 'margin-right': '200','float': 'right', 'display': 'inline-block'}),
                dcc.Graph(
                    id='feature-graphic')],
                    className='six columns',
                    style={'width': '49%', 'display': 'inline-block','padding':20}),

                html.Div([ #2
                    html.Div([ #3
                        dcc.Graph(id = 'vnir-spectrum')])],
                            className = 'container',
                            style = {'display': 'inline-block', 'width': '49%'}),

            html.Div([ #2
                    html.P('Developed by Yaron Ogen - ', style = {'display': 'inline'}),
                    html.A('yaronogen@gmail.com', href = 'mailto:yaronogen@gmail.com')],
                    className = 'twelve columns',
                    style = {'fontsize': 20, 'font-weight':'bold', 'padding-top': 20})

                    ])

@app.callback(
Output(‘datatable’, ‘rows’),
[Input(‘type’, ‘value’),
Input(‘Zones’, ‘values’)])
def update_selected_row_indices(YoelDan, Zone):
map_aux = map_data1.copy()

type filter

map_aux = map_aux[map_aux['YoelDan'].isin(YoelDan)]

Borough filter

map_aux = map_aux[map_aux['Zone'].isin(Zone)]

rows = map_aux.to_dict('records')
return rows

@app.callback(
Output(‘map-graph’, ‘figure’),
[Input(‘datatable’, ‘rows’),
Input(‘datatable’, ‘selected_row_indices’)])
def map_selection(rows, selected_row_indices):
aux = pd.DataFrame(rows)
temp_df = aux.ix[selected_row_indices, :]
if len(selected_row_indices) ==0:
return gen_map(aux)
return gen_map(temp_df)

@app.callback(
Output(‘bar-graph’, ‘figure’),
[Input(‘datatable’, ‘rows’),
Input(‘datatable’, ‘selected_row_indices’)])
def update_figure(rows, selected_row_indices):
dff = pd.DataFrame(rows)

layout = go.Layout(
    bargap = 0.05,
    bargroupgap = 0,
    barmode = 'group',
    showlegend = False,
    dragmode = 'select',
    xaxis = dict(
        showgrid = False,
        nticks = 50,
        fixedrange = False),
    yaxis = dict(
        showticklabels = True,
        showgrid = False,
        fixedrange = False,
        rangemode = 'nonnegative',
        zeroline = False,
        ))
data = Data([
    go.Bar(
        x = dff.groupby('Zone', as_index = False).count()['Zone'],
        y = dff.groupby('Zone', as_index = False).count()['YoelDan']
        )])
return go.Figure(data=data, layout=layout)

@app.callback(
Output(‘graph’, ‘figure’), [
Input(‘items’, ‘value’),
Input(‘points’, ‘value’),
Input(‘jitter’, ‘value’)])
def update_graph(value, points, jitter):
return {
‘data’: [
{
‘type’: ‘violin’,
‘x’: map_data1[‘Zone’],
‘y’: map_data1[value],
‘text’: [‘Sample {}’.format(i) for i in range(len(map_data1))],
‘points’: points,
‘jitter’: jitter
}
],
‘layout’: {
‘margin’: {‘l’: 30, ‘r’: 10, ‘b’: 30, ‘t’: 0}
}
}

@app.callback(
Output(‘feature-graphic’, ‘figure’),
[Input(‘xaxis’, ‘value’),
Input(‘yaxis’, ‘value’)])
def update_graph(xaxis_name, yaxis_name):
return {
‘data’: [go.Scatter(
x=map_data1[map_data1[‘Zone’] == i][xaxis_name],
y=map_data1[map_data1[‘Zone’] == i][yaxis_name],
text=map_data1[map_data1[‘Zone’] == i][‘Name’],
mode=‘markers’,
marker={
‘size’: 12,
#‘color’: ‘black’,
‘opacity’: 0.6,
‘line’: {‘width’: 0.7, ‘color’: ‘white’}},
name = i)
for i in df.Zone.unique()],
‘layout’: go.Layout(
title=‘Correlation between two variables’,
xaxis={‘title’: xaxis_name.title()},
yaxis={‘title’: yaxis_name.title()},
margin={‘l’: 100, ‘b’: 100, ‘t’: 100, ‘r’: 100},
hovermode=‘closest’)}

@app.callback(
Output(‘vnir-spectrum’, ‘figure’),
[Input(‘datatable’, ‘rows’),
Input(‘datatable’, ‘selected_row_indices’)])
def update_figure(rows, selected_row_indices):
dff = pd.DataFrame(rows)
fig = plotly.tools.make_subplots(
rows = 3, cols = 1,
subplot_titles = (‘VNIR-SWIR Spectrum’, ‘LWIR Spectrum’, ‘Sentinel-2 Spectrum’),
shared_xaxes = True)
marker = {‘color’: [’#0074D9’]*len(dff)}
for i in (selected_row_indices or []):
marker[‘color’][i] = ‘#FF851B
fig.append_trace({
‘x’: dff[wl],
‘y’: dff[spec_data],
‘type’: ‘line’,
‘marker’: marker}, 1,1)
fig.append_trace({
‘x’: dff[wl],
‘y’: dff[spec_data],
‘type’: ‘line’,
‘marker’: marker}, 2,1)
fig.append_trace({
‘x’: dff[wl],
‘y’: dff[spec_data],
‘type’: ‘line’,
‘marker’: marker}, 3,1)
fig[‘layout’][‘showlegend’] = False
fig[‘layout’][‘height’] = 800
fig[‘layout’][‘margin’] = {
‘l’: 40,
‘r’: 10,
‘t’: 60,
‘b’: 200
}
fig[‘layout’][‘yaxis3’][‘type’] = ‘log’
return fig

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

File