Dash v1.12.0 is a minor release featuring:
- New shape drawing options in
dcc.Graph
- Updated
DataTable
conditional formatting options -
dcc.Store
bug fixes - Fixes to regressions to callback resolution introduced in 📣 Dash v1.11.0 Release - Introducing Pattern-Matching Callbacks
- Ability to prevent the initial callback from firing with
@app.callback(..., prevent_initial_call=True)
- Updated documentation chapters:
- 📣 DataTable Conditional Formatting Documentation
- 📣 New Documention on Setting DataTable & Column Widths & Heights
- 📣 Dash Callbacks documentation improvements (including clientside examples!)
- 📣 Dash v1.11.0 Release - Introducing Pattern-Matching Callbacks
- 📣 Updated Documentation - Looking for feedback
Official Changelog Dash v1.12.0
Shape-drawing in dcc.Graph
figures, triggering relayoutData
events
Plotly.js 1.54 includes new layout dragmodes in order to draw shapes such as rectangles, lines, open or closed paths etc. These shapes can also be modified or deleted when activated. Adding or modifying shapes triggers a relayoutData
event of the corresponding figure. Below we show a minimal app for measuring and displaying the lengths of objects in a Dash app. The new dragmodes are called 'drawline'
, 'drawopenpath'
, 'drawclosedpath'
, 'drawcircle'
, 'drawrect'
, and 'eraseshape'
(with self-explanatory names).
This new shape-drawing feature paves the way to powerful image processing Dash applications and we are very excited about it!
This development has been funded by the Chan-Zuckerberg Initiative (CZI) Essential Open-Source Software for Science program and we would like to thank CZI for their support.
import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
import dash_core_components as dcc
import plotly.express as px
from skimage import data
import math
app = dash.Dash(__name__)
img = data.coins() # or any image represented as a numpy array
fig = px.imshow(img, color_continuous_scale='gray')
layout = {}
for key in fig.layout:
layout[key] = fig.layout[key]
layout['dragmode'] = 'drawline'
layout['newshape'] = {'line':{'color':'cyan'}}
fig_dict = {'data':fig.data, 'layout':layout}
app.layout = html.Div(children=[
dcc.Graph(
id='graph',
figure=fig_dict,
config={'modeBarButtonsToAdd':['drawline']}),
html.Pre(id='content', children='Length of lines (pixels) \n')
], style={'width':'25%'})
@app.callback(
dash.dependencies.Output('content', 'children'),
[dash.dependencies.Input('graph', 'relayoutData')],
[dash.dependencies.State('content', 'children')])
def shape_added(fig_data, content):
if fig_data is None:
return dash.no_update
if 'shapes' in fig_data:
line = fig_data['shapes'][-1]
length = math.sqrt((line['x1'] - line['x0']) ** 2 +
(line['y1'] - line['y0']) ** 2)
content += '%.1f'%length + '\n'
return content
if __name__ == '__main__':
app.run_server(debug=True)
Improve DataTable conditional styling
It is now possible to customize the style of cells based on their state (active, selected) and to apply the same style to an array of column_id
, row_index
, and header_index
. This simplifies customization by reducing the number of styles that need to be defined and by making it possible to change the active/selected cells style without resorting to CSS overrides.
See conditional formatting documentation: 📣 DataTable Conditional Formatting Documentation
import dash
import dash_table
import dash_html_components as html
import pandas as pd
import random
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
app = dash.Dash(__name__)
data = df.to_dict('records')
app.layout = html.Div([
dash_table.DataTable(
columns=[dict(name=i, id=i) for i in df.columns],
data=data,
style_data={
"fontFamily": "serif"
},
style_data_conditional=[
{
"if": {
"state": "active"
},
"backgroundColor": "#3399FF",
"border": "#3399FF"
},
{
"if": {
"state": "selected"
},
"backgroundColor": "#99CCFF",
"border": "#99CCFF"
}, {
"if": {
"column_id": ["pop", "lifeExp", "gdpPercap"]
},
"backgroundColor": "#f8f8f8",
"fontFamily": "monospace"
}, {
"if": {
"row_index": [0, 1, 2, 3, 4]
},
"backgroundColor": "#fff0f0",
"color": "darkred"
}
]
)
])
app.run_server(debug=True)
Prevent initial callback from firing
When Dash renders a new component(s), whether on page load or as part of a callback that returns children
, Dash fires off all of the callbacks that have those components as inputs. For Input
& State
, Dash looks at the initial values supplied in the component and, if no values were supplied, it will pass None
into your callback.
For most use cases, this keeps your application consistent: you can omit pre-computing your output values and let Dash “fill in” the outputs through your callbacks.
You can now skip this initialization behavior by passing in prevent_initial_call=True
to your @app.callback
or, if you want to skip this for all of your callbacks, prevent_initial_callbacks=True
to app = dash.Dash(__name__, prevent_initial_callbacks=True)
There are three main use cases for using this:
-
Your application doesn’t display any output results on page load. For example, you might have an empty form with a button and might not want to display any output. Current, you might be using
raise dash.exceptions.PreventUpdate
orreturn [dash.no_update]
@app.callback(Output('my-graph', 'figure'), [Input('button', 'n_clicks')]) def update_graph(n_clicks): if n_clicks is None: raise dash.exceptions.PreventUpdate
Now, you can prevent your callback from even being fired in the first place with:
@app.callback( Output('my-graph', 'figure'), [Input('button', 'n_clicks')], prevent_initial_call=True) def update_graph(n_clicks): if n_clicks is None: raise dash.exceptions.PreventUpdate
This will improve the performance by preventing the network request(s) from occurring. With pattern-matching callbacks, you may have 10s or 100s of components that might otherwise fire off these requests.
-
Some components have “derived properties” where their property’s initial value is computed on page load.
dcc.Location
is like this: when the page loads, it dynamically checks for the pathname of the rendered page and then fires an update. Currently, on page load, your callbacks will be fired twice: once withNone
(as per Dash’s callback initialization routine) and immediately after oncedcc.Location
has figured out thepathname
. You can now skip theNone
call withprevent_initial_call=True
and just wait for the properpathname
to come through. -
You may want to speed up your application by precomputing the output values instead of computing them on-the-fly on every page load.
Previous Releases
- 📣 Dash v1.11.0 Release - Introducing Pattern-Matching Callbacks
- 📣 Dash v1.10.0 Release - New dcc.Graph features, updated dcc.Link, React upgrade and bug fixes
- 📣 Dash v1.9.0 release - Bug fixes
New Documentation & Videos
- Upcoming Webinar on Pattern-Matching Callbacks on May 7th by @alexcjohnson
-
dcc.Store
at https://dash.plotly.com/dash-core-components/store has been updated - 📣 DataTable Conditional Formatting Documentation
- 📣 New Documention on Setting DataTable & Column Widths & Heights
- 📣 Dash Callbacks documentation improvements (including clientside examples!)
- 📣 Dash v1.11.0 Release - Introducing Pattern-Matching Callbacks
- 📣 Updated Documentation - Looking for feedback
These features & bug fixes were funded directly by organizations sponsoring our development or requested by our Dash Enterprise customers. Want to learn more? Get in touch.
3 posts - 3 participants