Pandas 'key' error while creating charts through Dash - python

I am trying to create a scatter plot between two metrics after asking for the dimension level drill down. However, I am getting the the error: KeyError: u’brand’(one of the column names). I am new do Dash and cannot debug the error because there is nothing wrong with the column name. Following is the code:
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd
import sqlalchemy as sq
import numpy as np
from datetime import datetime
engine_prd = sq.create_engine(“connection url”)
df=pd.read_sql(“SELECT t1.date,
t1.article_type as article_type,
t1.product_gender as product_gender,
t1.brand as brand,
t1.master_category as master_category,
t1.business_unit as business_unit,
SUM(t1.revenue) as revenue,
SUM(t1.sold_quantity) as units_sold,
SUM(t1.total_discount) / NULLIF( SUM(t1.total_mrp),0) AS discount_perc,
SUM(t1.approved_po_quantity) - SUM(t1.po_inwarded_quantity) AS pending_invard_quantity,
SUM(t1.revenue) / NULLIF(SUM(t1.list_count), 0) AS rpi,
SUM(t1.list_count),
100 *ratio_to_report(SUM(t1.list_count)) OVER (PARTITION BY t1.DATE) AS lc_share
FROM fact_category_over_view_metrics t1
WHERE t1.DATE> 20180101 and is_live_style=1
GROUP BY
t1.DATE,t1.article_type,t1.product_gender,t1.brand,t1.master_category,
t1.business_unit;”,engine_prd)
df[[‘date_format’]] = df[[‘date’]].applymap(str).applymap(lambda s: “{}/{}/{}”.format(s[4:6],s[6:], s[0:4]))
df[[‘year_month’]]=df[[‘date’]].applymap(str).applymap(lambda s: “{}-{}”.format(s[0:4],s[4:6]))
df[‘year_month’]=df[‘year_month’].astype(str)
year_month=df[‘year_month’].unique()
available_indicators = np.array([‘revenue’,‘units_sold’,‘discount_perc’,‘pending_invard_quantity’,‘rpi’,‘lc_share’])
dimension_level=np.array([‘brand’,‘product_gender’,‘article_type’,‘master_category’,‘business_unit’])
#available_indicators=list(df)
app=dash.Dash()
app.layout = html.Div([
html.Div([
html.Div([
dcc.Dropdown(
id='dimension-level',
options=[{'label': i, 'value': i} for i in dimension_level],
value='brand'
)]),
html.Div([
dcc.Dropdown(
id='crossfilter-xaxis-column',
options=[{'label': i, 'value': i} for i in available_indicators],
value='revenue'
),
dcc.RadioItems(
id='crossfilter-xaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Linear',
labelStyle={'display': 'inline-block'}
)
],
style={'width': '48%', 'display': 'inline-block'}),
html.Div([
dcc.Dropdown(
id='crossfilter-yaxis-column',
options=[{'label': i, 'value': i} for i in available_indicators],
value='units_sold'
),
dcc.RadioItems(
id='crossfilter-yaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Linear',
labelStyle={'display': 'inline-block'}
)
], style={'width': '48%', 'float': 'right', 'display': 'inline-block'})
]),
dcc.Graph(
id='crossfilter-indicator-scatter'),
dcc.Slider(
id='crossfilter-year-month--slider',
min=0,
max=len(df['year_month'].unique()),
value=0,
step=None,
marks={i : str(yearm) for i, yearm in enumerate(df['year_month'].unique())} # enumerate the dates
)
])
#app.callback(
dash.dependencies.Output(‘crossfilter-indicator-scatter’, ‘figure’),
[dash.dependencies.Input(‘dimension-level’, ‘value’),
dash.dependencies.Input(‘crossfilter-xaxis-column’, ‘value’),
dash.dependencies.Input(‘crossfilter-yaxis-column’, ‘value’),
dash.dependencies.Input(‘crossfilter-xaxis-type’, ‘value’),
dash.dependencies.Input(‘crossfilter-yaxis-type’, ‘value’),
dash.dependencies.Input(‘crossfilter-year-month–slider’, ‘value’)],
[dash.dependencies.State(‘crossfilter-year-month–slider’, ‘marks’)])
def update_graph(dimension_level_name,xaxis_column_name, yaxis_column_name,xaxis_type, yaxis_type, selected_year_month_key,marks):
selected_year_month=marks[str(selected_year_month_key)]
df_filtered = df[df['year_month'] == selected_year_month]
dff=df_filtered.groupby([dimension_level_name]).sum()
return {
'data': [go.Scatter(
x=dff[xaxis_column_name],
y=dff[yaxis_column_name],
text=dff[dimension_level_name],
#customdata=dff['article_type'],
mode='markers',
marker={
'size': 15,
'opacity': 0.5,
'line': {'width': 0.5, 'color': 'white'}
}
)],
'layout': go.Layout(
xaxis={
'title': xaxis_column_name,
'type': 'linear' if xaxis_type == 'Linear' else 'log'
},
yaxis={
'title': yaxis_column_name,
'type': 'linear' if yaxis_type == 'Linear' else 'log'
},
margin={'l': 40, 'b': 30, 't': 10, 'r': 0},
height=450,
hovermode='closest'
)
}
if name == ‘main’:
app.run_server()
The errors occurs while grouping by the df using the input value from dropdown. The data frame’s head looks has been linked to The sample data:

The key error occurs in "text=dff[dimension_level_name]". It is because while grouping by the dataframe , as_index is not set to False. This will throw a key error. The problem was solved by replacing dff=df_filtered.groupby([dimension_level_name]).sum() with:
dff=df_filtered.groupby([dimension_level_name].as_index=False).sum()

Related

Arranging elements horizontally in a dash application

I'm trying to develop a Dash application in python. I tried adding style={'display': 'inline-block'} to the html.Div() component, as well as to other components, but couldn't set the drop-down menus to align in one row.
The page looks as follows:
with the inline styling:
Without the inline styling:
The code in the question was given to me as a template that needs to be filled properly. The complex hierarchy was part of the template. My job is to add code as needed. I'm adding only the problematic part of the code (without the title and the graph elements that are seen in the images):
df = pd.read_csv("dash\Pricing Data.csv")
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
boxplot_layout = (
dbc.Container(
[dbc.Row(
[
dbc.Col(
[
dbc.Card(
[
dbc.CardBody(
[
dbc.Row(
[
dbc.Col(
html.Div(
dbc.Row(
[
dbc.Col(
[
dcc.Dropdown(
id="aggregate-dropdown",
options=[
{
"label": "Total",
"value": "sum",
},
{
"label": "Average",
"value": "average",
},
],
value="sum",
style={
'textAlign': 'center',
# 'color': colors['text']
},
)
],
),
dbc.Col(
[
dcc.Dropdown(
id="y-dropdown",
options=[
{'label': i, 'value': i}
for i in df.columns],
style={
'textAlign': 'center',
},
value='Age'
)
],
),
dbc.Col(
[
html.Label(
"by",
style={
'textAlign': 'center',
# 'color': colors['text']
}
)
],
),
dbc.Col(
[
dcc.Dropdown(
id="x-dropdown",
options=[
{'label': i, 'value': i}
for i in df.columns],
style={
'textAlign': 'center',
'padding': '3px ',
},
value='Age'
)],),],)))],),])],inverse=True,)])])]))
app.layout = boxplot_layout
if __name__ == "__main__":
app.run_server(debug=True)
Also, as can be seen in the images, there's an error message. I couldn't find solutions for this error, so if you have any ideas regarding its cause or how to find it I'll be grateful if you could post it too.
Thanks.
Following the doc example:
dbc.Row(
[
dbc.Col(html.Div("One of three columns")),
dbc.Col(html.Div("One of three columns")),
dbc.Col(html.Div("One of three columns")),
]
),
it results something you are chasing for. So, that's the basic structure, removing unnecessary code, follows:
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
import pandas as pd
df = pd.read_csv()
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div([
dbc.Container([
dbc.Row([
dbc.Col(
html.Div([
dcc.Dropdown(
id="aggregate-dropdown",
options=[
{
"label": "Total",
"value": "sum",
},
{
"label": "Average",
"value": "average",
},
],
value="sum",
style={
'textAlign': 'center',
# 'color': colors['text']
},
)
]), width=3
),
dbc.Col(
html.Div([
dcc.Dropdown(
id="y-dropdown",
options=[
{'label': i, 'value': i}
for i in df.columns],
style={
'textAlign': 'center',
},
value='Age'
)
]), width=3
),
dbc.Col(
html.Div([
html.Label(
"by",
style={
'textAlign': 'center',
# 'color': colors['text']
}
)
]), width=1
),
dbc.Col(
html.Div([
dcc.Dropdown(
id="x-dropdown",
options=[
{'label': i, 'value': i}
for i in df.columns],
style={
'textAlign': 'center',
},
value='Age'
)
]), width=3
),
])
])
])
if __name__ == "__main__":
app.run_server(debug=True)
Note I passed a 'width=' keyword argument to set the size of columns.
And that's the result:
result
I hope it's that help you to find the better way to organize your code.
What I did eventually was to change the style inside the Column components of the Drop-down menus, as well as the style of the Drop-down themselves. I used the tags 'padding' and 'width' and changed their values until it looked OK. I also used the value 'inline-block' for the 'display' tag.
For instance, here's the code for one of the drop-down menus and it's column:
dbc.Col(
[
dcc.Dropdown(
id="y-axis-dropdown",
options=
[{'label': i, 'value': i} for i in df.columns],
value='Age',
style={'textAlign': 'center'}
)
], style={
'display': 'inline-block',
'width': '25%',
'padding': 30,
'textAlign': 'center'
}
)

Divide my dashboard into two columns in Python Dash

I tried now for some time to divide my dashboard into two columns, with "Material1" centered in the first column, and "Material2" centered in the second column, keeping the graph as is (entire width) of this dashboard:
I tried dbc.col and dbc.Row methods to solve this, but haven't found the right way to do this.
Any help is highly appreciated!! :)
This is my code:
app.layout = html.Div([
# Input Row: Material 1
html.Div([
html.Label('Material 1'),
dcc.Dropdown(
id='dropdown1',
options=[{'label': k, 'value': k} for k in all_options.keys()],
value=options1[0],
style={'width': '400px', 'margin-left': 0}),
]),
html.Div([
html.Label('m3'),
daq.NumericInput(
id='numeric-input-1',
min=0,
max=200,
value=0,
style={'width': '200px', 'margin-left': 0}),
]),
# Input Row: Material 2
html.Div([
html.Label('Material 2'),
dcc.Dropdown(
id='dropdown2',
options=[{'label': k, 'value': k} for k in all_options.keys()],
value=options1[0],
style={'width': '400px', 'margin-left': 0}),
]),
html.Div([
html.Label('m3'),
daq.NumericInput(
id='numeric-input-2',
min=0,
max=200,
value=0,
style={'width': '200px', 'margin-left': 0}),
], style={'display': 'inline-block'}),
# Input: Indicator
html.Div([
html.Label('Indicator'),
dcc.Dropdown(
id='dropdown3',
style={'width': '400px', 'margin-left': 0}),
]),
#Graph
html.Div([
dcc.Graph(
id='display-selected-values',
style={'width': '2400px', 'margin-left': 0, 'columnCount': 1}),
])
])
it's all about being systematic (where code formatters help)
using dash 2.0.0 and dbc 1.0.0-b1
keep on embedding Row and Col as required to meet your layout requirements
import json
import numpy as np
import dash_bootstrap_components as dbc
import dash
from jupyter_dash import JupyterDash
all_options = {k: v for k, v in zip(list("ABCD"), np.random.randint(1, 4, 4))}
options1 = list(all_options.keys())
# Build App
app = JupyterDash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dash.html.Div(
[
dbc.Row(
[
dbc.Col(
dbc.Row(
[
dash.html.Label("Material 1"),
dash.dcc.Dropdown(
id="dropdown1",
options=[
{"label": k, "value": k} for k in all_options.keys()
],
value=options1[0],
style={"width": "400px", "margin-left": 0},
),
],
justify="center",
),
),
dbc.Col(
dbc.Row(
[
dash.html.Label("Material 2"),
dash.dcc.Dropdown(
id="dropdown2",
options=[
{"label": k, "value": k} for k in all_options.keys()
],
value=options1[0],
style={"width": "400px", "margin-left": 0},
),
],
justify="center",
),
),
],
justify="center",
),
dash.dcc.Graph(id="newCases", style={"height": "45vh"}),
],
style={"font-family": "Arial", "font-size": "0.9em", "text-align": "center"},
)
# Run app and display result inline in the notebook
app.run_server(mode="inline")

Aligning the height of the first and second column in Python Dash app

I have a probably simple problem that I cannot solve. I have two columns in my Python Dash dashboard, which are not aligned in height, see here:
What do I need to change in my code so that the two columns are on the same height?
Any help is much appreciated.
This is my code:
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div([
html.Label('Material 1'),
dcc.Dropdown(
id='s1m1s',
options=[{'label': i, 'value': i} for i in available_indicators],
value=options1[0],
),
html.Label('Material 1'),
dcc.Dropdown(
id='s1mdf45',
options=[{'label': i, 'value': i} for i in available_indicators],
value=options1[0],
),
], style={'width': '20%', 'display': 'inline-block'}),
html.Div([
html.Label('m3'),
daq.NumericInput(
id='s2m1_num',
min=0,
max=200,
value=0,
),
html.Label('m3'),
daq.NumericInput(
id='s2m2_num',
min=0,
max=200,
value=0,
),
], style={'width': '20%', 'display': 'inline-block'})
])
You can add 'vertical-align': 'top' to the style dictionaries of the two columns to make sure that they are aligned at the top, see below.
import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_daq as daq
app = dash.Dash(__name__)
app.layout = html.Div([
# first column
html.Div(
children=[
html.Label('Material 1'),
dcc.Dropdown(
id='s1m1s',
options=[{'label': i, 'value': i} for i in ['option_1', 'option_2', 'option_3']],
value='option_1',
),
html.Label('Material 1'),
dcc.Dropdown(
id='s1mdf45',
options=[{'label': i, 'value': i} for i in ['option_1', 'option_2', 'option_3']],
value='option_2',
),
],
style={
'width': '20%',
'display': 'inline-block',
'vertical-align': 'top',
}
),
# second column
html.Div(
children=[
html.Label('m3'),
daq.NumericInput(
id='s2m1_num',
min=0,
max=200,
value=0,
),
html.Label('m3'),
daq.NumericInput(
id='s2m2_num',
min=0,
max=200,
value=0,
),
],
style={
'width': '20%',
'display': 'inline-block',
'vertical-align': 'top',
}
)
])
if __name__ == '__main__':
app.run_server(debug=True, host='127.0.0.1')

Invalid prop for this component

I'm running this app using Python Dash .I keep getting this error even though the app is loading for me perfectly. Can you please help me spot where I'm going wrong?
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objects as go
from dash.dependencies import Input, Output
import plotly.express as px
df = px.data.tips()
sales1 = pd.read_csv("sales_data_sample.csv", encoding='unicode_escape')
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div([
html.Label('Process Monitoring Dashboard',style={'font-size':'25px','color':'blue','margin-left': '50%'},id='w_countries')
]),
html.P("Process End Date",style={'margin-left': '10%'}),
dcc.Dropdown(
id='ped',
value='-Select Process End Date',
options=[{'value': x, 'label': x}
for x in ['2021', '2022', '2023', '2024']],
clearable=False,
style={'width': '30%','margin-left': '10%'}
),
html.P("User Or Role",style={'margin-left': '10%'}),
dcc.Dropdown(
id='uor',
value='-Select User Or Role',
options=[{'value': x, 'label': x}
for x in ['Admin', 'Guest User']],
clearable=False,
style={'width': '30%','margin-left': '10%'}
),
html.P("Process Start Date",style={'margin-left': '10%'}),
dcc.Dropdown(
id='psd',
value='-Select Process Start Date',
options=[{'value': x, 'label': x}
for x in ['2021', '2022', '2023', '2024']],
clearable=False,
style={'width': '30%','margin-left': '10%'}
),
html.P("Process",style={'margin-left': '10%'}),
dcc.Dropdown(
id='p',
value='-Select Process',
options=[{'value': x, 'label': x}
for x in ['Disputed','In Process','On Hold','Resolved','Cancelled']],
clearable=False,
style={'width': '30%','margin-left': '10%'}
),
# Create pie chart
html.Div([
html.Br(),
dcc.Graph(id='pie',
config={'displayModeBar': 'hover'}),
],style={'margin-left': '1.4%', 'width': '50%', 'display': 'inline-block'}),
# Create horizontal bar chart (top 10 countries)
html.Div([
html.Br(),
dcc.Graph(id='top_10',
config={'displayModeBar': 'hover'}),
], style={'width': '48.6%', 'display': 'inline-block', 'float': 'right'})
])
#app.callback(Output('pie', 'figure'),
[Input('w_countries', 'value')])
def display_content(w_countries):
Cancelled = sales1.loc[sales1['STATUS'] == 'Cancelled'].count()[0]
Disputed = sales1.loc[sales1['STATUS'] == 'Disputed'].count()[0]
In_Process = sales1.loc[sales1['STATUS'] == 'In Process'].count()[0]
On_Hold = sales1.loc[sales1['STATUS'] == 'On Hold'].count()[0]
Resolved = sales1.loc[sales1['STATUS'] == 'Resolved'].count()[0]
Shipped = sales1.loc[sales1['STATUS'] == 'Shipped'].count()[0]
return {
'data': [go.Pie(labels=['Cancelled', 'Disputed', 'In Process', 'On Hold', 'Resolved', 'Shipped'],
values=[Cancelled, Disputed, In_Process, On_Hold, Resolved, Shipped],
hoverinfo='label+value+percent',
textinfo='label+value',
textposition='auto',
textfont=dict(size=13),
insidetextorientation='radial',
rotation=70,
)],
'layout': go.Layout(
width=780,
height=520,
hovermode='closest',
title={
'text': 'Instance By Process',
'y': 0.93,
'x': 0.43,
'xanchor': 'center',
'yanchor': 'top'},
titlefont={'family': 'Oswald',
'color': 'rgb(230, 34, 144)',
'size': 25},
legend={
'orientation': 'h',
'bgcolor': 'rgba(255,255,255,0)',
'xanchor': 'center', 'x': 0.5, 'y': -0.05},
),
}
# Create horizontal bar chart (top 10 countries)
#app.callback(Output('top_10', 'figure'),
[Input('w_countries', 'value')])
def update_graph(w_countries):
top_countries = sales1.groupby(['COUNTRY'])[['SALES', 'QUANTITYORDERED']].sum().sort_values(by=['SALES'], ascending=False).nlargest(10, columns=['SALES']).reset_index()
return {
'data': [go.Bar(x=top_countries['SALES'],
y=top_countries['COUNTRY'],
text=top_countries['SALES'],
texttemplate='%{text:.2s}',
textposition='inside',
marker=dict(
color=top_countries['SALES'],
colorscale='portland',
showscale=False),
orientation='h',
hoverinfo='text',
hovertext=
'<b>Country</b>: ' + top_countries['COUNTRY'].astype(str) + '<br>' +
'<b>Sales</b>: $' + [f'{x:,.0f}' for x in top_countries['SALES']] + '<br>' +
'<b>Q.Ordered</b>: $' + [f'{x:,.0f}' for x in top_countries['QUANTITYORDERED']] + '<br>'
)],
'layout': go.Layout(
width=780,
height=520,
# plot_bgcolor='rgb(250, 242, 242)',
# paper_bgcolor='rgb(250, 242, 242)',
title={
'text': 'Top 10 Countries with active customers',
'y': 0.93,
'x': 0.43,
'xanchor': 'center',
'yanchor': 'top'},
titlefont={'family': 'Oswald',
'color': 'rgb(230, 34, 144)',
'size': 25},
hovermode='closest',
xaxis=dict(title='<b>Sales</b>',
color='rgb(230, 34, 144)',
showline=True,
showgrid=True,
showticklabels=True,
linecolor='rgb(104, 204, 104)',
linewidth=2,
ticks='outside',
tickfont=dict(
family='Arial',
size=12,
color='rgb(17, 37, 239)'
)
),
yaxis=dict(title='<b>Country</b>',
autorange='reversed',
color='rgb(230, 34, 144)',
showline=True,
showgrid=False,
showticklabels=True,
linecolor='rgb(104, 204, 104)',
linewidth=2,
ticks='outside',
tickfont=dict(
family='Arial',
size=12,
color='rgb(17, 37, 239)'
)
)
)
}
if __name__ == '__main__':
app.run_server(debug=True)
And this is my error
Invalid prop for this component
Property "value" was used with component ID:
"w_countries"
in one of the Input items of a callback.
This ID is assigned to a dash_html_components.Label component
in the layout, which does not support this property.
This ID was used in the callback(s) for Output(s):
pie.figure
top_10.figure
You've told Dash to use the value from a Label component as an input for your callback. But Label doesn't have a value, and it isn't interactive like that. You need to use a different input for that callback.

Layout and Dropdown menu in Dash - Python

I cannot seem to be able to get the layout of my dropdown menu boxes correctly. Basically I want for the dropdown box to be on the right of their matching question and on the same line.
Can anyone help please?
I have tried multiple combinations of style={'display': 'inline-block', 'width:'X%'} and className = 'X columns' with no luck.
import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_auth
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Div(
[
html.Div(
[
html.H6("""Select your current industry""",
style={'textAlign': 'right', 'font-weight':'bold', 'margin-left': '0em', 'margin-right': '2em', 'display': 'inline-block', 'width': '40%'})
],
),
dcc.Dropdown(
id = 'business_area_dropdown',
options=[
{'label': 'Academia', 'value': 'academia'},
{'label': 'Energy', 'value': 'energy'},
{'label': 'Research', 'value': 'research'}
],
placeholder="Select Business Area",
style = dict(
width = '40%',
display = 'inline-block',
verticalAlign = "middle"
)
)
],
className='row'
),
html.Div(
[
html.Div(
[
html.H6("""Are you happy where you are?""",
style={'textAlign': 'right', 'font-weight':'bold', 'margin-left': '0em', 'margin-right': '2em', 'display': 'inline-block', 'width': '40%'})
],
),
dcc.Dropdown(
id = 'search_preference',
options=[
{'label': 'Yes', 'value': 'yes'},
{'label': 'No', 'value': 'no'}
],
placeholder="Select Answer",
style = dict(
width = '40%',
display = 'inline-block',
verticalAlign = "middle"
)
)
],
className='row'
),],
style={'display': 'inline-block', 'backgroundColor': '#fff7dd', 'width': '99%'}
)
if __name__ == '__main__':
app.run_server()
The dropdown boxes appear in a completely different line. I'd like for the dropdown boxes to be aligned horizontally to their respective questions to be answered.
My favorite styling trick, Flexbox, is how I would solve this one.
app.layout = html.Div([
html.Div(
[
html.Div(
[
html.H6("""Select your current industry""",
style={'margin-right': '2em'})
],
),
dcc.Dropdown(
id='business_area_dropdown',
options=[
{'label': 'Academia', 'value': 'academia'},
{'label': 'Energy', 'value': 'energy'},
{'label': 'Research', 'value': 'research'}
],
placeholder="Select Business Area",
style=dict(
width='40%',
verticalAlign="middle"
)
)
],
style=dict(display='flex')
),
html.Div(
[
html.Div(
[
html.H6("""Are you happy where you are?""",
style={'margin-right': '2em'})
],
),
dcc.Dropdown(
id='search_preference',
options=[
{'label': 'Yes', 'value': 'yes'},
{'label': 'No', 'value': 'no'}
],
placeholder="Select Answer",
style=dict(
width='40%',
display='inline-block',
verticalAlign="middle"
)
)
],
style=dict(display='flex')
), ],
)
And here is a screenshot of the results:

Categories