Video Explanation:
The conditional format is through style_ data_ Provided by the conditional property. The if keyword provides a set of conditional formatting statements, and the other keywords are camelCased CSS properties.
The if syntax supports multiple objects, row_index,column_id, filter_query,column_type,column_editable, and state.
filter_query is the most flexible choice when processing data.
1, All operators
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) df['id'] = df.index app.layout = dash_table.DataTable( data=df.to_dict('records'), sort_action='native', columns=[ {'name': 'Date', 'id': 'Date', 'type': 'datetime', 'editable': False}, {'name': 'Delivery', 'id': 'Delivery', 'type': 'datetime'}, {'name': 'Region', 'id': 'Region', 'type': 'text'}, {'name': 'Temperature', 'id': 'Temperature', 'type': 'numeric'}, {'name': 'Humidity', 'id': 'Humidity', 'type': 'numeric'}, {'name': 'Pressure', 'id': 'Pressure', 'type': 'any'}, ], # Table editable editable=True, # Data attach style style_data_conditional=[ { 'if': { # Single condition 'column_id': 'Region', }, 'backgroundColor': 'dodgerblue', 'color': 'white' }, { 'if': { # filter_query supports multiple conditions 'filter_query': '{Humidity} > 19 && {Humidity} < 41', 'column_id': 'Humidity' }, 'backgroundColor': 'tomato', 'color': 'white' }, { 'if': { 'column_id': 'Pressure', # Notice the double braces 'filter_query': f'{{Pressure}} = {df["Pressure"].max()}' }, 'backgroundColor': '#85144b', 'color': 'white' }, { 'if': { # Number | odd '| even' 'row_index': 5, 'column_id': 'Region' }, 'backgroundColor': 'hotpink', 'color': 'white' }, { 'if': { 'filter_query': '{id} = 4', # matching rows of a hidden column with the id, `id` 'column_id': 'Region' }, 'backgroundColor': 'RebeccaPurple' }, { 'if': { 'filter_query': '{Delivery} > {Date}', # comparing columns to each other 'column_id': 'Delivery' }, 'backgroundColor': '#3D9970' }, { 'if': { 'column_editable': False # True | False }, 'backgroundColor': 'rgb(240, 240, 240)', 'cursor': 'not-allowed' }, { 'if': { 'column_type': 'text' # 'text' | 'any' | 'datetime' | 'numeric' }, 'textAlign': 'left' }, { 'if': { 'state': 'active' # 'active' | 'selected' }, 'backgroundColor': 'rgba(0, 116, 217, 0.3)', 'border': '1px solid rgb(0, 116, 217)' } ] ) if __name__ == '__main__': app.run_server(debug=True)
2, Description of conditional operators
- filter_query supports different operators according to the data type of the column:
- =, >, > =, <, < = and contains are supported by all data types (numeric, text, datetime, and any)
- When using contains, a string is required on the right, so {Date} contains "01" can work, but {Date} contains 1 will not.
- Datestartswitch supports datetime
- is nil is supported for all data types
- is blank all data types are supported
- The default data type of the column is any
- column_type refers to the data type of the column (numeric, text, datetime, and any)
- column_editable can be equal to True or False (new in Dash 1.12.0)
- state can be equal to 'active' or 'selected' (added in Dash 1.12.0). Use it to change the default pink background and border color for selected and active cells.
- row_ The index is absolute - if you filter or sort the table, line 5 remains highlighted. Try sorting the columns and notice how "San Francisco" remains highlighted, while "London" does not.
- column_id, row_index and header_index can be equal to a scalar (as above) or a list of values. For example, 'column_id ': [' Region ',' Pressure '] is valid (new in Dash 1.12.0). DataTable filtering and conditional formatting perform faster when specifying a list of values and a list of individual if blocks.
- Attention 'filter_query ':' {delivery} > {date} ': filtering queries can compare columns with each other!
- id is a special hidden column that can be used as a row_index an alternative to highlighting data by index. Since each row has a unique id, the related conditional format id will still be associated with the data after sorting and filtering.
- Rebecca purple, hotpin, dodgerblue... These are named CSS colors. We recommend avoiding common color names such as red, blue and green because they look very outdated. For additional color recommendations, see http://clrs.cc/ .
- Since we are using. format, we {use {{and} to escape}}.
- To highlight a row, omit the column_id. To highlight a specific cell, include column_id.
- style_cell_conditional (all cells, including headers), style_header_conditional (header cell), style_filter_conditional is an alternative keyword that can be used to filter other parts of the table.
- Limit - if the table is editable, the maximum value may change if the user edits the table. Because this example hardcodes the maximum value in the filter expression, the highlighted value will no longer be highlighted. As a workaround, you can_ data_ Conditional in derived_ virtual_ When data changes, it is updated through callback. This restriction applies to any conditional format that uses hard coded numbers calculated from expressions in Python (including many examples below!).
3, Override highlight style
Instead of highlighting background cells, you can change the text color, bold text, underline, or style with any other css property.
import dash from dash import dash_table import pandas as pd from collections import OrderedDict from dash.dash_table.Format import Format, Sign data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), sort_action='native', columns=[ {"name": i, "id": i} for i in df.columns ], style_data_conditional=[ { 'if': { # Humidity column rows greater than 19 and less than 41, tomato color, bold 'filter_query': '{Humidity} > 19 && {Humidity} < 41', 'column_id': 'Humidity' }, 'color': 'tomato', 'fontWeight': 'bold' }, { 'if': { # Pressure column, lines greater than 19, text underlined 'filter_query': '{Pressure} > 19', 'column_id': 'Pressure' }, 'textDecoration': 'underline' } ] ) if __name__ == '__main__': app.run_server(debug=True)
4, Special characters such as emoticons, stars, check marks, circles
- You can copy and paste emoticons unicode characters directly into your code. We recommend copying values from emojipedia, for example https://emojipedia.org/star/ .
- New unicode emoticon characters are released every year and may not be available in the character set of your audience machine. The appearance of these icons is different on most operating systems.
- You may need to place # -- coding: utf-8 -- at the top of the code.
# -*- coding: utf-8 -*- import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) df['Rating'] = df['Humidity'].apply(lambda x: '⭐⭐⭐' if x > 30 else ( '⭐⭐' if x > 20 else ( '⭐' if x > 10 else '' ))) df['Growth'] = df['Temperature'].apply(lambda x: '↗️' if x > 0 else '↘️') df['Status'] = df['Temperature'].apply(lambda x: '🔥' if x > 0 else '🚒') app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), columns=[ {"name": i, "id": i} for i in df.columns ], ) if __name__ == '__main__': app.run_server(debug=True)
5, Highlight the maximum / minimum value in the column
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), columns=[ {"name": i, "id": i} for i in df.columns ], # Data attach style, style_data_conditional=[ { 'if': { # Pressure column, take the maximum value, and pay attention to the double braces 'filter_query': f'{{Pressure}} = {df["Pressure"].max()}', 'column_id': 'Pressure' }, 'backgroundColor': '#FF4136', 'color': 'white' }, { 'if': { # The whole row of the minimum value of the Temperature column, and set the background color and word color 'filter_query': f'{{Temperature}} = {df["Temperature"].min()}', }, 'backgroundColor': 'skyblue', 'color': 'white' }, ] ) if __name__ == '__main__': app.run_server(debug=True)
6, Highlight the first or last three values in the column
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), columns=[ {"name": i, "id": i} for i in df.columns ], style_data_conditional=( # Add two list derivations [ { 'if': { 'filter_query': f'{{Temperature}} = {i}', 'column_id': 'Temperature', }, 'backgroundColor': 'tomato', 'color': 'white' } for i in df['Temperature'].nlargest(3) # Top three of maximum ] + # Add two list derivations [ { 'if': { 'filter_query': f'{{Pressure}} = {i}', 'column_id': 'Pressure', }, 'backgroundColor': '#7FDBFF', 'color': 'white' } for i in df['Pressure'].nsmallest(3) # Top three minimum values ] ) ) if __name__ == '__main__': app.run_server(debug=True)
7, Highlight the maximum value for each row
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) def highlight_max_row(df): # Filter all numeric columns and delete the id column df_numeric_columns = df.select_dtypes('number').drop(['id'], axis=1) print(df_numeric_columns) return [ { 'if': { 'filter_query': f'{{id}} = {i}', 'column_id': col }, 'backgroundColor': 'tomato', 'color': 'white' } # idxmax(axis=1) find the maximum value of each row for (i, col) in enumerate( df_numeric_columns.idxmax(axis=1) ) ] # The id column is required to get the maximum value df['id'] = df.index app.layout = dash_table.DataTable( data=df.to_dict('records'), sort_action='native', # The page display does not contain an id column columns=[{'name': i, 'id': i} for i in df.columns if i != 'id'], # When the data attachment style needs to filter the data, it needs to call the function for processing, which cannot be processed directly in the layout style_data_conditional=highlight_max_row(df) ) if __name__ == '__main__': app.run_server(debug=True)
8, Highlight the first two values in a row
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) def style_row_by_top_values(df, nlargest=2): # Filter all numeric columns and delete the id column numeric_columns = df.select_dtypes('number').drop(['id'], axis=1).columns # Define style list styles = [] for i in range(len(df)): # Arrange rows in reverse order row = df.loc[i, numeric_columns].sort_values(ascending=False) # Rows that meet the requirements are added to the style list in turn for j in range(nlargest): styles.append({ 'if': { 'filter_query': f'{{id}} = {i}', 'column_id': row.keys()[j] }, 'backgroundColor': 'tomato', 'color': 'white' }) return styles # The id column is required to get the maximum value df['id'] = df.index app.layout = dash_table.DataTable( data=df.to_dict('records'), sort_action='native', # The page display does not contain an id column columns=[{'name': i, 'id': i} for i in df.columns if i != 'id'], # When the data attachment style needs to filter the data, it needs to call the function for processing, which cannot be processed directly in the layout style_data_conditional=style_row_by_top_values(df) ) if __name__ == '__main__': app.run_server(debug=True)
9, Highlight the first 10% or the last 10% by column
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) print(list(df.quantile(0.9).iteritems())) # [('Temperature', 5213.5), ('Humidity', 55.0), ('Pressure', 7418.0)] app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), sort_action='native', columns=[{'name': i, 'id': i} for i in df.columns], style_data_conditional=[ { 'if': { # {Temperature} >= 5213.5,{Humidity} >= 55.0, {Pressure} >= 7418.0 'filter_query': f'{{{col}}} >= {value}', 'column_id': col }, 'backgroundColor': '#B10DC9', 'color': 'white' # df.quantile(0.9) quantile 0.9 } for (col, value) in df.quantile(0.9).iteritems() ] ) if __name__ == '__main__': app.run_server(debug=True)
10, Highlight the above average and below average values in the column
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), sort_action='native', columns=[{'name': i, 'id': i} for i in df.columns], style_data_conditional=( [ { 'if': { # 50% or more 'filter_query': f'{{{col}}} >= {value}', 'column_id': col }, 'backgroundColor': 'tomato', 'color': 'white' # Quantile 0.1 } for (col, value) in df.quantile(0.5).iteritems() ] + # List derivation splicing [ { 'if': { # Less than 50% 'filter_query': '{{{}}} < {}'.format(col, value), 'column_id': col }, 'backgroundColor': 'skyblue', 'color': 'white' # Quantile 0.5 } for (col, value) in df.quantile(0.5).iteritems() ] ) ) if __name__ == '__main__': app.run_server(debug=True)
11, Highlight None, NaN, or empty string values
import dash from dash import dash_table import pandas as pd import numpy as np import dash_html_components as html data_with_none = [ {'Firm': 'Acme', '2017': '', '2018': 5, '2019': 10, '2020': 4}, {'Firm': 'Olive', '2017': None, '2018': 3, '2019': 13, '2020': 3}, {'Firm': 'Barnwood', '2017': np.NaN, '2018': 7, '2019': 3, '2020': 6}, {'Firm': 'Henrietta', '2017': 14, '2018': 1, '2019': 13, '2020': 1}, ] df = pd.DataFrame(data_with_none) app = dash.Dash(__name__) app.layout = html.Div([ html.Pre(repr(df)), dash_table.DataTable( data=df.to_dict('records'), columns=[{'name': i, 'id': i} for i in df.columns], style_data_conditional=( [ { 'if': { 'filter_query': '{{{}}} is blank'.format(col), 'column_id': col }, 'backgroundColor': 'tomato', 'color': 'white' } for col in df.columns ] ) ) ]) if __name__ == '__main__': app.run_server(debug=True)
12, Displays special values for NaN or None values
import dash from dash import dash_table, html import pandas as pd import numpy as np from dash.dash_table.Format import Format data_with_none = [ {'Firm': 'Acme', '2017': '', '2018': 5, '2019': 10, '2020': 4}, {'Firm': 'Olive', '2017': None, '2018': 3, '2019': 13, '2020': 3}, {'Firm': 'Barnwood', '2017': np.NaN, '2018': 7, '2019': 3, '2020': 6}, {'Firm': 'Henrietta', '2017': 14, '2018': 1, '2019': 13, '2020': 1}, ] df = pd.DataFrame(data_with_none) app = dash.Dash(__name__) app.layout = html.Div([ html.Pre(repr(df)), dash_table.DataTable( data=df.to_dict('records'), columns=[ { 'name': i, 'id': i, 'type': 'numeric', 'format': Format( nully='N/A' ) } for i in df.columns ], editable=True ) ]) if __name__ == '__main__': app.run_server(debug=True)
13, Highlight the text that contains the value
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), columns=[ {'name': i, 'id': i} for i in df.columns ], style_data_conditional=[ { 'if': { 'filter_query': '{Region} contains "New"' }, 'backgroundColor': '#0074D9', 'color': 'white' } ] ) if __name__ == '__main__': app.run_server(debug=True)
14, Highlight text equal to the value
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), columns=[ {'name': i, 'id': i} for i in df.columns ], style_data_conditional=[ { 'if': { 'filter_query': '{Region} = "San Francisco"' }, 'backgroundColor': '#0074D9', 'color': 'white' } ] ) if __name__ == '__main__': app.run_server(debug=True)
15, Highlight cells by value using color scales such as heat map
import dash from dash import dash_table, html import pandas as pd from collections import OrderedDict wide_data = [ {'Firm': 'Acme', '2017': 13, '2018': 5, '2019': 10, '2020': 4}, {'Firm': 'Olive', '2017': 3, '2018': 3, '2019': 13, '2020': 3}, {'Firm': 'Barnwood', '2017': 6, '2018': 7, '2019': 3, '2020': 6}, {'Firm': 'Henrietta', '2017': -3, '2018': -10, '2019': -5, '2020': -6}, ] df = pd.DataFrame(wide_data) app = dash.Dash(__name__) def discrete_background_color_bins(df, n_bins=5, columns='all'): import colorlover bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)] if columns == 'all': if 'id' in df: df_numeric_columns = df.select_dtypes('number').drop(['id'], axis=1) else: df_numeric_columns = df.select_dtypes('number') else: df_numeric_columns = df[columns] df_max = df_numeric_columns.max().max() df_min = df_numeric_columns.min().min() ranges = [ ((df_max - df_min) * i) + df_min for i in bounds ] styles = [] legend = [] for i in range(1, len(bounds)): min_bound = ranges[i - 1] max_bound = ranges[i] backgroundColor = colorlover.scales[str(n_bins)]['seq']['Blues'][i - 1] color = 'white' if i > len(bounds) / 2. else 'inherit' for column in df_numeric_columns: styles.append({ 'if': { 'filter_query': ( '{{{column}}} >= {min_bound}' + (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '') ).format(column=column, min_bound=min_bound, max_bound=max_bound), 'column_id': column }, 'backgroundColor': backgroundColor, 'color': color }) legend.append( html.Div(style={'display': 'inline-block', 'width': '60px'}, children=[ html.Div( style={ 'backgroundColor': backgroundColor, 'borderLeft': '1px rgb(50, 50, 50) solid', 'height': '10px' } ), html.Small(round(min_bound, 2), style={'paddingLeft': '2px'}) ]) ) return (styles, html.Div(legend, style={'padding': '5px 0 5px 0'})) (styles, legend) = discrete_background_color_bins(df) app.layout = html.Div([ html.Div(legend, style={'float': 'right'}), dash_table.DataTable( data=df.to_dict('records'), sort_action='native', columns=[{'name': i, 'id': i} for i in df.columns], style_data_conditional=styles ), ]) if __name__ == '__main__': app.run_server(debug=True)
16, Use color scale highlighting on a single column
import dash from dash import dash_table, html import pandas as pd from collections import OrderedDict wide_data = [ {'Firm': 'Acme', '2017': 13, '2018': 5, '2019': 10, '2020': 4}, {'Firm': 'Olive', '2017': 3, '2018': 3, '2019': 13, '2020': 3}, {'Firm': 'Barnwood', '2017': 6, '2018': 7, '2019': 3, '2020': 6}, {'Firm': 'Henrietta', '2017': -3, '2018': -10, '2019': -5, '2020': -6}, ] df = pd.DataFrame(wide_data) app = dash.Dash(__name__) def discrete_background_color_bins(df, n_bins=5, columns='all'): import colorlover bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)] if columns == 'all': if 'id' in df: df_numeric_columns = df.select_dtypes('number').drop(['id'], axis=1) else: df_numeric_columns = df.select_dtypes('number') else: df_numeric_columns = df[columns] df_max = df_numeric_columns.max().max() df_min = df_numeric_columns.min().min() ranges = [ ((df_max - df_min) * i) + df_min for i in bounds ] styles = [] legend = [] for i in range(1, len(bounds)): min_bound = ranges[i - 1] max_bound = ranges[i] backgroundColor = colorlover.scales[str(n_bins)]['seq']['Blues'][i - 1] color = 'white' if i > len(bounds) / 2. else 'inherit' for column in df_numeric_columns: styles.append({ 'if': { 'filter_query': ( '{{{column}}} >= {min_bound}' + (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '') ).format(column=column, min_bound=min_bound, max_bound=max_bound), 'column_id': column }, 'backgroundColor': backgroundColor, 'color': color }) legend.append( html.Div(style={'display': 'inline-block', 'width': '60px'}, children=[ html.Div( style={ 'backgroundColor': backgroundColor, 'borderLeft': '1px rgb(50, 50, 50) solid', 'height': '10px' } ), html.Small(round(min_bound, 2), style={'paddingLeft': '2px'}) ]) ) return (styles, html.Div(legend, style={'padding': '5px 0 5px 0'})) (styles, legend) = discrete_background_color_bins(df, columns=['2018']) app.layout = html.Div([ legend, dash_table.DataTable( data=df.to_dict('records'), sort_action='native', columns=[{'name': i, 'id': i} for i in df.columns], style_data_conditional=styles ) ]) if __name__ == '__main__': app.run_server(debug=True)
17, Display data bar
import dash from dash import dash_table import pandas as pd df_gapminder = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv') df = df_gapminder[:500] app = dash.Dash(__name__) def data_bars(df, column): n_bins = 100 bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)] ranges = [ ((df[column].max() - df[column].min()) * i) + df[column].min() for i in bounds ] styles = [] for i in range(1, len(bounds)): min_bound = ranges[i - 1] max_bound = ranges[i] max_bound_percentage = bounds[i] * 100 styles.append({ 'if': { 'filter_query': ( '{{{column}}} >= {min_bound}' + (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '') ).format(column=column, min_bound=min_bound, max_bound=max_bound), 'column_id': column }, 'background': ( """ linear-gradient(90deg, #0074D9 0%, #0074D9 {max_bound_percentage}%, white {max_bound_percentage}%, white 100%) """.format(max_bound_percentage=max_bound_percentage) ), 'paddingBottom': 2, 'paddingTop': 2 }) return styles def data_bars_diverging(df, column, color_above='#3D9970', color_below='#FF4136'): n_bins = 100 bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)] col_max = df[column].max() col_min = df[column].min() ranges = [ ((col_max - col_min) * i) + col_min for i in bounds ] midpoint = (col_max + col_min) / 2. styles = [] for i in range(1, len(bounds)): min_bound = ranges[i - 1] max_bound = ranges[i] min_bound_percentage = bounds[i - 1] * 100 max_bound_percentage = bounds[i] * 100 style = { 'if': { 'filter_query': ( '{{{column}}} >= {min_bound}' + (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '') ).format(column=column, min_bound=min_bound, max_bound=max_bound), 'column_id': column }, 'paddingBottom': 2, 'paddingTop': 2 } if max_bound > midpoint: background = ( """ linear-gradient(90deg, white 0%, white 50%, {color_above} 50%, {color_above} {max_bound_percentage}%, white {max_bound_percentage}%, white 100%) """.format( max_bound_percentage=max_bound_percentage, color_above=color_above ) ) else: background = ( """ linear-gradient(90deg, white 0%, white {min_bound_percentage}%, {color_below} {min_bound_percentage}%, {color_below} 50%, white 50%, white 100%) """.format( min_bound_percentage=min_bound_percentage, color_below=color_below ) ) style['background'] = background styles.append(style) return styles app.layout = dash_table.DataTable( data=df.to_dict('records'), sort_action='native', columns=[{'name': i, 'id': i} for i in df.columns], style_data_conditional=( data_bars(df, 'lifeExp') + data_bars(df, 'gdpPercap') ), style_cell={ 'width': '100px', 'minWidth': '100px', 'maxWidth': '100px', 'overflow': 'hidden', 'textOverflow': 'ellipsis', }, page_size=20 ) if __name__ == '__main__': app.run_server(debug=True)
18, Divergent data bar
import dash from dash import dash_table import pandas as pd df_gapminder = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv') df = df_gapminder[:500] app = dash.Dash(__name__) def data_bars(df, column): n_bins = 100 bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)] ranges = [ ((df[column].max() - df[column].min()) * i) + df[column].min() for i in bounds ] styles = [] for i in range(1, len(bounds)): min_bound = ranges[i - 1] max_bound = ranges[i] max_bound_percentage = bounds[i] * 100 styles.append({ 'if': { 'filter_query': ( '{{{column}}} >= {min_bound}' + (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '') ).format(column=column, min_bound=min_bound, max_bound=max_bound), 'column_id': column }, 'background': ( """ linear-gradient(90deg, #0074D9 0%, #0074D9 {max_bound_percentage}%, white {max_bound_percentage}%, white 100%) """.format(max_bound_percentage=max_bound_percentage) ), 'paddingBottom': 2, 'paddingTop': 2 }) return styles def data_bars_diverging(df, column, color_above='#3D9970', color_below='#FF4136'): n_bins = 100 bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)] col_max = df[column].max() col_min = df[column].min() ranges = [ ((col_max - col_min) * i) + col_min for i in bounds ] midpoint = (col_max + col_min) / 2. styles = [] for i in range(1, len(bounds)): min_bound = ranges[i - 1] max_bound = ranges[i] min_bound_percentage = bounds[i - 1] * 100 max_bound_percentage = bounds[i] * 100 style = { 'if': { 'filter_query': ( '{{{column}}} >= {min_bound}' + (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '') ).format(column=column, min_bound=min_bound, max_bound=max_bound), 'column_id': column }, 'paddingBottom': 2, 'paddingTop': 2 } if max_bound > midpoint: background = ( """ linear-gradient(90deg, white 0%, white 50%, {color_above} 50%, {color_above} {max_bound_percentage}%, white {max_bound_percentage}%, white 100%) """.format( max_bound_percentage=max_bound_percentage, color_above=color_above ) ) else: background = ( """ linear-gradient(90deg, white 0%, white {min_bound_percentage}%, {color_below} {min_bound_percentage}%, {color_below} 50%, white 50%, white 100%) """.format( min_bound_percentage=min_bound_percentage, color_below=color_below ) ) style['background'] = background styles.append(style) return styles app.layout = dash_table.DataTable( data=df.to_dict('records'), sort_action='native', columns=[{'name': i, 'id': i} for i in df.columns], style_data_conditional=( data_bars_diverging(df, 'lifeExp') + data_bars_diverging(df, 'gdpPercap') ), style_cell={ 'width': '100px', 'minWidth': '100px', 'maxWidth': '100px', 'overflow': 'hidden', 'textOverflow': 'ellipsis', }, page_size=20 ) if __name__ == '__main__': app.run_server(debug=True)
19, Highlight date
import dash from dash import dash_table import pandas as pd from collections import OrderedDict data = OrderedDict( [ ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]), ("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]), ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]), ("Humidity", [10, 20, 30, 40, 50, 60]), ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]), ] ) df = pd.DataFrame(data) app = dash.Dash(__name__) app.layout = dash_table.DataTable( data=df.to_dict('records'), columns=[ {'name': i, 'id': i} if i != 'Date' else {'name': 'Date', 'id': 'Date', 'type': 'datetime'} for i in df.columns ], style_data_conditional=[{ 'if': {'filter_query': '{Date} datestartswith "2015-10"'}, 'backgroundColor': '#85144b', 'color': 'white' }] ) if __name__ == '__main__': app.run_server(debug=True)