Explore Vizro
In this tutorial, you'll learn how to build an interactive dashboard with multiple pages, incorporating a wide range of Vizro's components. This tutorial should take about an hour to finish, so grab a coffee or tea and let's dive in! ☕
Note
If you're looking for a quick start to get up and running with Vizro, consider reviewing the first dashboard tutorial before diving into this one.
By the end of this tutorial, you have learned how to:
- Explore most of Vizro's components.
- Use the Vizro visual vocabulary to guide your chart creation.
- Design custom charts with Plotly Express.
- Develop multiple pages for the dashboard.
- Customize the layout of the pages.
- Add interactivity using filters and parameters.
- Add a logo and title to the dashboard.
- Customize the dashboard navigation.
This tutorial uses the tips dataset, which was collected by a waiter who recorded information about each tip he received over several months at a restaurant.
Here is a preview of the dashboard you'll build
1. Install Vizro or run on PyCafe
You can experiment with the code for this tutorial directly on PyCafe, so there's no need to install Vizro locally. We recommend starting with a blank Vizro project on PyCafe and copying the code snippets from this tutorial into it, to see how everything integrates. For more details, check out the PyCafe documentation.
If you prefer working in a Notebook or Python script
To work in a Notebook or locally using a Python script, you need to install Vizro.
Paste the code from the tutorial into a Notebook cell, run the Notebook, and evaluate it.
You will need to restart the kernel each time you run the code. Otherwise, you may encounter errors such as "Components must uniquely map..." because those components persist from the previous execution. As an alternative to restarting the kernel each time, you can add a cell containing from vizro import Vizro; Vizro._reset()
to the top of your Notebook and re-run it each time you re-run your code. With this method, there is no need to restart the Jupyter kernel.
If you prefer using Python scripts instead of Notebooks, follow these steps:
- Create a new script called
app.py
. - Copy the code above into the script.
- Navigate to the directory where
app.py
file is located using your terminal. - Run the script by executing the command
python app.py
.
Once the script is running, open your web browser and navigate to localhost:8050
to view the dashboard. To enable debug mode for hot reloading, add debug=True
inside the run() method at the end of your app.py
file:
Vizro().build(dashboard).run(debug=True)
2. Understand the basics
Before we dive in, let's quickly cover some basics:
At the top level, you'll be creating a Dashboard
. Here's what you can configure at the dashboard-level:
- Pages: You can add multiple pages; they are the building blocks of your dashboard.
- Navigation: You can customize navigation between those different pages.
- Title/Logo: You can add your own titles and logos.
For each Page
, you can additionally configure the following:
- Components: Add charts, tables, input/output interfaces, and more.
- Controls: Include filters and parameters.
- Layouts: Customize the placement of components within a page.
- Actions: Create interactions between components using actions.
3. Create a first page
In this section, you learn how to create a new Page
and store it in a variable called first_page
.
A Page
model is the foundation of any Vizro dashboard. It uses a set of components to display content. For a comprehensive list of all Vizro components, refer to the components overview page.
3.1. Add a table
To start, let's get an overview of the data by displaying it in a table using AgGrid. Follow these steps to create a page and add a table to it:
- Import the necessary packages and load the dataset.
- Create a
Page
and set itstitle
to"Data"
. - Add an
AgGrid
component to thecomponents
list. - Use the
dash_ag_grid
function inside thefigure
argument ofAgGrid
. - Provide details about the data source in the
footer
argument ofAgGrid
. - Add the newly created page to the list of
pages
in the Dashboard.
First Page
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M. (1995).
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
dashboard = vm.Dashboard(pages=[first_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
After running your code (either locally or on PyCafe), you can now view the dashboard (on localhost:8050
if you ran it locally, or on the right part of the screen if you are using PyCafe).
Take a moment to explore the data in the table. You can sort, filter, and search within the AgGrid
columns to better understand the dataset.
You'll notice a toggle in the top-right corner of the dashboard, enabling you to switch between dark and light themes. Try it out!
Great job! You've successfully created a first dashboard page!
4. Create a second page
4.1. Add a chart
Next, you'll learn how to add a second page to the dashboard, featuring charts and KPI (Key Performance Indicator) cards.
Vizro uses Graph
models and Plotly Express functions to create various types of charts. You can explore some of the available chart types and their code examples in the Vizro visual vocabulary.
Follow these steps to add a histogram to the page:
- Create a second
Page
and store it in a variable calledsecond_page
. Set itstitle
to"Summary"
. - Add a
Graph
to thecomponents
list. - Inside the
figure
argument of theGraph
, use the code for the px.histogram from the visual vocabulary. - Add the new page to the list of
pages
in theDashboard
by callingvm.Dashboard(pages=[first_page, second_page])
.
Second Page
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M. (1995).
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
vm.Graph(figure=px.histogram(tips, x="tip")),
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Notice that the charts are automatically stacked vertically in the order specified under components
, each taking up equal space. This is the default behavior in Vizro, but you'll learn how to customize the layout later!
Additionally, a page navigation menu has been added to the left side of the dashboard, enabling you to switch between the two pages we’ve created.
You'll also notice that the left-side menu can be collapsed to provide more space for the dashboard content. Give it a try!
4.2. Add KPI cards
You can combine and arrange various types of components
on a dashboard page. Refer to the components overview page for a comprehensive list of available components.
Let's add two KPI cards to the second page. Follow these steps:
- Add a
Figure
to the list ofcomponents
. - Inside the
figure
argument of theFigure
, use thekpi_card
function. - Configure your
kpi_card
by setting thevalue_column
,agg_func
,value_format
, andtitle
. To learn more about configuring KPI cards, check out our guide to KPI cards. - Repeat the above steps to add another KPI card to the page.
Add KPI Cards
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M. (1995).
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Graph(figure=px.histogram(tips, x="total_bill")),
vm.Graph(figure=px.histogram(tips, x="tip")),
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
4.3. Add tabs to switch views
You may not want to display both histograms simultaneously and instead prefer to switch between views. You can achieve this by using the Tabs
component. For more details, refer to Vizro's tabs user guide.
Let's place the two histograms in separate tabs. Follow these steps:
- Add each
Graph
to thecomponents
of aContainer
. - Set the
title
argument inside eachContainer
to the desired tab name. - Add the containers to the
tabs
list of theTabs
component. - Add the
Tabs
component to thecomponents
of thePage
.
Add Tabs
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M. (1995).
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
)
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Take a moment to switch between the tabs! 🕰️
As you explore the dashboard, you might notice that the current layout could use some adjustments. The histograms appear cramped, while the KPI cards have too much space. In the next section, you'll learn how to configure the layout and better arrange the components.
4.4. Configure the layout
By default, Vizro places each element in the order it was added to components
, and spaces them equally. You can use the Grid
to control the placement and size of components on the page. To learn more about how to configure layouts, check out How to use layouts.
In the following layout configuration, the layout is divided into four columns and four rows. The numbers in the grid correspond to the index of the components in the components
list.
- The first KPI card (0) is positioned at the top, occupying the first cell in the first row.
- The second KPI card (1) is positioned to the right of the first KPI card.
- There are two empty cells to the right of the KPI cards (-1).
- The
Tabs
component (2) is placed below the KPI cards, spanning all cells across the remaining three rows.
Run the code below to apply the layout to the dashboard page:
Code - Layout
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M (1995)
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
layout=vm.Grid(grid=[[0, 1, -1, -1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]),
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
)
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Much better, don't you think? The layout now provides sufficient space for the charts!
4.5. Add a filter
Filters enable you to interact with the dashboard by selecting specific data points to display.
To add a filter to the dashboard, follow these steps:
- Add a
Filter
to thecontrols
list of thePage
. - Specify the column to be filtered using the
column
argument of the Filter. - Change the
selector
in one of theFilters
to aChecklist
. For further customization, refer to the guide onHow to use selectors
.
Add a filter
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M (1995)
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
layout=vm.Grid(grid=[[0, 1, -1, -1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]),
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
)
],
controls = [vm.Filter(column="day"), vm.Filter(column="time", selector=vm.Checklist()), vm.Filter(column="size")]
)
dashboard = vm.Dashboard(pages=[first_page, second_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
You'll see that a Dropdown
is selected by default for categorical data, while a RangeSlider
is used for numerical data. Additionally, filters are applied to all components on the page.
If you want to apply a filter to specific components only, check out How to use filters.
Great work! You've just completed a second dashboard page and learned how to:
- Add a chart to a page using the visual vocabulary
- Add KPI cards to display summary statistics
- Add tabs to switch views
- Arrange components by customizing the layout
- Add a filter to interact with the dashboard
5. Create a third page
Now that you've learned how to create pages, add components, and configure layouts, you'll create a third page for the dashboard. This will give you the opportunity to practice your skills alongside learning some new concepts!
This page will feature a bar chart, a violin chart, and a heatmap and take inspiration from the Vizro visual vocabulary.
5.1. Add multiple charts
This step should feel familiar. Let's add all three charts to the page.
- Create a third
Page
and store it in a variable calledthird_page
. Set itstitle
to "Analysis". - Add three
Graph
models to thecomponents
of thePage
. - For each
Graph
, use thefigure
argument to provide one of the Plotly express functions:- px.violin (copy the code directly)
- px.bar (copy the code directly)
- px.density_heatmap (update the
data
,x
, andy
arguments to match the dataset)
- Provide a
title
for eachGraph
. - Add the new
Page
to the list ofpages
in the Dashboard.
Third page
third_page = vm.Page(
title="Analysis",
components=[
vm.Graph(
title="Where do we get more tips?",
figure=px.bar(tips, y="tip", x="day"),
),
vm.Graph(
title="Is the average driven by a few outliers?",
figure=px.violin(tips, y="tip", x="day", color="day", box=True),
),
vm.Graph(
title="Which group size is more profitable?",
figure=px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f"),
),
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page, third_page])
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M. (1995)
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
layout=vm.Grid(grid=[[0, 1, -1, -1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]),
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips",
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
),
],
controls=[
vm.Filter(column="day"),
vm.Filter(column="time", selector=vm.Checklist()),
vm.Filter(column="size"),
],
)
third_page = vm.Page(
title="Analysis",
components=[
vm.Graph(
title="Where do we get more tips?",
figure=px.bar(tips, y="tip", x="day"),
),
vm.Graph(
title="Is the average driven by a few outliers?",
figure=px.violin(tips, y="tip", x="day", color="day", box=True),
),
vm.Graph(
title="Which group size is more profitable?",
figure=px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f"),
),
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page, third_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Depending on your screen size, you may notice that the third chart is not visible. This issue can occur with Plotly charts when there isn't enough space to display them properly. Let's customize the layout again to allocate more space to the heatmap.
5.2. Configure the layout
This step should also feel familiar by now. Let's arrange the charts to provide more space for the heatmap.
In the following layout configuration, the layout is divided into two columns and two rows:
- The bar chart (0) and violin chart (1) are placed side by side in the first row.
- The heatmap (2) spans the entire second row.
Remember, the index corresponds to the order in which the components are added to the components
of the Page
.
Run the code below to apply the layout to the dashboard page:
Code - Layout
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M (1995)
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
layout=vm.Grid(grid=[[0, 1, -1, -1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]),
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
)
],
controls=[vm.Filter(column="day"), vm.Filter(column="time", selector=vm.Checklist()), vm.Filter(column="size")]
)
third_page = vm.Page(
title="Analysis",
layout=vm.Grid(grid=[[0, 1], [2, 2]]),
components=[
vm.Graph(
title="Where do we get more tips?",
figure=px.bar(tips, y="tip", x="day"),
),
vm.Graph(
title="Is the average driven by a few outliers?",
figure=px.violin(tips, y="tip", x="day", color="day", box=True),
),
vm.Graph(
title="Which group size is more profitable?",
figure=px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f"),
),
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page, third_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Fantastic work! The heatmap looks great, doesn't it?
5.3. Add a parameter
This section explains how to add a Parameter
to your dashboard. A Parameter
enables you to dynamically change a component's argument, making the dashboard more interactive. For more information on how to configure Parameters
, refer to the guide to parameters.
In this section, you learn how to switch the x
and color
arguments across all charts, enabling data analysis from different perspectives.
To add a parameter to the dashboard:
- Add a
Parameter
to thecontrols
of thePage
. - Assign an
id
to eachGraph
that the Parameter should target. - Define the parameter's
targets
using the formatcomponent-id.argument
. - Set the
selector
of the Parameter to aRadioItems
. - Provide options for the
RadioItems
selector.
Add a parameter
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M (1995)
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
layout=vm.Grid(grid=[[0, 1, -1, -1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]),
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
)
],
controls=[vm.Filter(column="day"), vm.Filter(column="time", selector=vm.Checklist()), vm.Filter(column="size")]
)
third_page = vm.Page(
title="Analysis",
layout=vm.Grid(grid=[[0, 1], [2, 2]]),
components=[
vm.Graph(
id="bar",
title="Where do we get more tips?",
figure=px.bar(tips, y="tip", x="day"),
),
vm.Graph(
id="violin",
title="Is the average driven by a few outliers?",
figure=px.violin(tips, y="tip", x="day", color="day", box=True),
),
vm.Graph(
id="heatmap",
title="Which group size is more profitable?",
figure=px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f"),
),
],
controls=[
vm.Parameter(
targets=["violin.x", "violin.color", "heatmap.x", "bar.x"],
selector=vm.RadioItems(
options=["day", "time", "sex", "smoker", "size"], value="day", title="Change x-axis inside charts:"
),
),
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page, third_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Take a moment to interact with the parameter. Note how the x-axis of all charts updates accordingly.
Isn't it amazing how effortlessly it is to shift the data analysis perspective now?
5.4. Add a custom chart
You may notice that the bar
chart has many inner lines. This happens because each line represents a unique data point when an unaggregated dataset is provided to px.bar
. To avoid this, you can aggregate the data before plotting. However, the aggregation needs to be dynamic, based on the parameter you added in the previous step.
This requires creating a custom chart with the following steps. For more information on when to create a custom chart, check out How to create custom charts.
- Create a function that takes the
data_frame
as input and returns a Plotly figure. - Decorate the function with the
@capture(graph)
decorator. - Inside the function, aggregate the data, provide a label for the chart, and update the bar width.
- Use this custom function in the
Graph
component instead ofpx.bar
.
Add custom chart
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
@capture("graph")
def bar_mean(data_frame, x, y):
df_agg = data_frame.groupby(x).agg({y: "mean"}).reset_index()
fig = px.bar(df_agg, x=x, y=y, labels={"tip": "Average Tip ($)"})
fig.update_traces(width=0.6)
return fig
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M (1995)
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
layout=vm.Grid(grid=[[0, 1, -1, -1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]),
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
)
],
controls=[vm.Filter(column="day"), vm.Filter(column="time", selector=vm.Checklist()), vm.Filter(column="size")]
)
third_page = vm.Page(
title="Analysis",
layout=vm.Grid(grid=[[0, 1], [2, 2]]),
components=[
vm.Graph(
id="bar",
title="Where do we get more tips?",
figure=bar_mean(tips, y="tip", x="day"),
),
vm.Graph(
id="violin",
title="Is the average driven by a few outliers?",
figure=px.violin(tips, y="tip", x="day", color="day", box=True),
),
vm.Graph(
id="heatmap",
title="Which group size is more profitable?",
figure=px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f"),
),
],
controls=[
vm.Parameter(
targets=["violin.x", "violin.color", "heatmap.x", "bar.x"],
selector=vm.RadioItems(
options=["day", "time", "sex", "smoker", "size"], value="day", title="Change x-axis inside charts:"
),
),
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page, third_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Fantastic job reaching this point! You've just completed the final dashboard page and learned how to:
- Add multiple charts
- Customize a layout
- Add a parameter to interact with the charts
- Add a custom chart to the dashboard
6. The final touches
Now that you've created all the dashboard pages, let's add a personal touch by including a title, logo, and customizing the navigation.
6.1. Add a title and logo
To add a title and logo to your dashboard, follow these steps:
- Set the
title
attribute of the Dashboard to "Tips Analysis Dashboard". - Download the
logo
from this link and save it in a folder namedassets
. - Place the
assets
folder in the same directory as yourapp.py/app.ipynb
file.
Your directory structure should look like this:
Add a dashboard title and logo
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
@capture("graph")
def bar_mean(data_frame, x, y):
df_agg = data_frame.groupby(x).agg({y: "mean"}).reset_index()
fig = px.bar(df_agg, x=x, y=y, labels={"tip": "Average Tip ($)"})
fig.update_traces(width=0.6)
return fig
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M (1995)
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
layout=vm.Grid(grid=[[0, 1, -1, -1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]),
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
)
],
controls=[vm.Filter(column="day"), vm.Filter(column="time", selector=vm.Checklist()), vm.Filter(column="size")]
)
third_page = vm.Page(
title="Analysis",
layout=vm.Grid(grid=[[0, 1], [2, 2]]),
components=[
vm.Graph(
id="bar",
title="Where do we get more tips?",
figure=bar_mean(tips, y="tip", x="day"),
),
vm.Graph(
id="violin",
title="Is the average driven by a few outliers?",
figure=px.violin(tips, y="tip", x="day", color="day", box=True),
),
vm.Graph(
id="heatmap",
title="Which group size is more profitable?",
figure=px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f"),
),
],
controls=[
vm.Parameter(
targets=["violin.x", "violin.color", "heatmap.x", "bar.x"],
selector=vm.RadioItems(
options=["day", "time", "sex", "smoker", "size"], value="day", title="Change x-axis inside charts:"
),
),
],
)
dashboard = vm.Dashboard(pages=[first_page, second_page, third_page], title="Tips Analysis Dashboard")
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
You should see the logo in the top-left corner of your dashboard header, with the title displayed next to it. If you can't see the logo, make sure the image is called logo
and is stored in the assets
folder. For more details on supported image formats, refer to the How to add a logo guide.
6.2. Customize the navigation
By default, a navigation panel on the left side enables users to switch between the pages. In this section, you'll learn how to customize it by using a navigation bar with icons instead.
The navigation bar will have two icons: one for the "Data" page and another for the "Summary" and "Analysis" pages.
To create a navigation bar, follow these steps:
- Set the
navigation
attribute of the Dashboard to a Navigation object. - Assign a NavBar object to the
nav_selector
attribute of theNavigation
. - Populate the
items
of the NavBar object with a list of NavLink objects. - Assign a NavBar object to the
nav_selector
attribute of theNavigation
. - Populate the
items
of the NavBar object with a list of NavLink objects. - Customize each NavLink object by setting its
label
,pages
, andicon
attributes.- The
label
controls the text displayed in the tooltip when hovering over the navigation icon. - The
pages
controls the pages included in the accordion navigation for that icon. - The
icon
sets the icon to display using the Material Design Icons library.
- The
Customize navigation
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
tips = px.data.tips()
@capture("graph")
def bar_mean(data_frame, x, y):
df_agg = data_frame.groupby(x).agg({y: "mean"}).reset_index()
fig = px.bar(df_agg, x=x, y=y, labels={"tip": "Average Tip ($)"})
fig.update_traces(width=0.6)
return fig
first_page = vm.Page(
title="Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(tips),
footer="""**Data Source:** Bryant, P. G. and Smith, M (1995)
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
],
)
second_page = vm.Page(
title="Summary",
layout=vm.Grid(grid=[[0, 1, -1, -1], [2, 2, 2, 2], [2, 2, 2, 2], [2, 2, 2, 2]]),
components=[
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="total_bill",
agg_func="mean",
value_format="${value:.2f}",
title="Average Bill",
)
),
vm.Figure(
figure=kpi_card(
data_frame=tips,
value_column="tip",
agg_func="mean",
value_format="${value:.2f}",
title="Average Tips"
)
),
vm.Tabs(
tabs=[
vm.Container(
title="Total Bill ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="total_bill")),
],
),
vm.Container(
title="Total Tips ($)",
components=[
vm.Graph(figure=px.histogram(tips, x="tip")),
],
),
],
)
],
controls=[vm.Filter(column="day"), vm.Filter(column="time", selector=vm.Checklist()), vm.Filter(column="size")]
)
third_page = vm.Page(
title="Analysis",
layout=vm.Grid(grid=[[0, 1], [2, 2]]),
components=[
vm.Graph(
id="bar",
title="Where do we get more tips?",
figure=bar_mean(tips, y="tip", x="day"),
),
vm.Graph(
id="violin",
title="Is the average driven by a few outliers?",
figure=px.violin(tips, y="tip", x="day", color="day", box=True),
),
vm.Graph(
id="heatmap",
title="Which group size is more profitable?",
figure=px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f"),
),
],
controls=[
vm.Parameter(
targets=["violin.x", "violin.color", "heatmap.x", "bar.x"],
selector=vm.RadioItems(
options=["day", "time", "sex", "smoker", "size"], value="day", title="Change x-axis inside charts:"
),
),
],
)
dashboard = vm.Dashboard(
pages=[first_page, second_page, third_page],
title="Tips Analysis Dashboard",
navigation=vm.Navigation(
nav_selector=vm.NavBar(
items=[
vm.NavLink(label="Data", pages=["Data"], icon="database"),
vm.NavLink(label="Charts", pages=["Summary", "Analysis"], icon="bar_chart"),
]
)
),
)
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Take a moment to explore the navigation bar! Hover over the icons to view the tooltip text, and click on them to navigate between the pages.
Congratulations on completing this tutorial!
You now have the skills to configure layouts, and add components and interactivity to Vizro dashboards across multiple navigable pages.
7. Find out more
After completing the tutorial, you have a solid understanding of the main elements of Vizro and how to bring them together to create dynamic and interactive data visualizations.
You can find out more about Vizro's components by reading the components overview page. To gain more in-depth knowledge about the usage and configuration details of individual controls, check out the guides dedicated to Filters, Parameters, and Selectors.
If you'd like to understand more about different ways to configure the navigation of your dashboard, head to Navigation.
Vizro doesn't end here; we've only covered the key features, but there's still much more to explore! You can learn:
- How to use actions for example, for chart interaction or custom controls.
- How to extend and customize Vizro dashboards by creating your own:
- How to add custom styling using static assets such as custom css or JavaScript files.
- How to customize your data connection
- How to create dashboards from
yaml
,dict
orjson
following the dashboard guide. - How to deploy your dashboard
- How to use Vizro-AI to create charts with GenAI