- First time
- Every time
- How to
- Run the app
- See installed packages
- Install packages
- Launch Jupyter Notebook
- Change the app name in the browser title bar
- Change the app name in the navigation bar
- Change your name and contact info in the footer
- Change Bootswatch theme
- Change navigation bar colors
- Change home page text & button
- Add a page
- Remove a page
- Add an image
- Add a scikit-learn pipeline
- Exit the Pipenv shell
You need this software on your local computer:
- A terminal. If you're on Windows, I recommend Git Bash. If you're on Mac or Linux, a terminal is built in.
- Python 3. I recommend Anaconda Distribution.
- An IDE (Integrated Development Environment) or text editor. I recommend VS Code.
You also need to install Pipenv.
pip install pipenv
It automatically creates and manages a virtualenv for your projects, as well as adds/removes packages from your Pipfile as you install/uninstall packages. It also generates the ever-important Pipfile.lock, which is used to produce deterministic builds.
Create a new repository from this template.
Clone the repo onto your local computer:
git clone https://github.com/<you>/<repo>.git
Change directory into the repo:
cd <repo>
Create a virtual environment for this project, and install dependencies from Pipfile.lock:
pipenv install
Next, activate the Pipenv shell & run the app!
cd <repo>
pipenv shell
You can verify your virtual environment is active:
- Look at your command prompt prefix
- Run the command
which jupyter
✅ You should see this:
(your-repo-name) $ which jupyter
/Users/you/.local/share/virtualenvs/your-repo-name/bin/jupyter
❌ Not this:
(base) $ which jupyter
/anaconda3/bin/jupyter
python run.py
Then in your browser, go to http://localhost:8050/
Ctrl+C quits the app.
cat Procfile
You'll see output like this:
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
dash = "*"
dash-bootstrap-components = "*"
gunicorn = "*"
plotly = "*"
jupyter = "*"
pandas = "*"
[requires]
python_version = "3.7"
pipenv install <package>
For example, to install scikit-learn, category_encoders, xgboost, & Dash DAQ:
pipenv install scikit-learn category_encoders xgboost dash_daq
First, don't forget to activate the Pipenv shell. Then:
jupyter notebook
Edit app.py
file, app.title
string:
app.title = 'YOUR APP NAME' # appears in browser title bar
Edit run.py
file, navbar
object, brand
string:
navbar = dbc.NavbarSimple(
brand='YOUR APP NAME',
...
)
Edit run.py
file, footer
object:
footer = dbc.Container(
dbc.Row(
dbc.Col(
html.P(
[
html.Span('Your Name', className='mr-2'),
html.A(html.I(className='fas fa-envelope-square mr-1'), href='mailto:<you>@<provider>.com'),
html.A(html.I(className='fab fa-github-square mr-1'), href='https://github.com/<you>/<repo>'),
html.A(html.I(className='fab fa-linkedin mr-1'), href='https://www.linkedin.com/in/<you>/'),
html.A(html.I(className='fab fa-twitter-square mr-1'), href='https://twitter.com/<you>'),
],
className='lead'
)
)
)
)
Dash components use the className
parameter for CSS classes. The classes that start with fa
are for Font Awesome's icons. The classes with mr
stands for "margin right" and are from Bootstrap. The class lead
is also from Bootstrap to make "lead" paragraphs stand out more. You can add & remove CSS classes if you want.
Browse themes at https://bootswatch.com/
dbc.themes.BOOTSTRAP
dbc.themes.CERULEAN
dbc.themes.COSMO
dbc.themes.CYBORG
dbc.themes.DARKLY
dbc.themes.FLATLY
dbc.themes.JOURNAL
dbc.themes.LITERA
dbc.themes.LUMEN
dbc.themes.LUX
dbc.themes.MATERIA
dbc.themes.MINTY
dbc.themes.PULSE
dbc.themes.SANDSTONE
dbc.themes.SIMPLEX
dbc.themes.SKETCHY
dbc.themes.SLATE
dbc.themes.SOLAR
dbc.themes.SPACELAB
dbc.themes.SUPERHERO
dbc.themes.UNITED
dbc.themes.YETI
Edit app.py
file, external_stylesheets
parameter:
external_stylesheets = [
dbc.themes.BOOTSTRAP, # Bootswatch theme
'https://use.fontawesome.com/releases/v5.9.0/css/all.css', # for social media icons
]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
First, choose your Bootswatch theme.
Then, edit run.py
file, navbar
object, color
, light
& dark
parameters:
navbar = dbc.NavbarSimple(
...
color='light',
light=True,
dark=False
)
These parameters are explained in Dash Bootstrap Components docs:
color
(string, optional): Sets the color of the NavbarSimple. Main options are primary, light and dark, default light. You can also choose one of the other contextual classes provided by Bootstrap (secondary, success, warning, danger, info, white) or any valid CSS color of your choice (e.g. a hex code, a decimal code or a CSS color name)
light
(boolean, optional): Applies thenavbar-light
class to the NavbarSimple, causing text in the children of the Navbar to use dark colors for contrast / visibility.
dark
(boolean, optional): Applies thenavbar-dark
class to the NavbarSimple, causing text in the children of the Navbar to use light colors for contrast / visibility.
Edit pages/index.py
file, column1
object:
column1 = dbc.Col(
[
dcc.Markdown(
"""
## Value Proposition
Emphasize how the app will benefit users. Don't emphasize the underlying technology.
✅ RUN is a running app that adapts to your fitness levels and designs personalized workouts to help you improve your running.
❌ RUN is the only intelligent running app that uses sophisticated deep neural net machine learning to make your run smarter because we believe in ML driven workouts.
"""
),
dcc.Link(dbc.Button('Call To Action', color='primary'), href='/predictions')
],
md=4,
)
The RUN app example comes from Google's People + AI Guidebook.
1. Make a new file, pages/pagename.py
The code should have an object named layout
, with a Dash component assigned to it. For example:
import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from app import app
column1 = dbc.Col(
[
dcc.Markdown(
"""
## PAGE NAME
"""
),
],
md=4,
)
column2 = dbc.Col([])
layout = dbc.Row([column1, column2])
This layout is explained in Dash Bootstrap Components docs:
The Bootstrap grid has twelve columns. The layout of your app should be built as a series of rows of columns.
We set
md=4
indicating that on a 'medium' sized or larger screen the column should take up a third of the width. Since we don't specify behaviour on smaller size screens Bootstrap will allow the rows to wrap so as not to squash the content.
2. Edit run.py
file. Import <pagename>
from the pages
module.
from pages import index, predictions, insights, process, pagename
3. Edit run.py
file, display_page
function. Return <pagename>.layout
when pathname == '/<pagename>'
@app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
if pathname == '/':
return index.layout
elif pathname == '/predictions':
return predictions.layout
elif pathname == '/insights':
return insights.layout
elif pathname == '/process':
return process.layout
elif pathname == '/pagename':
return pagename.layout
else:
return dcc.Markdown('## Page not found')
4. Edit run.py
file, navbar
object. Add dbc.NavItem
& dcc.Link
objects for the page.
navbar = dbc.NavbarSimple(
children=[
dbc.NavItem(dcc.Link('Predictions', href='/predictions', className='nav-link')),
dbc.NavItem(dcc.Link('Insights', href='/insights', className='nav-link')),
dbc.NavItem(dcc.Link('Process', href='/process', className='nav-link')),
dbc.NavItem(dcc.Link('Page Name', href='/pagename', classname='nav-link')),
],
...
)
-
Edit
run.py
file,navbar
object. Remove thedbc.NavItem
&dcc.Link
objects for the page. -
Edit
run.py
file. Do not import<pagename>
from thepages
module. -
Edit
run.py
file,display_page
function. Remove the code block that returns<pagename>.layout
whenpathname == '/<pagename>'
-
Delete the file,
pages/<pagename>.py
-
Put the image file
<imagefile.extension>
in theassets/
directory. -
Edit the file,
pages/<pagename>.py
. Add a Dash HTML Img component in the layout:
html.Img(src='assets/imagefile.extension', className='img-fluid')
You can size and position images with Boostrap (for example, with the img-fluid
class) or just with CSS.
- Activate the Pipenv shell
- Install packages (scikit-learn, anything else you want)
- Launch Jupyter Notebook
- In your notebook, fit your pipeline. For example:
import category_encoders as ce
import plotly.express as px
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import make_pipeline
gapminder = px.data.gapminder()
X = gapminder[['year', 'continent']]
y = gapminder['lifeExp']
pipeline = make_pipeline(
ce.OneHotEncoder(use_cat_names=True),
LinearRegression()
)
pipeline.fit(X, y)
from joblib import dump
dump(pipeline, 'pipeline.joblib')
-
Copy the file
pipeline.joblib
into theassets/
directory. -
Edit the file,
pages/<pagename>.py
. Add this code at the top, to load the pipeline.
from joblib import load
pipeline = load('assets/pipeline.joblib')
- Add Dash components for inputs. For example:
column1 = dbc.Col(
[
dcc.Markdown('## Predictions', className='mb-5'),
dcc.Markdown('#### Year'),
dcc.Slider(
id='year',
min=1955,
max=2055,
step=5,
value=2020,
marks={n: str(n) for n in range(1960,2060,20)},
className='mb-5',
),
dcc.Markdown('#### Continent'),
dcc.Dropdown(
id='continent',
options = [
{'label': 'Africa', 'value': 'Africa'},
{'label': 'Americas', 'value': 'Americas'},
{'label': 'Asia', 'value': 'Asia'},
{'label': 'Europe', 'value': 'Europe'},
{'label': 'Oceania', 'value': 'Oceania'},
],
value = 'Africa',
className='mb-5',
),
],
md=4,
)
- Add Dash component for output. For example:
column2 = dbc.Col(
[
html.H2('Expected Lifespan', className='mb-5'),
html.Div(id='prediction-content', className='lead')
]
)
- Add callback to update output based on inputs. For example:
import pandas as pd
@app.callback(
Output('prediction-content', 'children'),
[Input('year', 'value'), Input('continent', 'value')],
)
def predict(year, continent):
df = pd.DataFrame(
columns=['year', 'continent'],
data=[[year, continent]]
)
y_pred = pipeline.predict(df)[0]
return f'{y_pred:.0f} years'
exit