diff --git a/app_layout_function.py b/app_layout_function.py index 110def0..cf5060e 100644 --- a/app_layout_function.py +++ b/app_layout_function.py @@ -8,6 +8,7 @@ def serve_layout(): return html.Div('hlo world') app.layout = serve_layout +app.server.secret_key='secret' if __name__ == '__main__': app.run_server(debug=False) diff --git a/colum-count.gif b/colum-count.gif new file mode 100644 index 0000000..dfcd29c Binary files /dev/null and b/colum-count.gif differ diff --git a/component-library.py b/component-library.py new file mode 100644 index 0000000..475b7fb --- /dev/null +++ b/component-library.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +import dash +from dash.dependencies import Input, Output +import dash_html_components as html +import dash_core_components as dcc +import json + +app = dash.Dash() + +def layout(id): + return html.Div([ + html.Label('Dropdown'), + dcc.Dropdown( + options=[ + {'label': 'New York City', 'value': 'NYC'}, + {'label': u'Montréal', 'value': 'MTL'}, + {'label': 'San Francisco', 'value': 'SF'} + ], + value='MTL', + id='{}-dropdown'.format(id) + ), + + html.Label('Multi-Select Dropdown'), + dcc.Dropdown( + options=[ + {'label': 'New York City', 'value': 'NYC'}, + {'label': u'Montréal', 'value': 'MTL'}, + {'label': 'San Francisco', 'value': 'SF'} + ], + value=['MTL', 'SF'], + multi=True, + id='{}-multi-dropdown'.format(id) + ), + + html.Label('Radio Items'), + dcc.RadioItems( + options=[ + {'label': 'New York City', 'value': 'NYC'}, + {'label': u'Montréal', 'value': 'MTL'}, + {'label': 'San Francisco', 'value': 'SF'} + ], + value='MTL', + id='{}-radio-items'.format(id) + ), + + html.Label('Checkboxes'), + dcc.Checklist( + options=[ + {'label': 'New York City', 'value': 'NYC'}, + {'label': u'Montréal', 'value': 'MTL'}, + {'label': 'San Francisco', 'value': 'SF'} + ], + values=['MTL', 'SF'], + id='{}-checkboxes'.format(id) + ), + + html.Label('Text Input'), + dcc.Input( + value='MTL', + type='text', + id='{}-input'.format(id) + ), + + html.Label('Slider'), + dcc.Slider( + min=0, + max=9, + marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, + value=5, + id='{}-slider'.format(id) + ), + + html.Label('Range Slider'), + dcc.RangeSlider( + min=0, + max=9, + marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, + value=[5, 8], + id='{}-range-slider'.format(id) + ), + + html.Label('Slider on Drag'), + dcc.Slider( + min=0, + max=9, + marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, + value=5, + updatemode='drag', + id='{}-slider-drag'.format(id) + ), + + html.Label('Range Slider'), + dcc.RangeSlider( + min=0, + max=9, + marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)}, + value=[5, 8], + updatemode='drag', + id='{}-range-slider-drag'.format(id) + ) + + ]) + + +app.scripts.config.serve_locally = True + +app.layout = html.Div([ + html.H3('Uncontrolled Components'), + layout('xx'), + html.Hr(), + html.H3('Controlled Components'), + layout('controlled'), + html.Div(id='output-value') +]) + +INPUTS = [ + Input(id_, 'value') for id_ in app.layout.keys() + if 'controlled' in id_ and 'checkboxes' not in id_] +INPUTS.append(Input('controlled-checkboxes', 'values')) + + +@app.callback( + Output('output-value', 'children'), + INPUTS) +def display_values(*args): + return json.dumps(args) + + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/config_bar.py b/config_bar.py new file mode 100644 index 0000000..0dcd4eb --- /dev/null +++ b/config_bar.py @@ -0,0 +1,12 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html + +app = dash.Dash() + +app.layout = html.Div([ + dcc.Graph(id='my-graph', figure={'data': [{'x': [1, 2, 3]}]}, config={'editable': True, 'modeBarButtonsToRemove': ['pan2d', 'lasso2d']}) +]) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/copy-figure.py b/copy-figure.py new file mode 100644 index 0000000..ebc90bd --- /dev/null +++ b/copy-figure.py @@ -0,0 +1,36 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html +import copy + +app = dash.Dash() + +FIGURE = { + 'data': [ + {'x': [1, 2, 3], 'y': [4, 2, 1], 'type': 'bar'} + ] +} + +app.layout = html.Div([ + dcc.Dropdown( + id='color', + options=[ + {'label': i, 'value': i} for i in ['blue', 'red', 'black'] + ], + value='blue' + ), + dcc.Graph(id='graph', figure=FIGURE) +]) + + +@app.callback( + dash.dependencies.Output('graph', 'figure'), + [dash.dependencies.Input('color', 'value')]) +def update_graph(color): + copied_figure = copy.deepcopy(FIGURE) + copied_figure['data'][0]['marker'] = {'color': color} + return copied_figure + + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash-click.gif b/dash-click.gif new file mode 100644 index 0000000..a664478 Binary files /dev/null and b/dash-click.gif differ diff --git a/dash-click.py b/dash-click.py new file mode 100644 index 0000000..119cdb7 --- /dev/null +++ b/dash-click.py @@ -0,0 +1,50 @@ +import dash +from dash.dependencies import Input, Output, State +import dash_html_components as html +import dash_core_components as dcc + +app = dash.Dash() + +app.layout = html.Div([ + html.Button('Click Me', id='button'), + html.H3(id='button-clicks'), + + html.Hr(), + + html.Label('Input 1'), + dcc.Input(id='input-1'), + + html.Label('Input 2'), + dcc.Input(id='input-2'), + + html.Label('Slider 1'), + dcc.Slider(id='slider-1'), + + html.Button('Click Me', id='button-2'), + + html.Div(id='output') +], className='container') + +@app.callback( + Output('button-clicks', 'children'), + [Input('button', 'n_clicks')]) +def clicks(n_clicks): + return 'Button has been clicked {} times'.format(n_clicks) + +@app.callback( + Output('output', 'children'), + [Input('button-2', 'n_clicks')], + state=[State('input-1', 'value'), + State('input-2', 'value'), + State('slider-1', 'value')]) +def compute(n_clicks, input1, input2, slider1): + return 'A computation based off of {}, {}, and {}'.format( + input1, input2, slider1 + ) + + +app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) + + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash-modebar.py b/dash-modebar.py new file mode 100644 index 0000000..512c5bf --- /dev/null +++ b/dash-modebar.py @@ -0,0 +1,31 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html + +app = dash.Dash() +app.layout = html.Div([ + dcc.Graph( + id='my-graph', + figure={ + 'data': [{'x': [1, 2, 3]}] + }, + config={ + 'modeBarButtonsToRemove': [ + 'sendDataToCloud', + 'pan2d', + 'zoomIn2d', + 'zoomOut2d', + 'autoScale2d', + 'resetScale2d', + 'hoverCompareCartesian', + 'hoverClosestCartesian', + 'toggleSpikelines' + ], + 'displayModeBar': True, + 'displaylogo': False + } + ) +]) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash-urls-hide-show-tabs.gif b/dash-urls-hide-show-tabs.gif new file mode 100644 index 0000000..ad1b759 Binary files /dev/null and b/dash-urls-hide-show-tabs.gif differ diff --git a/dash-urls-hide-show-tabs.py b/dash-urls-hide-show-tabs.py new file mode 100644 index 0000000..438010e --- /dev/null +++ b/dash-urls-hide-show-tabs.py @@ -0,0 +1,117 @@ +import dash +from dash.dependencies import Input, Output +import dash_core_components as dcc +import dash_html_components as html + + +app = dash.Dash() + + +tab_style = { + 'color': '#0074D9', + 'text-decoration': 'underline', + 'margin': 30, + 'cursor': 'pointer' +} + +app.layout = html.Div([ + dcc.Location(id='url'), + dcc.Link('Tab 1', href='/', style=tab_style), + dcc.Link('Tab 2', href='/tab-2', style=tab_style), + dcc.Link('Tab 3', href='/tab-3', style=tab_style), + html.Div([ + + # Tab 1 + html.Div( + id='tab-1', + style={'display': 'none'}, + children=[ + html.H1('Tab 1'), + dcc.Dropdown( + id='dropdown-1', + options=[ + {'label': 'Tab 1: {}'.format(i), 'value': i} + for i in ['A', 'B', 'C'] + ] + ), + html.Div(id='display-1') + ] + ), + + # Tab 2 + html.Div( + id='tab-2', + style={'display': 'none'}, + children=[ + html.H1('Tab 2'), + dcc.Dropdown( + id='dropdown-2', + options=[ + {'label': 'Tab 2: {}'.format(i), 'value': i} + for i in ['A', 'B', 'C'] + ] + ), + html.Div(id='display-2') + ] + ), + + # Tab 3 + html.Div( + id='tab-3', + style={'display': 'none'}, + children=[ + html.H1('Tab 3'), + dcc.Dropdown( + id='dropdown-3', + options=[ + {'label': 'Tab 3: {}'.format(i), 'value': i} + for i in ['A', 'B', 'C'] + ] + ), + html.Div(id='display-3') + ] + ), + ]) +]) + + +def generate_display_tab(tab): + def display_tab(pathname): + if tab == 'tab-1' and (pathname is None or pathname == '/'): + return {'display': 'block'} + elif pathname == '/{}'.format(tab): + return {'display': 'block'} + else: + return {'display': 'none'} + return display_tab + + +for tab in ['tab-1', 'tab-2', 'tab-3']: + app.callback(Output(tab, 'style'), [Input('url', 'pathname')])( + generate_display_tab(tab) + ) + + +@app.callback( + Output('display-1', 'children'), + [Input('dropdown-1', 'value')]) +def display_value(value): + return 'You have selected {}'.format(value) + + +@app.callback( + Output('display-2', 'children'), + [Input('dropdown-2', 'value')]) +def display_value(value): + return 'You have selected {}'.format(value) + + +@app.callback( + Output('display-3', 'children'), + [Input('dropdown-3', 'value')]) +def display_value(value): + return 'You have selected {}'.format(value) + + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash_app.png b/dash_app.png new file mode 100644 index 0000000..e058e3e Binary files /dev/null and b/dash_app.png differ diff --git a/dash_b64_image.py b/dash_b64_image.py new file mode 100644 index 0000000..4773b9b --- /dev/null +++ b/dash_b64_image.py @@ -0,0 +1,14 @@ +import dash +import dash_html_components as html +import base64 + +app = dash.Dash() + +encoded_image = base64.b64encode(open('dash_app.png', 'rb').read()) + +app.layout = html.Div([ + html.Img(src='data:image/png;base64,{}'.format(encoded_image)) +]) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash_css.py b/dash_css.py new file mode 100644 index 0000000..6175280 --- /dev/null +++ b/dash_css.py @@ -0,0 +1,35 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html + +import flask +import os + +app = dash.Dash() + +app.layout = html.Div('Hello World') + +# Add a static image route that serves images from desktop +# Be *very* careful here - you don't want to serve arbitrary files +# from your computer or server +css_directory = os.getcwd() +stylesheets = ['stylesheet.css'] +static_css_route = '/static/' + + +@app.server.route('{}'.format(static_css_route)) +def serve_stylesheet(stylesheet): + if stylesheet not in stylesheets: + raise Exception( + '"{}" is excluded from the allowed static files'.format( + stylesheet + ) + ) + return flask.send_from_directory(css_directory, stylesheet) + + +for stylesheet in stylesheets: + app.css.append_css({"external_url": "/static/{}".format(stylesheet)}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash_download_link.py b/dash_download_link.py new file mode 100644 index 0000000..8a065cb --- /dev/null +++ b/dash_download_link.py @@ -0,0 +1,75 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html +import pandas as pd +import urllib + +df = pd.DataFrame({ + 'a': [1, 2, 3, 4], + 'b': [2, 1, 5, 6], + 'c': ['x', 'x', 'y', 'y'] +}) + + +def generate_table(dataframe, max_rows=10): + return html.Table( + # Header + [html.Tr([html.Th(col) for col in dataframe.columns])] + + + # Body + [html.Tr([ + html.Td(dataframe.iloc[i][col]) for col in dataframe.columns + ]) for i in range(min(len(dataframe), max_rows))] + ) + + +app = dash.Dash(__name__) +app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) +app.layout = html.Div([ + html.Label('Filter'), + + dcc.Dropdown( + id='field-dropdown', + options=[ + {'label': i, 'value': i} for i in + (['all'] + list(df['c'].unique()))], + value='all' + ), + html.Div(id='table'), + html.A( + 'Download Data', + id='download-link', + download="rawdata.csv", + href="", + target="_blank" + ) +]) + + +def filter_data(value): + if value == 'all': + return df + else: + return df[df['c'] == value] + + +@app.callback( + dash.dependencies.Output('table', 'children'), + [dash.dependencies.Input('field-dropdown', 'value')]) +def update_table(filter_value): + dff = filter_data(filter_value) + return generate_table(dff) + + +@app.callback( + dash.dependencies.Output('download-link', 'href'), + [dash.dependencies.Input('field-dropdown', 'value')]) +def update_download_link(filter_value): + dff = filter_data(filter_value) + csv_string = dff.to_csv(index=False, encoding='utf-8') + csv_string = "data:text/csv;charset=utf-8," + urllib.quote(csv_string) + return csv_string + + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash_dropdown_x.py b/dash_dropdown_x.py new file mode 100644 index 0000000..04364a6 --- /dev/null +++ b/dash_dropdown_x.py @@ -0,0 +1,33 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html + +from dash.dependencies import Input, Output + +app = dash.Dash() +app.layout = html.Div([ + html.H1(children='Dropdown test'), + dcc.Dropdown( + id='test-selector', + placeholder='Select a value', + options=[{'label':'foo', 'value':0},{'label':'bar', 'value':1},{'label':'baz', 'value':2}], + multi=True + ), + html.Div( + id='foobar' + ) + +]) + +@app.callback( + Output(component_id='foobar', component_property='children'), + [Input(component_id='test-selector', component_property='value')] +) +def test_interaction(value): + print(value) + return value + +app.scripts.config.serve_locally = True + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash_multiple_sliders.py b/dash_multiple_sliders.py new file mode 100644 index 0000000..c15cef6 --- /dev/null +++ b/dash_multiple_sliders.py @@ -0,0 +1,36 @@ +import dash +from dash.dependencies import Input, Output +import dash_html_components as html +import dash_core_components as dcc + +app = dash.Dash() + +app.config.supress_callback_exceptions = True + +app.layout = html.Div([ + html.Button('Add a slider', id='button', n_clicks=0), + html.Div(id='slider-container'), + + # this is a hack: include a hidden dcc component so that + # dash registers and serve's this component's JS and CSS + # libraries + dcc.Input(style={'display': 'none'}) +]) + +@app.callback(Output('slider-container', 'children'), [Input('button', 'n_clicks')]) +def add_sliders(n_clicks): + return html.Div( + [html.Div([ + html.Div(dcc.Slider(id='slider-{}'.format(i))), + html.Div(id='output-{}'.format(i), style={'marginTop': 30}) + ]) for i in range(n_clicks)] + ) + +# up to 10 sliders +for i in range(10): + @app.callback(Output('slider-{}'.format(i), 'children'), [Input('slider-{}'.format(i), 'value')]) + def update_output(slider_i_value): + return slider_i_value + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dash_script.py b/dash_script.py new file mode 100644 index 0000000..fb6c20e --- /dev/null +++ b/dash_script.py @@ -0,0 +1,11 @@ +import dash +import dash_html_components as html + +app = dash.Dash() + +app.layout = html.Div([ + html.Script('alert(1);', type='text/javascript') +]) + +if __name__ == '__main__': + app.run_server() diff --git a/dash_sqlite.py b/dash_sqlite.py new file mode 100644 index 0000000..79e82a6 --- /dev/null +++ b/dash_sqlite.py @@ -0,0 +1,52 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html +import pandas as pd + +from sqlalchemy import create_engine + +# Create a simple database +engine = create_engine('sqlite:///sample.db') +df = pd.DataFrame({ + 'a': [1, 2, 3, 4, 5, 6], + 'b': ['x', 'y', 'x', 'x', 'z', 'y'] +}) +df.to_sql('dataframe', engine, if_exists='replace') + +# Dash +def generate_table(dataframe, max_rows=10): + return html.Table( + # Header + [html.Tr([html.Th(col) for col in dataframe.columns])] + + + # Body + [html.Tr([ + html.Td(dataframe.iloc[i][col]) for col in dataframe.columns + ]) for i in range(min(len(dataframe), max_rows))] + ) + + +app = dash.Dash() +app.layout = html.Div([ + dcc.Dropdown( + id='dropdown', + options=[{'label': i, 'value': i} for i in df.b.unique()], + value='x', + clearable=False + ), + html.Div(id='table-container') +]) + + +@app.callback( + dash.dependencies.Output('table-container', 'children'), + [dash.dependencies.Input('dropdown', 'value')]) +def sql(value): + dff = pd.read_sql_query( + 'SELECT a, b FROM dataframe WHERE b = "{}"'.format(value), + engine + ) + return generate_table(dff) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dates.py b/dates.py new file mode 100644 index 0000000..63a62b2 --- /dev/null +++ b/dates.py @@ -0,0 +1,26 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html +from datetime import datetime as dt + +app = dash.Dash() +app.layout = html.Div([ + dcc.DatePickerSingle( + id='date-picker-single', + date=dt(1997, 5, 10) + ), + html.Div(id='output') +]) + +app.scripts.config.serve_locally=True +app.css.config.serve_locally=True + +@app.callback( + dash.dependencies.Output('output', 'children'), + [dash.dependencies.Input('date-picker-single', 'date')]) +def display_date(date): + print(date) + return 'You have selected {}'.format(date) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/dependency_tree.py b/dependency_tree.py new file mode 100644 index 0000000..2958072 --- /dev/null +++ b/dependency_tree.py @@ -0,0 +1,46 @@ +import numpy as np +import dash +from dash.dependencies import Input, Output +from plotly.graph_objs import * +import dash_core_components as dcc +import dash_html_components as html + +app = dash.Dash() +# function to plot +def func(x): + return x[:,0]**2 + np.sin(x[:,1]) +# default ranges for x0 & x1 +xranges = [[0,1], [-np.pi, np.pi]] +# dropdown to pick which x to plot against +xchooser = dcc.Dropdown( + id='xchooser', + options=[{'label':'x0', 'value':'0'},{'label':'x1', 'value':'1'}], + value='0') +# the user can also modify the ranges manually +minsetter = dcc.Input(id='minsetter', type='number', value=xranges[0][0]) +maxsetter = dcc.Input(id='maxsetter', type='number', value=xranges[0][1]) + +app.layout = html.Div([ + html.Div(xchooser, style={'width':'15%'}), + html.Div(['Min: ',minsetter,'Max: ',maxsetter]), + html.Div([dcc.Graph(id='trend_plot')], style={'width':'80%','float':'right'}) + ]) + +@app.callback(Output('minsetter','value'),[Input('xchooser','value')]) +def set_min(xindex): + return xranges[int(xindex)][0] +@app.callback(Output('maxsetter','value'),[Input('xchooser','value')]) +def set_max(xindex): + return xranges[int(xindex)][1] +@app.callback(Output('trend_plot','figure'), + [Input('xchooser','value'),Input('minsetter','value'),Input('maxsetter','value')]) +def make_graph(xindex, xmin, xmax): + npt = 20 + xgrid = np.zeros((npt,2)) + xgrid[:,int(xindex)] = np.linspace(int(xmin), int(xmax), npt) + print 'Calling func!' + f = func(xgrid) + return Figure(data=[Scatter(x=xgrid[:,int(xindex)], y=f, mode='markers+lines')]) + +if __name__ == '__main__': + app.run_server() diff --git a/download-link.gif b/download-link.gif new file mode 100644 index 0000000..16dc497 Binary files /dev/null and b/download-link.gif differ diff --git a/dropdown_1000.gif b/dropdown_1000.gif new file mode 100644 index 0000000..7fd63c0 Binary files /dev/null and b/dropdown_1000.gif differ diff --git a/dropdown_1000.py b/dropdown_1000.py new file mode 100644 index 0000000..78e03b2 --- /dev/null +++ b/dropdown_1000.py @@ -0,0 +1,11 @@ +import dash +import dash_html_components as html +import dash_core_components as dcc + +app = dash.Dash() +app.layout = html.Div([ + dcc.Dropdown(options=[{'label': 'Option ' + str(i), 'value': i} for i in range(100 * 1000)], multi=True) +]) + +if __name__ == '__main__': + app.run_server(debug=True, port=8060) diff --git a/graph_column_count.py b/graph_column_count.py new file mode 100644 index 0000000..6a97d9e --- /dev/null +++ b/graph_column_count.py @@ -0,0 +1,11 @@ +import dash, dash_core_components as dcc, dash_html_components as html +import plotly.graph_objs as go + +app = dash.Dash() +app.layout = html.Div([ + dcc.Graph(id='a', figure=dict(data = [go.Scatter( x = [1,2], y = [3,4] )])), + dcc.Graph(id='b', figure=dict(data = [go.Scatter( x = [1,2], y = [3,4] )])), + ], style={'columnCount': 2}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/multi-column-grid.py b/multi-column-grid.py new file mode 100644 index 0000000..504255b --- /dev/null +++ b/multi-column-grid.py @@ -0,0 +1,25 @@ +import dash +import dash_html_components as html +import dash_core_components as dcc + +app = dash.Dash() +app.layout = html.Div([ + html.Div([ + html.Div([ + html.H3('Column 1'), + dcc.Graph(id='g1', figure={'data': [{'y': [1, 2, 3]}]}) + ], className="six columns"), + + html.Div([ + html.H3('Column 2'), + dcc.Graph(id='g2', figure={'data': [{'y': [1, 2, 3]}]}) + ], className="six columns"), + ], className="row") +]) + +app.css.append_css({ + 'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css' +}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/multi-page-dropdown-example.gif b/multi-page-dropdown-example.gif new file mode 100644 index 0000000..d2c31b5 Binary files /dev/null and b/multi-page-dropdown-example.gif differ diff --git a/multi-page-dropdown.gif b/multi-page-dropdown.gif new file mode 100644 index 0000000..3604484 Binary files /dev/null and b/multi-page-dropdown.gif differ diff --git a/multi-page-dropdown.py b/multi-page-dropdown.py new file mode 100644 index 0000000..ac78dfb --- /dev/null +++ b/multi-page-dropdown.py @@ -0,0 +1,109 @@ +import dash +from dash.dependencies import Input, State, Output +import dash_html_components as html +import dash_core_components as dcc +import pandas as pd + +df = pd.DataFrame({ + 'x': [1, 2, 3, 1, 2, 3, 1, 2, 3], + 'y': [3, 2, 4, 1, 4, 5, 4, 3, 1], + 'group-1': ['/', '/exhibit-b', '/exhibit-c', '/', '/exhibit-b', '/exhibit-c', '/', '/exhibit-b', '/exhibit-c'], + 'group-2': ['LA', 'LA', 'LA', 'London', 'London', 'London', 'Montreal', 'Montreal', 'Montreal'], +}) + +app = dash.Dash() +app.scripts.config.serve_locally=True + +app.config.supress_callback_exceptions = True + +app.layout = html.Div([ + # This "header" will persist across pages + html.H2('Multi Page Dash App'), + + + # Each "page" will modify this element + html.Div(id='content-container-part-1'), + + + dcc.Dropdown( + id='graph-control', + options=[{'label': i, 'value': i} for i in df['group-2'].unique()], + value='LA' + ), + + # Each "page" will modify this element + html.Div(id='content-container-part-2'), + + # This Location component represents the URL bar + dcc.Location(id='url', refresh=False) +], className="container") + +link_mapping = { + '/': 'Exhibit A', + '/exhibit-b': 'Exhibit B', + '/exhibit-c': 'Exhibit C', +} + +styles = { + 'link': {'padding': '20'} +} + +@app.callback( + Output('content-container-part-1', 'children'), + [Input('url', 'pathname')]) +def display_page(pathname): + return html.Div([ + html.Div([ + html.Span( + dcc.Link(link_mapping['/'], href="/") if pathname != '/' else 'Exhibit A', + style=styles['link'] + ), + + html.Span( + dcc.Link(link_mapping['/exhibit-b'], href="/exhibit-b") if pathname != '/exhibit-b' else 'Exhibit B', + style=styles['link'] + ), + + html.Span( + dcc.Link(link_mapping['/exhibit-c'], href="/exhibit-c") if pathname != '/exhibit-c' else 'Exhibit C', + style=styles['link'] + ) + + ]), + + dcc.Markdown('### {}'.format(link_mapping[pathname])), + ]) + + +@app.callback( + Output('content-container-part-2', 'children'), + [Input('url', 'pathname')]) +def display_page(*args): + return html.Div([ + dcc.Graph( + id='graph', + ) + ]) + + +@app.callback( + Output('graph', 'figure'), + [Input('graph-control', 'value'), + Input('url', 'pathname')]) +def update_graph(value, pathname): + dff = df[(df['group-1'] == pathname) & (df['group-2'] == value)] + return { + 'data': [{ + 'x': dff.x, + 'y': dff.y, + 'type': 'bar' + }], + 'layout': { + 'title': '{} in {}'.format(value, link_mapping[pathname]) + } + } + +app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/multiple-workers.gif b/multiple-workers.gif new file mode 100644 index 0000000..a0739d4 Binary files /dev/null and b/multiple-workers.gif differ diff --git a/multiple_workers.py b/multiple_workers.py new file mode 100644 index 0000000..0e233e1 --- /dev/null +++ b/multiple_workers.py @@ -0,0 +1,20 @@ +import dash +import dash_html_components as html +import dash_core_components as dcc + +app = dash.Dash(__name__) + +app.layout = html.Div([ + dcc.Input(id='input', value='initial value'), + html.Div(id='output') +]) + +@app.callback( + dash.dependencies.Output('output', 'children'), + [dash.dependencies.Input('input', 'value')]) +def update_output(value): + print(value) + return value + +server = app.server +server.secret_key = 'secret' diff --git a/oosage.py b/oosage.py new file mode 100644 index 0000000..15e18f9 --- /dev/null +++ b/oosage.py @@ -0,0 +1,48 @@ +import dash +import dash_auth +import dash_html_components as html +import dash_core_components as dcc +import plotly + + +app = dash.Dash('auth') +auth = dash_auth.PlotlyAuth( + app, + 'Dash Authentication Sample App', + 'private', + 'http://localhost:8050' +) + +app.layout = html.Div([ + html.H1('Welcome to the app'), + html.H3('You are successfully authorized'), + dcc.Dropdown( + id='dropdown', + options=[{'label': i, 'value': i} for i in ['A', 'B']], + value='A' + ), + dcc.Graph(id='graph') +], className="container") + +@app.callback( + dash.dependencies.Output('graph', 'figure'), + [dash.dependencies.Input('dropdown', 'value')]) +def update_graph(dropdown_value): + return { + 'layout': { + 'title': 'Graph of {}'.format(dropdown_value), + 'margin': { + 'l': 20, + 'b': 20, + 'r': 10, + 't': 60 + } + }, + 'data': [{'x': [1, 2, 3], 'y': [4, 1, 2]}] + } + + +app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/sample.db b/sample.db new file mode 100644 index 0000000..61011e1 Binary files /dev/null and b/sample.db differ diff --git a/sql_dash_dropdown.py b/sql_dash_dropdown.py new file mode 100644 index 0000000..b336dc3 --- /dev/null +++ b/sql_dash_dropdown.py @@ -0,0 +1,140 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html +import pandas as pd + +from sqlalchemy import create_engine + +ENGINE = create_engine('sqlite:///sample.db') + +# Create a simple database +def create_sample_database(): + + df = pd.DataFrame({ + 'column_a': [1, 2, 3, 4, 5, 6], + 'column_b': [6, 5, 4, 3, 2, 1], + 'column_c': ['a', 'b', 'c', 'a', 'a', 'b'] + }) + df.to_sql('dataframe', ENGINE, if_exists='replace') + + +create_sample_database() + + +# Dash +def generate_table(dataframe, max_rows=10): + return html.Table( + # Header + [html.Tr([html.Th(col) for col in dataframe.columns])] + + + # Body + [html.Tr([ + html.Td(dataframe.iloc[i][col]) for col in dataframe.columns + ]) for i in range(min(len(dataframe), max_rows))] + ) + +app = dash.Dash() +app.layout = html.Div([ + dcc.Input( + id='sql-query', + value='SELECT * FROM dataframe', + style={'width': '100%'}, + type='text' + ), + html.Button('Run Query', id='run-query'), + + html.Hr(), + + html.Div([ + html.Div(id='table-container', className="four columns"), + + html.Div([ + html.Div([ + html.Div([ + html.Label('Select X'), + dcc.Dropdown( + id='dropdown-x', + clearable=False, + ) + ], className="six columns"), + html.Div([ + html.Label('Select Y'), + dcc.Dropdown( + id='dropdown-y', + clearable=False, + ) + ], className="six columns") + ], className="row"), + html.Div(dcc.Graph(id='graph'), className="ten columns") + ], className="eight columns") + ], className="row"), + + # hidden store element + html.Div(id='table-store', style={'display': 'none'}) +]) + + +@app.callback( + dash.dependencies.Output('table-store', 'children'), + [dash.dependencies.Input('run-query', 'n_clicks')], + state=[dash.dependencies.State('sql-query', 'value')]) +def sql(number_of_times_button_has_been_clicked, sql_query): + dff = pd.read_sql_query( + sql_query, + ENGINE + ) + return dff.to_json() + + +@app.callback( + dash.dependencies.Output('table-container', 'children'), + [dash.dependencies.Input('table-store', 'children')]) +def dff_to_table(dff_json): + dff = pd.read_json(dff_json) + return generate_table(dff) + + +@app.callback( + dash.dependencies.Output('graph', 'figure'), + [dash.dependencies.Input('table-store', 'children'), + dash.dependencies.Input('dropdown-x', 'value'), + dash.dependencies.Input('dropdown-y', 'value')]) +def dff_to_table(dff_json, dropdown_x, dropdown_y): + dff = pd.read_json(dff_json) + return { + 'data': [{ + 'x': dff[dropdown_x], + 'y': dff[dropdown_y], + 'type': 'bar' + }], + 'layout': { + 'margin': { + 'l': 20, + 'r': 10, + 'b': 60, + 't': 10 + } + } + } + + +@app.callback( + dash.dependencies.Output('dropdown-x', 'options'), + [dash.dependencies.Input('table-store', 'children')]) +def create_options_x(dff_json): + dff = pd.read_json(dff_json) + return [{'label': i, 'value': i} for i in dff.columns] + + +@app.callback( + dash.dependencies.Output('dropdown-y', 'options'), + [dash.dependencies.Input('table-store', 'children')]) +def create_options_y(dff_json): + dff = pd.read_json(dff_json) + return [{'label': i, 'value': i} for i in dff.columns] + + +app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/sqlite-editor.gif b/sqlite-editor.gif new file mode 100644 index 0000000..5efdb92 Binary files /dev/null and b/sqlite-editor.gif differ diff --git a/sqlite-editor.png b/sqlite-editor.png new file mode 100644 index 0000000..fd76eb3 Binary files /dev/null and b/sqlite-editor.png differ diff --git a/sqlite.gif b/sqlite.gif new file mode 100644 index 0000000..7d39394 Binary files /dev/null and b/sqlite.gif differ diff --git a/stylesheet.css b/stylesheet.css new file mode 100644 index 0000000..ca30b64 --- /dev/null +++ b/stylesheet.css @@ -0,0 +1,3 @@ +body { + font-size: 20px; +} diff --git a/table_experiments.py b/table_experiments.py new file mode 100644 index 0000000..f2652c8 --- /dev/null +++ b/table_experiments.py @@ -0,0 +1,53 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html +import dash_table_experiments as dt +import pandas as pd + +app = dash.Dash() + +app.scripts.config.serve_locally=True + +df_simple = pd.DataFrame({ + 'Column 1': [1, 2, 3], + 'Column 2': [1, 19, 10] +}) + +df_complex = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/1962_2006_walmart_store_openings.csv') + +app.layout = html.Div([ + dt.EditableTable( + id='editable-table', + editable=True, + dataframe=df_simple.to_dict() + ), + + dcc.Graph(id='my-graph', animate=True), + + html.Div( + dt.EditableTable(dataframe=df_complex.iloc[0:50].to_dict()), + style={'height': 100, 'overflow-y': 'scroll'} + ) + +]) + + +@app.callback( + dash.dependencies.Output('my-graph', 'figure'), + [dash.dependencies.Input('editable-table', 'dataframe')]) +def update_graph(dataframe_dict): + df = pd.DataFrame(dataframe_dict) + return { + 'data': [{ + 'x': df['Column 1'], + 'y': df['Column 2'] + }] + } + +app.css.append_css({"external_url": [ + "https://codepen.io/chriddyp/pen/bWLwgP.css", + "https://codepen.io/chriddyp/pen/rzyyWo.css" +]}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/three-column.py b/three-column.py new file mode 100644 index 0000000..fedfa25 --- /dev/null +++ b/three-column.py @@ -0,0 +1,77 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html + + +#Define Dash App +app=dash.Dash() + + +app.layout = html.Div([ + html.Div([ + dcc.Graph( + id='example-graph', + figure={ + 'data': [ + {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar'} + ], + 'layout': { + 'title': 'Dash Data Visualization', + 'height':500 + } + } + ), + ], + style={'width': '33%', 'display': 'inline-block'} + ), + + html.Div([ + html.Label('Multi-Select Dropdown'), + dcc.Dropdown( + options=[ + {'label': 'New York City', 'value': 'NYC'}, + {'label': u'Montreal', 'value': 'MTL'}, + {'label': 'San Francisco', 'value': 'SF'} + ], + value=['MTL', 'SF'], + multi=True + ), + + dcc.Graph( + id='example-graph3', + figure={ + 'data': [ + {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar'} + ], + 'layout': { + 'title': 'Dash Data Visualization', + 'height':250 + } + } + ) + ], + style={'width': '33%', 'display': 'inline-block'} + ), + + html.Div([ + dcc.Graph( + id='example-graph4', + figure={ + 'data': [ + {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar'} + ], + 'layout': { + 'title': 'Dash Data Visualization', + 'height':500 + } + } + ) + ], + style={'width': '33%', 'display': 'inline-block', 'float': 'right'}, + ) + ] +) + + +if __name__ == '__main__': + app.run_server() diff --git a/toggle-interval.gif b/toggle-interval.gif new file mode 100644 index 0000000..50438ef Binary files /dev/null and b/toggle-interval.gif differ diff --git a/toggle-interval.py b/toggle-interval.py new file mode 100644 index 0000000..101b3b1 --- /dev/null +++ b/toggle-interval.py @@ -0,0 +1,35 @@ +import dash_core_components as dcc +import dash_html_components as html +import dash +import datetime + +app = dash.Dash() + +app.layout = html.Div([ + dcc.Interval(id='my-interval'), + dcc.RadioItems(id='set-time', + value=1000, + options=[ + {'label': 'Every second', 'value': 1000}, + {'label': 'Every 5 seconds', 'value': 5000}, + {'label': 'Off', 'value': 60*60*1000} # or just every hour + ]), + html.Div(id='display-time') +]) + + +@app.callback( + dash.dependencies.Output('display-time', 'children'), + events=[dash.dependencies.Event('my-interval', 'interval')]) +def display_time(): + return str(datetime.datetime.now()) + + +@app.callback( + dash.dependencies.Output('my-interval', 'interval'), + [dash.dependencies.Input('set-time', 'value')]) +def update_interval(value): + return value + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/urls/multi_page.py b/urls/multi_page.py index e6e951c..123ec78 100644 --- a/urls/multi_page.py +++ b/urls/multi_page.py @@ -22,13 +22,14 @@ Output('content-container', 'children'), [Input('url', 'pathname')]) def display_page(pathname): + print(pathname) if pathname == '/': return html.Div([ html.Div('You are on the index page.'), # the dcc.Link component updates the `Location` pathname # without refreshing the page - dcc.Link(html.A('Go to page 2 without refreshing!'), href="/page-2"), + dcc.Link(html.A('Go to page 2 without refreshing!'), href="/page-2", style={'color': 'blue', 'text-decoration': 'none'}), html.Hr(), html.A('Go to page 2 but refresh the page', href="/page-2") ]) @@ -40,7 +41,9 @@ def display_page(pathname): else: return html.Div('I guess this is like a 404 - no content available') -app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) +# app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) + +app.scripts.config.serve_locally = True if __name__ == '__main__': app.run_server(debug=True) diff --git a/urls/styled.py b/urls/styled.py new file mode 100644 index 0000000..ef7168a --- /dev/null +++ b/urls/styled.py @@ -0,0 +1,14 @@ +import dash_core_components as dcc +import dash_html_components as html +import dash + +app = dash.Dash() + +app.layout = html.Div([ + dcc.Link('Unstyled Link', href="/page-1"), + dcc.Link('Styled Link', href="/page-2", style={"color": "red", "text-decoration": "none"}) +]) + + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/usage.py b/usage.py new file mode 100644 index 0000000..f823aa3 --- /dev/null +++ b/usage.py @@ -0,0 +1,60 @@ +import dash +import dash_core_components as dcc +import dash_html_components as html +import dash_table_experiments as dt +import pandas as pd + +app = dash.Dash() + +app.scripts.config.serve_locally=True + +DF_INITIAL = pd.DataFrame({ + 'Column 1': [1, 2, 3], + 'Column 2': [1, 19, 10], + 'Column 3': [3, 1, 2], +}) + +app.layout = html.Div([ + dt.EditableTable( + id='editable-table', + editable=True, + dataframe=DF_INITIAL.to_dict(), + + # Optional attributes + column_order=DF_INITIAL.columns, + merged_styles={ + 'td': { + 'border': 'thin lightgrey solid' + } + }, + index_name='Index', + types={ + 'Column 1': 'numeric', + 'Column 2': 'numeric', + 'Column 3': 'numeric' + } + ), + + dcc.Graph(id='my-graph'), + +]) + + +@app.callback( + dash.dependencies.Output('my-graph', 'figure'), + [dash.dependencies.Input('editable-table', 'dataframe')]) +def update_graph(dataframe_dict): + df = pd.DataFrame(dataframe_dict) + return { + 'data': [{ + 'x': df.index, + 'y': df[c], + 'mode': 'lines+markers', + 'marker': {'size': 12}, + 'line': {'width': 4}, + 'name': c + } for c in df.columns] + } + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/usage_basic_auth.py b/usage_basic_auth.py new file mode 100644 index 0000000..817b075 --- /dev/null +++ b/usage_basic_auth.py @@ -0,0 +1,49 @@ +# pip install dash==0.17.8rc1 +# pip install dash-auth==0.0.2 + +import dash +import dash_auth +import dash_html_components as html +import dash_core_components as dcc +import plotly + + +app = dash.Dash('auth') +auth = dash_auth.BasicAuth( + app, + (('hello', 'world',),) +) + +app.layout = html.Div([ + html.H1('Welcome to the app'), + html.H3('You are successfully authorized'), + dcc.Dropdown( + id='dropdown', + options=[{'label': i, 'value': i} for i in ['A', 'B']], + value='A' + ), + dcc.Graph(id='graph') +], className="container") + +@app.callback( + dash.dependencies.Output('graph', 'figure'), + [dash.dependencies.Input('dropdown', 'value')]) +def update_graph(dropdown_value): + return { + 'layout': { + 'title': 'Graph of {}'.format(dropdown_value), + 'margin': { + 'l': 20, + 'b': 20, + 'r': 10, + 't': 60 + } + }, + 'data': [{'x': [1, 2, 3], 'y': [4, 1, 2]}] + } + +app.scripts.config.serve_locally = True +app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/usage_plotly_auth.py b/usage_plotly_auth.py new file mode 100644 index 0000000..efc1928 --- /dev/null +++ b/usage_plotly_auth.py @@ -0,0 +1,51 @@ +# pip install dash==0.17.8rc1 +# pip install dash-auth==0.0.2 + +import dash +import dash_auth +import dash_html_components as html +import dash_core_components as dcc +import plotly + + +app = dash.Dash('auth') +auth = dash_auth.PlotlyAuth( + app, + 'Dash Authentication Sample App', + 'private', + 'http://localhost:8050' +) + +app.layout = html.Div([ + html.H1('Welcome to the app'), + html.H3('You are successfully authorized'), + dcc.Dropdown( + id='dropdown', + options=[{'label': i, 'value': i} for i in ['A', 'B']], + value='A' + ), + dcc.Graph(id='graph') +], className="container") + +@app.callback( + dash.dependencies.Output('graph', 'figure'), + [dash.dependencies.Input('dropdown', 'value')]) +def update_graph(dropdown_value): + return { + 'layout': { + 'title': 'Graph of {}'.format(dropdown_value), + 'margin': { + 'l': 20, + 'b': 20, + 'r': 10, + 't': 60 + } + }, + 'data': [{'x': [1, 2, 3], 'y': [4, 1, 2]}] + } + +app.scripts.config.serve_locally = True +app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"}) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/viacom.py b/viacom.py new file mode 100644 index 0000000..e79eedf --- /dev/null +++ b/viacom.py @@ -0,0 +1,32 @@ +import dash +import dash_html_components as html +import dash_core_components as dcc +import pandas as pd + +df = pd.DataFrame({ + 'a': [1, 2, 3, 4], + 'b': ['A', 'B', 'A', 'B'] +}) + +app = dash.Dash() + +app.layout = html.Div([ + dcc.Dropdown( + id='my-dropdown', + options=[ + {'label': i, 'value': i} for i in df['b'].unique() + ], + value='A' + ), + html.Div(id='my-output') +]) + +@app.callback( + dash.dependencies.Output('my-output', 'children'), + [dash.dependencies.Input('my-dropdown', 'value')]) +def display_value(value): + dff = df[df['b'] == value] + return list(dff) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/walmart.py b/walmart.py new file mode 100644 index 0000000..8656557 --- /dev/null +++ b/walmart.py @@ -0,0 +1,58 @@ +import dash +import dash_html_components as html +import dash_core_components as dcc + +import pandas as pd + +df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/1962_2006_walmart_store_openings.csv') + +app = dash.Dash() +app.scripts.config.serve_locally=True + +app.layout = html.Div([ + html.H1('Dash App'), + html.Div(id='text-element'), + dcc.Dropdown( + id='dropdown', + options=[ + {'label': i, 'value': i} + for i in df.YEAR.unique() + ], + value=2001 + ), + dcc.Graph( + id='my-graph', + figure={ + 'data': [ + {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar'} + ] + } + ) +]) + +@app.callback( + dash.dependencies.Output('text-element', 'children'), + [dash.dependencies.Input('dropdown', 'value')]) +def update_text(new_year): + dff = df[df.YEAR == new_year] + return 'There were {} stores in {}'.format( + len(dff), + new_year + ) + +@app.callback( + dash.dependencies.Output('my-graph', 'figure'), + [dash.dependencies.Input('dropdown', 'value')]) +def update_graph(new_value): + dff = df[df.YEAR == new_value] + return { + 'data': [{ + 'lat': dff.LAT, + 'lon': dff.LON, + 'type': 'scattermapbox', + }], + 'layout': {'mapbox': {'accesstoken': 'pk.eyJ1IjoiY2hyaWRkeXAiLCJhIjoiY2oyY2M4YW55MDF1YjMzbzhmemIzb290NiJ9.sT6pncHLXLgytVEj21q43A'}} + } + +if __name__ == '__main__': + app.run_server()