I am building a dashboard with multi-Page Apps plotly and bootstrap. There is a horizontal scrollbar overflow on my website. I am looking to remove a scroll bar, and remove this blank space after imagen, thank you.
Here is the code:
App:
import pandas as pd
from dash_auth import BasicAuth
from dash import Dash, dcc, html, Input, Output, callback
from dash_extensions.enrich import ServersideOutput, DashProxy, ServersideOutputTransform
import dash_bootstrap_components as dbc
from pages import test, error_404
df = pd.read_parquet('dataset.parquet.gzip')
external_stylesheets = [
dbc.themes.BOOTSTRAP,
dbc.icons.BOOTSTRAP,
]
app = Dash(__name__, title = 'Test',
external_stylesheets=external_stylesheets,
suppress_callback_exceptions=True,
)
server = app.server
app.layout = html.Div([
dcc.Location(id="url", pathname="", refresh=False),
# Header
dbc.Row([
dbc.Col(html.A(
html.Img(src=app.get_asset_url("leters.jpg"), className="img-fluid brand-other"),
id="logo",
href="https://www.leters.com/", target="blank"
), width='12', class_name='justify-content-end d-flex'),
]),
html.Div(id='page-content'),
], className='col-12 col-lg-12')
#callback(
Output(component_id='page-content', component_property='children'),
Input(component_id='url', component_property='pathname')
)
def routing(path):
print(path)
if path == "":
return test.test
else:
return error_404
if __name__ == "__main__":
app.run_server(debug=True)
test:
from dash import html
test = html.Div([
html.H3("test", className="sub_title"),
])
I think you should change from html.Div to dbc.Container as below:
app.layout = dbc.Container([
dcc.Location(id="url", pathname="", refresh=False),
# Header
dbc.Row([
dbc.Col(html.A(
html.Img(src=app.get_asset_url("leters.jpg"), className="img-fluid brand-other"),
id="logo",
href="https://www.leters.com/", target="blank"
), width='12', class_name='justify-content-end d-flex'),
]),
html.Div(id='page-content'),
], fluid=True)
Hope this help.
Related
In Python I am working with Dash and Dash bootstrap components. I am having trouble with the bootstrap Modal component. My most basic implementation of the modal, using the first example here, works fine. However, If I try to replace their single callback with two separate callbacks for the buttons, it stops working. Can anybody explain to me why this is and help me get it working? The callbacks don't seem difficult at all.
Most basic implementation of their code (this works for me):
from dash import Dash, html
from dash.dependencies import Input, Output, State
import dash_bootstrap_components as dbc
from dash_bootstrap_components.themes import LUMEN
app = Dash(external_stylesheets=[LUMEN])
app.title = "Test"
app.layout = html.Div(
[
dbc.Button("Open modal", id="open", n_clicks=0),
dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("Header")),
dbc.ModalBody("This is the content of the modal"),
dbc.ModalFooter(
dbc.Button(
"Close", id="close", className="ms-auto", n_clicks=0
)
),
],
id="modal",
is_open=False,
),
]
)
#app.callback(
Output("modal", "is_open"),
[Input("open", "n_clicks"), Input("close", "n_clicks")],
[State("modal", "is_open")],
)
def toggle_modal(n1, n2, is_open):
print(is_open)
print(type(is_open))
if n1 or n2:
return not is_open
return is_open
app.run()
Code with their callbacks replaced by two separate callbacks for the buttons (not working):
from dash import Dash, html
from dash.dependencies import Input, Output, State
import dash_bootstrap_components as dbc
from dash_bootstrap_components.themes import LUMEN
app = Dash(external_stylesheets=[LUMEN])
app.title = "Test"
app.layout = html.Div(
[
dbc.Button("Open modal", id="open", n_clicks=0),
dbc.Modal(
[
dbc.ModalHeader(dbc.ModalTitle("Header")),
dbc.ModalBody("This is the content of the modal"),
dbc.ModalFooter(
dbc.Button(
"Close", id="close", className="ms-auto", n_clicks=0
)
),
],
id="modal",
is_open=False,
),
]
)
#app.callback(
Output("modal", "is_open"),
Input("open", "n_clicks")
)
def toggle_modal_open(n1):
if n1:
return True
#app.callback(
Output("modal", "is_open"),
Input("close", "n_clicks")
)
def toggle_modal_close(n1):
if n1:
return False
app.run()
I'm building an app with dash-plotly but i'm confused about how to the layer correctly the items.
import dash
import dash_bootstrap_components as dbc
from dash import html
from dash import dcc
app = dash.Dash(__name__)
app.layout = html.Div([
dbc.Row([ #row 1
dcc.Input(type='text'),
html.Button('A button'),
]),
html.Br(),
dbc.Row([ #row 2
dcc.Dropdown(['0','1', '2','3','4','5','6','7','8','9','10'],
'1',
style={
'width':'10%'}),
html.Button('A Button'),
])
])
if __name__ == '__main__':
app.run_server(debug=True)
The items in row #1 are inline, but the items in row #2 are stacked on each other. Both rows are composed with different elements, so how to impose the items in row #2 to be inline? What are the rules regarding dbc.Row ?
I think the problem here that you are using dash bootstrap components but with default stylesheet and I think you should combine dbc.Col with dbc.Row to make better layout. Here is the sample code:
import dash
import dash_bootstrap_components as dbc
from dash import html
from dash import dcc
app = dash.Dash(__name__,external_stylesheets=[dbc.themes.LUX])
app.layout = html.Div([
dbc.Row([
dbc.Col([
dcc.Input(type='text')
],width={'size':1,'offset':0,'order':'1'}),
dbc.Col([
html.Button('A button'),
],width={'size':1,'offset':0,'order':'1'})
]),
html.Br(),
dbc.Row([
dbc.Col([
dcc.Dropdown(['0','1', '2','3','4','5','6','7','8','9','10'],
'1'),
],width={'size':1,'offset':0,'order':'1'}),
dbc.Col([
html.Button('A Button'),
],width={'size':1,'offset':0,'order':'1'})
])
])
if __name__ == '__main__':
app.run_server(debug=True)
As you see, I added external_stylesheets=[dbc.themes.LUX] and added dbc.Col to the layout.
You can also use Bootstrap 5 instead using dash bootstrap components library likewise -
import dash
import dash_bootstrap_components as dbc
from dash import html
from dash import dcc
app = dash.Dash(__name__, external_stylesheets = ["https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"])
app.layout = html.Div([
html.Div([
html.Div(
dcc.Input(id = "input-1", type = "text", placeholder = "Enter", className = "form-control"),
className = "col-lg-5"),
html.Div(
html.Button("Submit", id = "submit-1", className = "btn btn-dark"),
className = "col-lg-3"),
], className = "row row-cols-auto mb-4"),
html.Div([
html.Div(
dcc.Dropdown(['0','1', '2','3','4','5','6','7','8','9','10'],
'1'),
className = "col-lg-5"),
html.Div(
html.Button("Submit", id = "submit-2", className = "btn btn-dark"),
className = "col-lg-3"),
], className = "row row-cols-auto")
], className = "container-fluid mt-2")
if __name__ == '__main__':
app.run_server(debug=True)[![Sample][1]][1]
I have the following skeleton code
# ------------------------------
# IMPORT LIBRARIES
# ------------------------------
# Import Dash and Dash Bootstrap Components
import dash
import dash_bootstrap_components as dbc
from dash import Input, Output, dcc, html, dash_table, State
import dash_leaflet as dl
# Import Core Libraries
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from dash import Input, Output, dcc, html, dash_table
token='my_token'
FONT_AWESOME = "https://use.fontawesome.com/releases/v5.10.2/css/all.css"
# Import data
data_url = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vSGcAFoXyMXk7lj3KJrpzKd5XiBufm2xa7M39QNZxw5ma0TZhP35q-mf2ybyf9cZQdEwsoWkHiQWfjC/pub?gid=0&single=true&output=csv'
df = pd.read_csv(data_url)
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP,FONT_AWESOME], title='CONFIRM - SK4U', update_title=None,
meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=0.7, minimum-scale=0.4"}],
)
server = app.server
fig_map = px.scatter_mapbox(df,lat='latitude',lon='longitude',
mapbox_style='mapbox://styles/vostpt/cl1w0k6uf000415nt86nk7uv2',
#color='Kategória / Category',
width=1400,height=700,
hover_name='name',
#center=[48.799330977271445,19.338585158029197],
center=dict(lon=20.0068, lat=48.8264),
zoom=7,
custom_data=['name']
)
fig_map.update_layout(
hoverlabel=dict(
bgcolor="white",
font_size=16,
font_family="sans-serif"
)
)
fig_map.update_layout(mapbox = dict(accesstoken = token, style ='mapbox://styles/vostpt/cl1w0k6uf000415nt86nk7uv2'))
app.layout = html.Div(
[
dbc.Row(
[
dbc.Col(
dbc.Card(
dbc.CardBody(
[
html.H4("Title", className="card-title"),
html.H6("Card subtitle", className="card-subtitle"),
html.P(id="card_data"),
dbc.CardLink("Card link", href="#"),
dbc.CardLink("External link", href="https://google.com"),
]
),
),
),
dbc.Col(
dcc.Graph(id="my_map",figure=fig_map),
xs=12,
),
],
),
],
)
#app.callback(
Output(component_id="card_data", component_property="children"),
Input(component_id="my_map", component_property="hoverData")
)
def upgrade_card(hoverData):
title = hoverData['name'][0]
return title
if __name__ == "__main__":
app.run_server(host='0.0.0.0', debug=True)
My objective is to update the text in the card, with the data from the dataframe, on mouse hover.
The app receives the input from the hoverData but returns the error message
TypeError: 'NoneType' object is not subscriptable
Any help would be much appreciated.
Disclaimer: The solution will be used in a non-for-profit NGO's project. No commercial use will be made of the solution
These errors usually come up when you did not properly initialize. The children of the p-tag are non-existent in your example, so they cannot be updated.
So, replace html.P(id="card_data") with html.P("", id="card_data").
I am trying to add multiple navigations for the same URL path.
my code..
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
app = dash.Dash()
index_layout = html.Div([
# represents the URL bar, doesn't render anything
dcc.Location(id='url', refresh=False),
html.Br(),
dcc.Link(dbc.Button('Page1',
color="secondary",
className="mr-1",
outline=True,
style={"width":400,
"vertical-align": "middle",
}
), href='/page1'),
html.Br(),html.Br(),html.Br(),html.Br(),html.Br(),
dcc.Link(dbc.Button("Page2",
style={"width":400,
"vertical-align": "middle"},
color="secondary",
className="mr-1",
outline=True
), href='/page2'),
])
page1_layout = html.H1("Page1")
page2_layout = html.H1("Page2")
app.layout = html.Div([
dcc.Location(id='url-nav', refresh=True),
html.Span(dbc.Nav(
[
dbc.NavLink(dbc.NavLink("Page1", href="/page1")),
dbc.NavLink(dbc.NavLink("Page2", href="/page2")),
],
pills=True,),
className="ml-auto"
),
dcc.Location(id='url', refresh=True),
html.Center([
html.H3('DEMO AP',id='title'),
# content will be rendered in this element
html.Div(id='page-content'),
],),
])
### CALLBACKS
#app.callback(dash.dependencies.Output('page-content', 'children'),
[dash.dependencies.Input('url', 'pathname')])
def display_page(pathname="/"):
ctx = dash.callback_context
triggered_by = ctx.triggered[0].get("prop_id")
if pathname == "/page1":
return page1_layout
elif pathname == "/page2":
return page2_layout
else:
return index_layout
if __name__ == "__main__":
app.run_server()
Button navigations are working fine, but html.Nav only works on the very first click, not consistent and not working on the following clicks.
Kindly help.
From testing this out the problem seems to be with this line in index_layout:
dcc.Location(id='url', refresh=False),
If you look in the console you will see that a lot of requests are sent constantly when you're on the main page (when index_layout is rendered).
When this line is removed your code works as expected.
Working solution:
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_table
app = dash.Dash()
index_layout = html.Div(
[
html.Br(),
dcc.Link(
dbc.Button(
"Page1",
color="secondary",
className="mr-1",
outline=True,
style={
"width": 400,
"vertical-align": "middle",
},
),
href="/page1",
),
html.Br(),
html.Br(),
html.Br(),
html.Br(),
html.Br(),
dcc.Link(
dbc.Button(
"Page2",
style={"width": 400, "vertical-align": "middle"},
color="secondary",
className="mr-1",
outline=True,
),
href="/page2",
),
]
)
page1_layout = html.H1("Page1")
page2_layout = html.H1("Page2")
app.layout = html.Div(
[
dcc.Location(id="url-nav", refresh=True),
html.Span(
dbc.Nav(
[
dbc.NavLink(dbc.NavLink("Page1", href="/page1")),
dbc.NavLink(dbc.NavLink("Page2", href="/page2")),
],
pills=True,
),
className="ml-auto",
),
dcc.Location(id="url", refresh=True),
html.Center(
[
html.H3("DEMO AP", id="title"),
# content will be rendered in this element
html.Div(id="page-content"),
],
),
]
)
### CALLBACKS
#app.callback(
dash.dependencies.Output("page-content", "children"),
[dash.dependencies.Input("url", "pathname")],
)
def display_page(pathname="/"):
ctx = dash.callback_context
triggered_by = ctx.triggered[0].get("prop_id")
if pathname == "/page1":
return page1_layout
elif pathname == "/page2":
return page2_layout
else:
return index_layout
if __name__ == "__main__":
app.run_server()
The problem here I think is that there are two Location components rendered at the same time with the same id (url). This apparently causes the callback to be called constantly and causes inconsistent link behavior.
I want to create a map that shows specified locations using Dash. I prepared a script:
import dash
import dash_core_components as dcc
import dash_html_components as html
mapbox_access_token = 'pk.eyJ1IjoiYWxpc2hvYmVpcmkiLCJhIjoiY2ozYnM3YTUxMDAxeDMzcGNjbmZyMmplZiJ9.ZjmQ0C2MNs1AzEBC_Syadg'
app = dash.Dash()
server = app.server
app.layout = html.Div([
dcc.Graph(
id='simple-map',
figure=dict(
data=dict(
lat=[51.98799603],
lon=[5.922999562],
type='scattermapbox',
marker=dict(size=5, color='white', opacity=0)
),
layout=dict(
mapbox=dict(
layers=[],
accesstoken=mapbox_access_token,
style='light',
center=dict(
lat=52.370216,
lon=-4.895168,
),
pitch=0,
zoom=2.5
)
)
)
)
])
app.css.append_css({
'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'
})
if __name__ == '__main__':
app.run_server(debug=True)
However, I am getting this result:
What am I doing wrong?
The solution is always simpler than it seemed. You have to add brackets to the data and to the marker.
import dash
import dash_core_components as dcc
import dash_html_components as html
mapbox_access_token = 'pk.eyJ1IjoiYWxpc2hvYmVpcmkiLCJhIjoiY2ozYnM3YTUxMDAxeDMzcGNjbmZyMmplZiJ9.ZjmQ0C2MNs1AzEBC_Syadg'
app = dash.Dash()
server = app.server
app.layout = html.Div([
dcc.Graph(
id='simple-map',
figure=dict(
data=[dict(
lat=[51.98799603],
lon=[5.922999562],
type='scattermapbox',
marker=[dict(size=5, color='white', opacity=0)]
)],
layout=dict(
mapbox=dict(
layers=[],
accesstoken=mapbox_access_token,
style='light',
center=dict(
lat=52.370216,
lon=-4.895168,
),
pitch=0,
zoom=2.5
)
)
)
)
])
app.css.append_css({
'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'
})
if __name__ == '__main__':
app.run_server(debug=True)
And the results is: