I am trying to create a simple Dash application that includes Dash-Leaflet so that it plots some points as markers. It is apparently working as expected when no styles are applied. But I would like to create a layout with bootstrap with tabs as in this example: https://hellodash.pythonanywhere.com/
When I place the map element within a tab container, it does not render properly. If I move it away it works fine.
This is the code I have so far:
from dash import Dash, dcc, html, dash_table, Input, Output, callback
import plotly.express as px
import dash_bootstrap_components as dbc
import dash_leaflet as dl
import dash_leaflet.express as dlx
from dash_extensions.javascript import assign
import pandas as pd
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
header = html.H4(
"Sample map", className="bg-primary text-white p-2 mb-2 text-center"
)
data = pd.DataFrame([{'name': 'Point 1', 'lat': 39.535, 'lon': 0.0563, 'cluster': 1, 'val_x': 0, 'val_y': 1},
{'name': 'Point 2', 'lat': 40.155, 'lon': -0.0453, 'cluster': 1, 'val_x': 1, 'val_y': 4},
{'name': 'Point 1', 'lat': 38.875, 'lon': 0.0187, 'cluster': 2, 'val_x': 2, 'val_y': 2}])
dropdown = html.Div(
[
dbc.Label("Select Cluster"),
dcc.Dropdown(
data.cluster.unique().tolist(),
id="cluster_selector",
clearable=False,
),
],
className="mb-4",
)
controls = dbc.Card(
[dropdown],
body=True,
)
tab1 = dbc.Tab([dl.Map([dl.TileLayer()], style={'width': '100%',
'height': '50vh',
'margin': "auto",
"display": "block"}, id="map")], label="Map")
tab2 = dbc.Tab([dcc.Graph(id="scatter-chart")], label="Scatter Chart")
tabs = dbc.Card(dbc.Tabs([tab1, tab2]))
app.layout = dbc.Container(
[
header,
dbc.Row(
[
dbc.Col(
[
controls,
],
width=3,
),
dbc.Col([tabs], width=9),
]
),
],
fluid=True,
className="dbc",
)
if __name__ == "__main__":
app.run_server(debug=True, port=8052)
This is what it looks like.
I have tried the proposed solutions on this post but they do not seem to work (or I am applying the wrong)
Do you have any suggestions on where to look for the problem?
Thank you very much.
Related
I have a small issue with Dash Table.
What I want to do is to put the table "records" inside the HTML container "graphique3". I have two problems:
First, when I simply want to display the table, nothing appears, it's just a copy/paste of a template here: https://dash.plotly.com/datatable/style. It works when I make a new file though.
Second, if I put my table code inside the container "graphique3" I get this error message
SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?" for data = OrderedDict
I don't understand what is the issue, since, as mentioned before, it works fine in a new file.
# Run this app with `python app.py` and
# visit http://127.0.0.1:8050/ in your web browser.
from dash import Dash, html, dcc, dash_table
import plotly.express as px
import pandas as pd
import dash_daq as daq
from collections import OrderedDict
app = Dash(__name__)
# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
df = pd.DataFrame({
"Fruit": ["Apples", "Oranges", "Bananas", "test4", "test5", "test6","test7","test8","test9"],
"Amount": [4, 1, 2, 2, 4, 5, 9, 5, 6],
})
fig = px.bar(df, x="Fruit", y="Amount", barmode="group")
#Réduire l'espace entre les éléments
fig.update_layout(
margin=dict(l=5, r=5, t=5, b=5),
paper_bgcolor="white",
),
# Table to put inside the container "graphique4"
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(__name__)
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
style_cell_conditional=[
{
'if': {'column_id': c},
'textAlign': 'left'
} for c in ['Date', 'Region']
],
style_data={
'color': 'black',
'backgroundColor': 'white'
},
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': 'rgb(220, 220, 220)',
}
],
style_header={
'backgroundColor': 'rgb(210, 210, 210)',
'color': 'black',
'fontWeight': 'bold'
}
)
app.layout = html.Div(className='dashboard', children=[
# ------ Graphiques --------
#Première row
html.Div(className='row1', style={'display': 'flex', 'justify-content': 'center'}, children=[
# Graphiques
html.Div(className='graphique1',children=[
dcc.Graph(
id='exemple-graph1',
figure=fig,
style={'flex-grow': '1', 'width':'900px'}
),
]),
html.Div(className='graphique2',children=[
dcc.Graph(
id='exemple-graph2',
figure=fig,
style={'flex-grow': '1', 'width':'900px'}
),
]),
]),
# Deuxième row
html.Div(className='row2', style={'display': 'flex', 'justify-content': 'center'}, children=[
# Graphiques
html.Div(className='graphique3', children=[
dcc.Graph(
id='exemple-graph3',
figure=fig,
#style={'display': 'flex', 'width': '500px'}
),
]),
html.Div(className='graphique4', children=[
daq.Gauge(
color={"gradient": True, "ranges": {"green": [0, 6], "yellow": [6, 8], "red": [8, 10]}},
value=2,
label='Temps avant la prochaine relève',
max=10,
min=0,
),
]),
html.Div(className='graphique5', children=[
dcc.Graph(
id='exemple-graph5',
figure=fig,
)
]),
]),
])
if __name__ == '__main__':
app.run_server(debug=True)
#lien tutoriel : https://towardsdatascience.com/dash101-part-2-prettify-dash-dashboard-with-css-and-python-3866c069a3b6
The following code fragment taken from the Dash Tutorial website generates a HTML table.
def generate_table(dataframe, max_rows=10):
return html.Table([
html.Thead(
html.Tr([html.Th(col) for col in dataframe.columns])
),
html.Tbody([
html.Tr([
html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
]) for i in range(min(len(dataframe), max_rows))
])
])
Within your code you then call the function to generate the table and pass the dataframe as a parameter.
html.Div(className='graphique3', children=[
dcc.Graph(
id='exemple-graph3',
figure=fig,
#style={'display': 'flex', 'width': '500px'}
),
generate_table(df)
]),
I want to get from a call back a DF(DataFrame) and the figure for that same DF, but I want to show each one individually.
I will take this example posted by #Philippe in this link just to have something to work with and give some ideas:
import dash
import dash_core_components as dcc
import dash_table as dt
import dash_html_components as html
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
import plotly.graph_objs as go
sample_data = {
'series': {
'data': [
{'title': 'Game of Thrones', 'score': 9.5},
{'title': 'Stranger Things', 'score': 8.9},
{'title': 'Vikings', 'score': 8.6}
],
'style': {
'backgroundColor': '#ff998a'
}
},
'movies': {
'data': [
{'title': 'Rambo', 'score': 7.7},
{'title': 'The Terminator', 'score': 8.0},
{'title': 'Alien', 'score': 8.5}
],
'style': {
'backgroundColor': '#fff289'
}
}
}
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1('Multi output example'),
dcc.Dropdown(id='data-dropdown', options=[
{'label': 'Movies', 'value': 'movies'},
{'label': 'Series', 'value': 'series'}
], value='movies'),
html.Div([
dcc.Graph(id='graph'),
dt.DataTable(id='data-table', columns=[
{'name': 'Title', 'id': 'title'},
{'name': 'Score', 'id': 'score'}
])
])
], id='container')
#app.callback([
Output('graph', 'figure'),
Output('data-table', 'data'),
Output('data-table', 'columns'),
Output('container', 'style')
], [Input('data-dropdown', 'value')])
def multi_output(value):
if value is None:
raise PreventUpdate
selected = sample_data[value]
data = selected['data']
columns = [
{'name': k.capitalize(), 'id': k}
for k in data[0].keys()
]
figure = go.Figure(
data=[
go.Bar(x=[x['score']], text=x['title'], name=x['title'])
for x in data
]
)
return figure, data, columns, selected['style']
if __name__ == '__main__':
app.run_server()
In the end a results showing the fig and data of the DataFrame is shown
like this.
However, I want to first show the figure. Then I want to use the data from the DF created in the callback to do more calculations and finally display those calculations using a submit button you click on it.
Is this possible?
What I have done so far is using two different callbacks with kind of the same script, but I was wondering if I can used just one callback a save some repetition in the code.
I hope my question is clear, and thank you in advance!
I found a solution!I used dcc.store here some references if someone need it in the future: https://dash.plotly.com/dash-core-components/store
My line code was this one:
dcc.Store(id='store-data', data=[], storage_type='memory'),
Taking from https://www.youtube.com/watch?v=dLykSQNIM1E. Great video created by Youtube Channel: Charming Data
I am trying to create a dashboard to show the ethnicity makeup in different cities for multiple years. My dataframe consists of Year, Month, City and Native variables. I pasted an image on the bottom that shows my dataframe. I also tried to replicate a Dash code that I have but I received multiple errors after executing it, and it looks like most of the errors are about the City variable. Is there any guide to get my dash to work?
import dash
from jupyter_dash import JupyterDash # pip install dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output
#df
import dash
from jupyter_dash import JupyterDash # pip install dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output
#df
app = JupyterDash()
app.layout = html.Div([
html.H1("Native Country of Father"),
dcc.Dropdown(
id='cities',
options=[{'label': i, 'value': i} for i in list(df.City.unique()) + ['All']],
value='All'
),
dcc.RadioItems(
id='xaxis-type',
options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],
value='Log',
labelStyle={'display': 'inline-block'}
),
dcc.Graph(id='graph-with-slider'),
dcc.Slider(
id='year-slider',
min=df['Year'].min(),
max=df['Year'].max(),
value=df['Year'].min(),
step=None,
marks={str(Year): str(Year) for Year in df['Year'].unique()}
)
],
style={'width': '48%', 'display': 'inline-block'})
#app.callback(
Output('graph-with-slider', 'figure'),
[Input('year-slider', 'value'),
Input('xaxis-type','value'),
Input('cities','value')])
def update_figure(selected_year, axis_type, City):
if City=="All":
filtered_df = df
else:
filtered_df = df[df['City']==City]
filtered_df = filtered_df[filtered_df.Year == selected_year]
traces = []
for i in filtered_df.City.unique():
df_by_City = filtered_df[filtered_df['City'] == i]
traces.append(go.Scatter(
y=df_by_City['Native Country of Father'],
text=df_by_City['Native Country of Father'],
mode='markers',
opacity=0.7,
marker={
'size': 15,
'line': {'width': 0.5, 'color': 'white'}
},
name=i
))
return {
'data': traces,
'layout': go.Layout(
xaxis={'type': 'linear' if axis_type == 'Linear' else 'log',
'title': 'GDP Per Capita'},
yaxis={'title': 'Life Expectancy', 'range': [20, 90]},
margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
legend={'x': 0, 'y': 1},
hovermode='closest'
)
}
if __name__ =='__main__':
app.run_server(mode="external")
To get the dropdown working properly, you'll have to fix the value passed to options. What you have is:
options=[{'label': i, 'value': i} for i in list(df.City.unique()) + ['All']]
If you remove ['All'] and change the value prop, it should work. In order to have a value that selects everything, you need something like
options=[
{'label': i, 'value': i} for i in list(df.City.unique())
] + [{'label': 'All', 'value': 'All'}]
I'm building a dashboard (code below) and my goal is to show several key facts about the data on a country-level basis. For example, current population vs. average population of all countries, life expectation vs. average life expectation of all countries etc.
I don't want to display the graph when no country (i.e. no dropdown option) is selected. This should also be standard when first launching the dashboard. However, I receive an error message when either clearing the dropdown or setting the value to '' in the layout area.
Does anybody know any solution to this problem?
import pandas as pd
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
import plotly.express as px
import plotly.graph_objects as go
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
fig = go.Figure()
# create the Dash app
app = dash.Dash()
# set up app layout
app.layout = html.Div(children=[
html.H1(children='Demographic Statistics'),
dcc.Dropdown(id='country-dropdown',
options=[{'label': x, 'value': x}
for x in df.country.unique()],
value='Argentina',
multi=False, clearable=True),
dcc.Graph(id='indicators', figure=fig)
])
# set up the callback function
#app.callback(
Output('indicators', 'figure'),
[Input('country-dropdown', 'value')])
def display_demographic_statistics(selected_country):
filtered_country = df[df.country == selected_country]
pop_confirmed = df.loc[df['country'] == selected_country, 'pop'].iloc[0]
lifexp = df.loc[df['country'] == selected_country, 'lifeExp'].iloc[0]
average_confirmed = df["pop"].mean()
average_lifexp = df["lifeExp"].mean()
return {
'data': [go.Indicator(
mode='number+delta',
value=pop_confirmed,
delta={'reference': average_confirmed,
'position': 'right',
'valueformat': ',g',
'relative': False,
'font': {'size': 15}},
number={'valueformat': ',',
'font': {'size': 20},
},
domain={'y': [0, 1], 'x': [0, 1]})],
'layout': go.Layout(
title={'text': 'Demgraphic Statistics'},
grid = {'rows': 2, 'columns': 2, 'pattern': "independent"},
template = {'data' : {'indicator': [{
'mode' : "number+delta+gauge",
'delta' : {'reference': 90}}]}}
),
}
# Run local server
if __name__ == '__main__':
app.run_server(debug=True, use_reloader=False)
You could make the component with id='indicators' an html.Div and use the callback to update its children property as follows:
if the user selects a country from the dropdown, then the callback returns
a dcc.Graph with the indicators for the selected country,
if the user clears the dropdown, then the callback returns None (i.e. nothing).
Note also that the value of the dropdown when no selection has been made is None, not ''.
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
app = dash.Dash()
app.layout = html.Div(children=[
html.H1(children='Demographic Statistics'),
dcc.Dropdown(
id='country-dropdown',
options=[{'label': x, 'value': x} for x in df.country.unique()],
value=None,
multi=False,
clearable=True
),
html.Div(id='indicators')
])
#app.callback(
Output('indicators', 'children'),
[Input('country-dropdown', 'value')])
def display_demographic_statistics(selected_country):
if selected_country is not None:
pop_confirmed = df.loc[df['country'] == selected_country, 'pop'].iloc[0]
average_confirmed = df['pop'].mean()
return dcc.Graph(
figure=go.Figure(
data=go.Indicator(
mode='number+delta',
value=pop_confirmed,
delta={
'reference': average_confirmed,
'position': 'right',
'valueformat': ',g',
'relative': False,
'font': {'size': 15}
},
number={
'valueformat': ',',
'font': {'size': 20},
},
domain={
'y': [0, 1],
'x': [0, 1]
}
),
layout=go.Layout(
title={'text': 'Demgraphic Statistics'},
grid={'rows': 2, 'columns': 2, 'pattern': 'independent'},
template={'data': {'indicator': [{'mode': 'number+delta+gauge', 'delta': {'reference': 90}}]}}
)
)
)
else:
return None
if __name__ == '__main__':
app.run_server(host='127.0.0.1', debug=True)
Greetings = I'm trying to build multiple Dash (by Plotly) Apps in One Page. In other words, the user sees a data visualization on top of the page, scrolls down, sees some sample text, scrolls down and then sees another data visualization. The code runs but only the second data visualization populates (along with the sample text). Any help would be greatly appreciated.
Here is the sample code:
import plotly.plotly as py
import plotly.graph_objs as go
import numpy as np
import pandas as pd
import requests
import io
import re
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from app import server
app = dash.Dash('dash_36', sharing=True, url_base_pathname='/dash_36',
csrf_protect=False, server=server)
app.config['suppress_callback_exceptions']=True
df = pd.read_csv('app_8/main.csv')
colors = {
'background': '#111111',
'text': '#7FDBFF'
}
app.layout = html.Div([
html.A("Previous Chart: ", href='dash_16'),
html.A(" Next Chart:", href='dash_18'),
html.A(" Back to Main Page:",
href='https://ds.org/index'),
dcc.Graph(
id='Senators of the United States 115th Congress: '
'America ~ A Country Up For $ALE',
figure={
'data': [
go.Scatter(
x=df[df['party'] == i]['sector_total'],
y=df[df['party'] == i]['industry_total'],
#z=df[df['candidate_name'] == i]['contributor_total'],
text=df[df['party'] == i]['candidate_name'],
mode='markers',
opacity=0.7,
marker={
'size': 15,
'line': {'width': 0.5, 'color': 'white'}
},
name=i
) for i in df.party.unique()
],
'layout': go.Layout(
xaxis={'title': 'Sector Total'},
yaxis={'title': 'Industry Total'},
#margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
#legend={'x': 0, 'y': 1},
hovermode='closest',
title='Sector Total, Industry Total & Candidate Name by
Party',
plot_bgcolor= colors['background'],
paper_bgcolor=colors['background'],
height=700,
font= {
'color': colors['text'],
}
)
}
),
dcc.Markdown('''
# SAMPLE TEXT
# This is an <h1> tag
## This is an <h2> tag
###### This is an <h6> tag
'''),
dcc.Markdown('''
*This text will be italic*
_This will also be italic_
**This text will be bold**
__This will also be bold__
_You **can** combine them_
'''),
dcc.Graph(
id='Senators of the United States 115th Congress: '
'America ~ A Country Up For $ALE',
figure={
'data': [
go.Scatter(
x=df[df['contributor_name'] == i]
['contributor_individual'],
y=df[df['contributor_name'] == i]['contributor_pac'],
#z=df[df['candidate_name'] == i]['contributor_total'],
text=df[df['contributor_name'] == i]['candidate_name'],
mode='markers',
opacity=0.7,
marker={
'size': 15,
'line': {'width': 0.5, 'color': 'white'}
},
name=i
) for i in df.contributor_name.unique()
],
'layout': go.Layout(
xaxis={'title': 'Contributor Individual'},
yaxis={'title': 'Contributor PAC'},
#margin={'l': 10, 'b': 10, 't': 10, 'r': 10},
#legend={'x': 0, 'y': 1},
hovermode='closest',
title='Contributor Individual, Contributor PAC & Candidate
Name by Contributor Name',
plot_bgcolor= colors['background'],
paper_bgcolor=colors['background'],
height=700,
font= {
'color': colors['text'],
}
)
}
)
])
The idea is to have two different script for each dash and then use another script who makes the connection. You can follow this tutorial: multiple dash
At the end there is an example.