Beautiful Dashboards with Dash and Tailwindcss

Daniel Boadzie
Analytics Vidhya
Published in
5 min readJan 13, 2022

--

One of the best ways to share insights in Data is to use a dashboard to showcase them. That is one of the reasons why dashboard tools like Tableau, Data Studio, etc continue to trend. These tools provide a beautiful graphical interpretation of Data.

The only downside to these tools is that they are not flexible enough for you to create your designs. Some have themes for this kind of work but are limited.

We all love Tailwindcss; a utility first CSS framework and we love to use it for everything including creating beautiful dashboards.

Dash is a dashboarding framework from Plotly, with support for Python, R, and Julia. With Dash, you can create a custom responsive dashboard and style it with Tailwindcss. We will use the Python version of Dash in this article.

Poetry for Package Management

We will use poetry our our package manager for this project.

poetry init

and then install the dependencies with the following command:

poetry add dash pandas

Now, create a app.py file in your directory. This will be the entry point to our app.

We will start by importing our libraries:

import dash
import pandas as pd
import plotly.express as px
from dash import dcc, html

Notice that now you can now import dcc: Dash's core and html components from dash. This makes it easier than it was before and we are grateful for it.

Adding Tailwindcss

To add Tailwindcss to the app, all we need to do is to use Tailwindcss’s CDN as an external_script and pass it to our app instance.

app = dash.Dash(
__name__,
external_scripts=external_script,
)
app.scripts.config.serve_locally = True

Since, we want to focus on Tailwindcss and Dash in this article, we will use a toy data from the Dash website. We will use Pandas to manipulate the data. Of Course you can use your own data instead.

df = pd.DataFrame(
{
"Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
"Amount": [4.2, 1.0, 2.1, 2.32, 4.20, 5.0],
"City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"],
}
)


fruit_count = df.Fruit.count()
total_amt = df.Amount.sum()
city_count = df.City.count()
variables = df.shape[1]

Next, we will create some figures and use Tailwindcss to style our dashboard:

fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

fig1 = px.box(df, x="City", y="Amount", color="City")

app.layout = html.Div(
html.Div(
children=[
html.Div(
children=[
html.H1(children="Dash Tailwindcss Mastery", className=" py-3 text-5xl font-bold text-gray-800"),
html.Div(
children="""
Dash with Tailwindcss = 💝 .
""",
className="text-left prose prose-lg text-2xl py-3 text-gray-600",
),
],
className="w-full mx-14 px-16 shadow-lg bg-white -mt-14 px-6 container my-3 ",
),
html.Div(
html.Div(
children=[
html.Div(
children=[
f"${total_amt}",
html.Br(),
html.Span("Total Sales", className="text-lg font-bold ml-4"),
],
className=" shadow-xl py-4 px-14 text-5xl bg-[#76c893] text-white font-bold text-gray-800",
),
html.Div(
children=[
fruit_count,
html.Br(),
html.Span("Fruit Count", className="text-lg font-bold ml-4"),
],
className=" shadow-xl py-4 px-24 text-5xl bg-[#1d3557] text-white font-bold text-gray-800",
),
html.Div(
children=[
variables,
html.Br(),
html.Span("Variabales", className="inline-flex items-center text-lg font-bold ml-4"),
],
className=" shadow-xl py-4 px-24 text-5xl bg-[#646ffa] text-white font-bold text-gray-800",
),
html.Div(
children=[
city_count,
html.Br(),
html.Span("City Count", className="text-lg font-bold ml-4"),
],
className="w-full shadow-xl py-4 px-24 text-5xl bg-[#ef553b] text-white font-bold text-gray-800",
),
],
className="my-4 w-full grid grid-flow-rows grid-cols-1 lg:grid-cols-4 gap-y-4 lg:gap-[60px]",
),
className="flex max-w-full justify-between items-center ",
),
html.Div(
children=[
html.Div(
children=[
dcc.Graph(id="example-graph", figure=fig),
],
className="shadow-xl w-full border-3 rounded-sm",
),
html.Div(
children=[
dcc.Graph(id="example-graph1", figure=fig1),
],
className="w-full shadow-2xl rounded-sm",
),
],
className="grid grid-cols-1 lg:grid-cols-2 gap-4",
),
],
className="bg-[#ebeaee] flex py-14 flex-col items-center justify-center ",
),
className="bg-[#ebeaee] container mx-auto px-14 py-4",
)

Finally, we will run our code and check the output in the browser.


if __name__ == "__main__":
app.run_server(debug=True)

Run the App

To run, the app type the following command in your terminal:

poetry run python app.py

Navigate to http://127.0.0.1:8050/ and voila, your custom dashboard will greet you with smiles.

The full code for app looks like the following:

# Run this app with `python app.py` and
# visit http://127.0.0.1:8050/ in your web browser.

# Run this app with `python app.py` and
# visit http://127.0.0.1:8050/ in your web browser.

import dash
import pandas as pd
import plotly.express as px
from dash import dcc, html

external_script = ["https://tailwindcss.com/", {"src": "https://cdn.tailwindcss.com"}]

app = dash.Dash(
__name__,
external_scripts=external_script,
)
app.scripts.config.serve_locally = True

# 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", "Apples", "Oranges", "Bananas"],
"Amount": [4.2, 1.0, 2.1, 2.32, 4.20, 5.0],
"City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"],
}
)


fruit_count = df.Fruit.count()
total_amt = df.Amount.sum()
city_count = df.City.count()
variables = df.shape[1]

fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

fig1 = px.box(df, x="City", y="Amount", color="City")

app.layout = html.Div(
html.Div(
children=[
html.Div(
children=[
html.H1(children="Dash Tailwindcss Mastery", className=" py-3 text-5xl font-bold text-gray-800"),
html.Div(
children="""
Dash with Tailwindcss = 💝 .
""",
className="text-left prose prose-lg text-2xl py-3 text-gray-600",
),
],
className="w-full mx-14 px-16 shadow-lg bg-white -mt-14 px-6 container my-3 ",
),
html.Div(
html.Div(
children=[
html.Div(
children=[
f"${total_amt}",
html.Br(),
html.Span("Total Sales", className="text-lg font-bold ml-4"),
],
className=" shadow-xl py-4 px-14 text-5xl bg-[#76c893] text-white font-bold text-gray-800",
),
html.Div(
children=[
fruit_count,
html.Br(),
html.Span("Fruit Count", className="text-lg font-bold ml-4"),
],
className=" shadow-xl py-4 px-24 text-5xl bg-[#1d3557] text-white font-bold text-gray-800",
),
html.Div(
children=[
variables,
html.Br(),
html.Span("Variabales", className="inline-flex items-center text-lg font-bold ml-4"),
],
className=" shadow-xl py-4 px-24 text-5xl bg-[#646ffa] text-white font-bold text-gray-800",
),
html.Div(
children=[
city_count,
html.Br(),
html.Span("City Count", className="text-lg font-bold ml-4"),
],
className="w-full shadow-xl py-4 px-24 text-5xl bg-[#ef553b] text-white font-bold text-gray-800",
),
],
className="my-4 w-full grid grid-flow-rows grid-cols-1 lg:grid-cols-4 gap-y-4 lg:gap-[60px]",
),
className="flex max-w-full justify-between items-center ",
),
html.Div(
children=[
html.Div(
children=[
dcc.Graph(id="example-graph", figure=fig),
],
className="shadow-xl w-full border-3 rounded-sm",
),
html.Div(
children=[
dcc.Graph(id="example-graph1", figure=fig1),
],
className="w-full shadow-2xl rounded-sm",
),
],
className="grid grid-cols-1 lg:grid-cols-2 gap-4",
),
],
className="bg-[#ebeaee] flex py-14 flex-col items-center justify-center ",
),
className="bg-[#ebeaee] container mx-auto px-14 py-4",
)

if __name__ == "__main__":
app.run_server(debug=True)

Concluding Thoughts

Combining the power of Dash and the easy of Tailwindcss helps you to easily create beautiful custom dashboards you can use to share insight from your analysis with others. With little or no design skills, you can create dashboards that will get you hired or promoted.

--

--

Daniel Boadzie
Analytics Vidhya

Data scientist | AI Engineer |Software Engineering|Trainer|Svelte Entusiast. Find out more about my me here https://www.linkedin.com/in/boadzie/