Introduction to Dash framework from Plotly, reactive framework for building dashboards in Python. Tech talk covers basics and more advanced topics like custom component and scaling.
Speaker: Damian Rodziewicz.
Resources:
1. Blogpost
https://appsilon.com/overview-of-dash-python-framework-from-plotly-for-building-dashboards/
2. Github
https://github.com/DamianRodziewicz/dash_example
app.py
https://github.com/DamianRodziewicz/dash_example longer_computations_app.py
3. Youtube:
https://youtu.be/NUXUmv-aeG4
Tech Talk - Overview of Dash framework for building dashboards
1. Dash
Appsilon tech talks | Damian | 04/04/2018
Overview of Dash framework for building dashboards
2. What is Dash?
● Dash is a productive Python framework for building web applications.
● Created and maintained by Plotly. https://plot.ly/products/dash/.
● Written on top of Flask, Plotly.js, and React.js.
● Dashboard is implemented in pure Python.
● Dash is an open source library, released under the permissive MIT license.
3. What you get with Dash
● Frontend generated in Python
● Reactive computations abstraction
● Component class for every HTML tag as well as keyword arguments for all of the HTML arguments implemented in
dash_html_components package
● Interactive html elements implemented in dash-core-components
● Plotly python API implemented in dash-core-components available through Graph class
5. What you see in the code
● The layout is composed of a tree of "components" like html.Div and dcc.Graph.
● The dash_html_components library has a component for every HTML tag. The html.H1(children='Hello Dash') component
generates a <h1>Hello Dash</h1> HTML element in your application.
● Not all components are pure HTML. The dash_core_components describe higher-level components that are interactive and are
generated with JavaScript, HTML, and CSS through the React.js library.
● Each component is described entirely through keyword attributes. Dash is declarative: you will primarily describe your
application through these attributes.
● The children property is special. By convention, it's always the first attribute which means that you can omit it:
html.H1(children='Hello Dash') is the same as html.H1('Hello Dash'). Also, it can contain a string, a number, a single component,
or a list of components.
● Attribute 'class' is replaced with 'className'.
● Style attribute can be a python dictionary.
● Attributes cannot have hyphen in name. If you need to write something like 'margin-left', you have to write 'marginLeft' instead.
● Attribute values must be serializable to JSON.
6. Interactivity
● The "inputs" and "outputs" of our application interface are described declaratively through the app.callback decorator.
● The inputs and outputs of our application are simply the properties of a particular component.
● Any "Output" can have multiple "Input" components.
○ @app.callback(Output('indicator-graphic', 'figure'),
[Input('xaxis-column', 'value'), Input('yaxis-column', 'value'), Input('year--slider', 'value')])
def update_graph(xaxis_value, yaxis_value, year_slider_value): …
● Each Dash callback function can only update a single Output property.
○ To update multiple Outputs, you have to write multiple functions.
● "State" allows you to pass along extra values without firing the callbacks.
○ @app.callback(Output('indicator-graphic', 'figure'),
[Input('xaxis-column', 'value'), Input('yaxis-column', 'value')],
[State('year--slider', 'value')])
def update_graph(xaxis_value, yaxis_value, year_slider_value): …
● There are no intermediate values in the reactive graph.
○ You have to add hidden div with intermediate data (as suggested by plotly)
○ Or you have to use redis to store intermediate values (as suggested by plotly)
7. How does this work?
● Declare app layout. It will generate react code that will be run in the browser.
● Each element has attributes that describe its state.
○ You can change them which makes the app re-render itself.
○ You can listen on any changes to those attributes and run callbacks.
● Frontend sends HTTP request every time an input is changed.
● Backend recalculates the graph of dependencies and sends back the list of changes to frontend.
8. One more look
into the code
https://github.com/DamianRodziewicz/dash_example
app.py
9. Dash core components
● Dropdown
● Slider
● RangeSlider
● Input
● TextArea
● Checkboxes
● RadioItems
● Button
● DatePickerSingle
● DatePickerRange
● Markdown
● Upload component
● Tabs
● Graph - component shares the same syntax as the open-source plotly.py library. See https://plot.ly/python/ for reference
● Interactive Table - under development in https://github.com/plotly/dash-table-experiments repository
10. Dash custom components - Dash semantic
● You can implement your own components in Dash. For more information on how to do that visit https://dash.plot.ly/plugins
● We have started implementing our own components and helpers in https://github.com/Appsilon/dash-semantic
○ Leaflet map
○ Timeline (react horizontal timeline port)
○ Mixpanel hook (to allow using Mixpanel with frontend plugin that identifies user by cookie)
○ IncludeScript (includes and runs an external script on demand - useful if app runs in local mode)
● We’ll cover this library (and instructions on using it in your project) in separate tech talk.
12. Single threaded Dash
● Graph recalculation is blocking and is single threaded
● However we can extract the flask server that is generated and use gunicorn to make the computations concurrent
● http://gunicorn.org/ - Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The
Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly
speedy.
● Seems to still have a limit on concurrent users.
14. Dash limitations
● We don’t know how it scales for many concurrent users
● At some point you will need more sophisticated components than Dash provides by default
○ You’ll have to write your own components in React.js
○ Or you’ll have to port already existing components from React.js to Dash
● You’ll quickly find out that some quick wins are still under development (Mapbox raster example)
● There are no intermediate values in the reactive graph.
○ You have to add hidden div with intermediate data (as suggested by plotly)
● You have to write separate function for every Output which forces you to restructure the code
● There are some issues we may not be able to resolve without getting to know the way Dash works by heart
● There may be still some issues with Dash that we don’t know about - we have to add a margin to our work