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. You can follow along using the written guide below or join in with the accompanying video tutorial.
This tutorial should take about half 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 quickstart tutorial before diving into this one.
By the end of this tutorial, you will 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
There's no need to install Vizro locally because you can experiment with the complete code for the tutorial directly on PyCafe in your browser. We recommend starting with a blank Vizro project on PyCafe and copying the code snippets from this tutorial into it, to build it up from scratch and see how it fits together.
For more information about working with Vizro on PyCafe, 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.pyfile 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 also 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. These steps create a page and add a table to it:
- Import the necessary packages and load the dataset.
- Create a
Pageand set itstitleto"Data". - Add an
AgGridcomponent to thecomponentslist. - Use the
dash_ag_gridfunction inside thefigureargument ofAgGrid. - Provide details about the data source in the
footerargument ofAgGrid. - Add the newly created page to the list of
pagesin the Dashboard model.
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.
In the top-right corner of the dashboard, you'll notice a toggle to switch between dark and light themes. Try it out!
3.2. Add an export data button
Next, you'll add a Button that lets users export the data currently shown in your dashboard.
This is an example of an action. Vizro provides several built-in actions, and you can also write your own custom actions.
These steps add an export data button:
- Add a
Buttonmodel to thecomponentslist and settext="Export Data". - Use the
actionsargument of theButtonto specify the built-inexport_dataaction.
Export Data Button
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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
dashboard = vm.Dashboard(pages=[first_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Click on the Button and see what happens! 📂
3.3. Configure the layout
Notice there is extra blank space below the button. In this step, you’ll learn how to improve the layout by arranging components more efficiently.
Vizro supports two layouts: Grid and Flex. To understand the differences between them, check out our guide on layouts.
By default, Vizro uses the Grid layout, which arranges components in the order they appear inside components and gives them equal space. However, in our case, we want the Button and AgGrid to only take up the space they need — not equal space.
To achieve this, we'll switch to the Flex layout and set a height for the AgGrid, as the default is 400px otherwise.
- In the
layoutargument of thePage, use theFlexlayout model vialayout = vm.Flex() - Specify
style= {"height": "600px"}inside thedash_ag_grid, as it would otherwise default to400px.
Use Flex 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
import vizro.actions as va
tips = px.data.tips()
first_page = vm.Page(
title="Data",
layout=vm.Flex(),
components=[
vm.AgGrid(
figure=dash_ag_grid(tips, style= {"height": "600px"}),
footer="""**Data Source:** Bryant, P. G. and Smith, M. (1995).
Practical Data Analysis: Case Studies in Business Statistics.
Homewood, IL: Richard D. Irwin Publishing.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
dashboard = vm.Dashboard(pages=[first_page])
Vizro().build(dashboard).run()
Run and edit this code in Py.Cafe
Looks much better already! Great job - you've successfully created your 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 that features 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.
These steps add a histogram to the page:
- Create a second
Pageand store it in a variable calledsecond_page. Set itstitleto"Summary". - Add a
Graphmodel to thecomponentslist. - Inside the
figureargument of theGraphmodel, use the code for the px.histogram from the visual vocabulary. - Add the new page to the list of
pagesin theDashboardmodel 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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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!
Also, 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.
These steps add two KPI cards to the second page:
- Add a
Figuremodel to the list ofcomponents. - Inside the
figureargument of theFigure, use thekpi_cardfunction. - Configure your
kpi_cardby 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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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 model. For more details, refer to Vizro's tabs user guide.
These steps place the two histograms in separate tabs:
- Add each
Graphto thecomponentsof aContainer. - Set the
titleargument inside eachContainerto the desired tab name. - Add the containers to the
tabslist of theTabscomponent. - Add the
Tabscomponent to thecomponentsof 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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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 adjustment. The histograms appear cramped, and 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
In this section, you'll customize the Grid layout to control the placement and size of components on the page.
The following layout configuration 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
Tabscomponent (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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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
You can use filters to interact with the dashboard by selecting specific data points to display.
These steps add a filter to the dashboard:
- Add a
Filtermodel to thecontrolslist of thePage. - Specify the column to be filtered using the
columnargument of the Filter model. - Change the
selectorin one of theFiltersto 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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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. Also, 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 made 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 takes inspiration from the Vizro visual vocabulary. It will feature:
- a bar chart
- a violin chart
- a heatmap
5.1. Add multiple charts
These steps should feel familiar, as they add three charts to the new page.
- Create a third
Pageand store it in a variable calledthird_page. Set itstitleto "Analysis". - Add three
Graphmodels to thecomponentsof thePage. - For each
Graph, use thefigureargument 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, andyarguments to match the dataset)
- Provide a
titlefor eachGraph. - Add the new
Pageto the list ofpagesin theDashboardmodel.
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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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 revise the layout to allocate more space for the heatmap.
5.2. Configure the layout
This step should also feel familiar by now. In the following new layout configuration, divide layout 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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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 you make the dashboard more interactive for the user by adding a parameter to dynamically change a component's argument.
In this section, you learn how to switch the x and color arguments across all charts, enabling data analysis from different perspectives.
These steps add a parameter to the dashboard:
- Add a
Parameterto thecontrolsof thePage. - Assign an
idto eachGraphthat the Parameter should target. - Define the parameter's
targetsusing the formatcomponent-id.argument. - Set the
selectorof the Parameter to aRadioItems. - Provide options for the
RadioItemsselector.
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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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. Notice how the x-axis of all charts updates dynamically based on your selection.
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. The following steps create a custom chart:
- Create a function that takes the
data_frameas 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
Graphcomponent instead ofpx.bar.
For more information on when to create a custom chart, check out How to create custom charts.
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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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. Finishing touches
Now that you've created all the dashboard pages, let's add a title and logo, and customize the navigation.
6.1. Add a title and logo
The following steps add a title and logo to the dashboard:
- Set the
titleattribute of the Dashboard model to "Tips Analysis Dashboard". - Download the
logofrom this link and save it in a folder namedassets. - Place the
assetsfolder in the same directory as yourapp.py/app.ipynbfile.
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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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 guide on how to add a logo.
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.
The following steps create a navigation bar:
- Set the
navigationattribute of the Dashboard model to a Navigation object. - Assign a NavBar object to the
nav_selectorattribute of theNavigation. - Populate the
itemsof the NavBar object with a list of NavLink objects. - Customize each NavLink object by setting its
label,pages, andiconattributes.- The
labelcontrols the text displayed in the tooltip when hovering over the navigation icon. - The
pagescontrols the pages included in the accordion navigation for that icon. - The
iconsets 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
import vizro.actions as va
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.""",
),
vm.Button(text="Export Data", actions=va.export_data()),
],
)
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 other built-in actions such as cross-filters
- 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,dictorjsonfollowing the dashboard guide. - How to deploy your dashboard
- How to use gen AI to assist in chart and dashboard creation.
- Vizro-MCP helps you build charts and dashboards that adhere to the Vizro design template. It is the easiest way to use a generative AI (gen AI) application to help you work with Vizro.
- Vizro-AI is also available as a means of building Vizro charts and dashboards with gen AI. You will need some technical knowledge, and an API key to use with a large language model (LLM).













