Skip to content

Explore Vizro

In this tutorial, we walk through the process of creating a sophisticated dashboard. You'll be introduced to some Vizro components and learn how to create a pair of dashboard pages and configure their layout to suit the functionality you need. The example uses the gapminder data.

If you haven't yet done so, you may want to review the first dashboard tutorial before starting on this one.

1. Install Vizro and get ready to run your code

To get started with this tutorial, make sure you have installed Vizro, and can run the dashboard code within a Jupyter Notebook cell or from a Python script.

2. Create a first dashboard page

In this section we create a new Page called first_page.

The foundation of every Vizro dashboard is a Page object. A page uses a set of component types to display the content of the page. These components can be objects such as Graph, Table, Card, Button, Container, or Tabs.

2.1. Add the first figure

Vizro uses Graph objects and Plotly Express functions to build different types of figures.

The code below shows the steps necessary to add a box plot to the page:

  1. Add a Vizro Graph to the components list.
  2. Add a plotly.express.box figure to the list of components.

First component

from vizro import Vizro
import vizro.models as vm
import vizro.plotly.express as px

df = px.data.gapminder()
gapminder_data = (
        df.groupby(by=["continent", "year"]).
            agg({"lifeExp": "mean", "pop": "sum", "gdpPercap": "mean"}).reset_index()
    )

first_page = vm.Page(
    title="First Page",
    components=[
        vm.Graph(
            id="box_cont",
            figure=px.box(gapminder_data, x="continent", y="lifeExp", color="continent",
                            labels={"lifeExp": "Life Expectancy", "continent":"Continent"}),
        ),
    ],
)

dashboard = vm.Dashboard(pages=[first_page])
Vizro().build(dashboard).run()

FirstPage1

To see the dashboard in action

Paste the above code into a Notebook cell, run the Notebook, and evaluate it.


If you prefer to use Python scripts to Notebooks, here's how to try out the dashboard:

  1. Create a new script called app.py.
  2. Copy the code above into the script.
  3. Navigate to the directory where app.py file is located using your terminal.
  4. Run the script by executing the command python app.py.

Once the script is running, open your web browser and go to localhost:8050. You should see the dashboard page with the gapminder data displayed, as shown in the Result tab above.

As you can see from the code, the first_page is added to the Dashboard before building and running it with Vizro().build(dashboard).run(). Every Page that you want to display needs to be added to the Dashboard object.

2.2. Add further components

You can combine and arrange various types of components on a dashboard page. The components currently available are Card, Graph, and Button. For more information, refer to the components overview page to find the guide for each type.

The code below adds two components to the page:

  • A Card to insert markdown text into the dashboard.
  • A Graph to illustrate GDP development per continent since 1952 as a line graph.

Before you run this code in a Jupyter Notebook

If you are following this tutorial in a Jupyter Notebook, you need to restart the kernel each time you evaluate the code. If you do not, you will see error messages such as "Components must uniquely map..." because those components already exist from the previous evaluation.

Add components

vm.Card(
    text="""
        # First dashboard page
        This pages shows the inclusion of markdown text in a page and how components
        can be structured using Layout.
    """,
)
vm.Graph(
    id="line_gdp",
    figure=px.line(gapminder_data, x="year", y="gdpPercap", color="continent",
                    labels={"year": "Year", "continent": "Continent",
                    "gdpPercap":"GDP Per Cap"}, title=''),
)
from vizro import Vizro
import vizro.models as vm
import vizro.plotly.express as px

df = px.data.gapminder()
gapminder_data = (
        df.groupby(by=["continent", "year"]).
            agg({"lifeExp": "mean", "pop": "sum", "gdpPercap": "mean"}).reset_index()
    )

first_page = vm.Page(
    title="First Page",
    components=[
        vm.Card(
            text="""
                # First dashboard page
                This pages shows the inclusion of markdown text in a page and how components
                can be structured using Layout.
            """,
        ),
        vm.Graph(
            id="box_cont",
            figure=px.box(gapminder_data, x="continent", y="lifeExp", color="continent",
                            labels={"lifeExp": "Life Expectancy", "continent":"Continent"}),
        ),
        vm.Graph(
            id="line_gdp",
            figure=px.line(gapminder_data, x="year", y="gdpPercap", color="continent",
                            labels={"year": "Year", "continent": "Continent",
                            "gdpPercap":"GDP Per Cap"}, title=''),
        ),

    ],
)

dashboard = vm.Dashboard(pages=[first_page])
Vizro().build(dashboard).run()

FirstPage2

As you explore the dashboard, you may notice that the current layout could be further enhanced. The charts may appear cramped, while the text component has ample unused space. The next section explains how to configure the layout and arrange the components.

An introduction to Vizro-AI

In the example above, the code to create the line graph was generated using Vizro-AI. Vizro-AI enables you to use English, or other languages, to create interactive charts with Plotly by simplifying the process through use of a large language model. In essence, Vizro-AI generates code from natural language instructions so that you can add it into a Vizro dashboard, such as in the example above.

Find out more in the Vizro-AI documentation!

2.3. Configure the layout

By default, Vizro places each element in the order it was added to components list, and spaces them equally.

You can use the Layout object to specify the placement and size of components on the page. To learn more about how to configure layouts, check out How to use layouts.

The following layout configuration positions the text at the top and the two charts side by side, giving them more space relative to the text component:

grid=[ [0, 0],
       [1, 2],
       [1, 2],
       [1, 2] ]

Vizro interprets these values as follows. First, the configuration divides the available space into two columns and four rows. Each element in the list (such as [0,0]) represents one row of the grid layout:

image1

Each element in the components list is referenced with a unique number, and placed on the grid as visualized with the white frames. The Card, is referenced by 0 as it is the first element in the components list. It is placed in the first row and spans across both columns ([0, 0]). The two Graph objects, referenced by 1 and 2, are positioned next to each other and occupy a column each.

image2

The Graph objects occupy three rows, denoted by [1, 2], [1, 2], [1, 2], while the Card only occupies one row [0, 0]. As a result, the Graph objects occupy three-quarters of the vertical space, while the Card occupies one-quarter of it.

image3

Run the code below to apply the layout to the dashboard page:

Configure layout

layout=vm.Layout(grid=[[0, 0], [1, 2], [1, 2], [1, 2]])
from vizro import Vizro
import vizro.models as vm
import vizro.plotly.express as px

df = px.data.gapminder()
gapminder_data = (
        df.groupby(by=["continent", "year"]).
            agg({"lifeExp": "mean", "pop": "sum", "gdpPercap": "mean"}).reset_index()
    )

first_page = vm.Page(
    title="First Page",
    layout=vm.Layout(grid=[[0, 0], [1, 2], [1, 2], [1, 2]]),
    components=[
        vm.Card(
            text="""
                # First dashboard page
                This pages shows the inclusion of markdown text in a page and how components
                can be structured using Layout.
            """,
        ),
        vm.Graph(
            id="box_cont",
            figure=px.box(gapminder_data, x="continent", y="lifeExp", color="continent",
                            labels={"lifeExp": "Life Expectancy", "continent":"Continent"}),
        ),
        vm.Graph(
            id="line_gdp",
            figure=px.line(gapminder_data, x="year", y="gdpPercap", color="continent",
                            labels={"year": "Year", "continent": "Continent",
                            "gdpPercap":"GDP Per Cap"}),
            ),
    ],
)

dashboard = vm.Dashboard(pages=[first_page])
Vizro().build(dashboard).run()

FirstPage3

2.4. Add a control for dashboard interactivity

Controls add interactivity to the dashboard page and make it more dynamic, enabling users to have greater control and customization over the displayed data and components.

There are two types of control:

  • Filters enable users to filter a column of the underlying data.
  • Parameters enable users to change arguments or properties of the components, such as adjusting colors.

The guides for Filters and Parameters explain how to apply Filters and Parameters. For further customization, refer to the guide on selectors.

To link a control to a component, use the id assigned to the component, which is unique across all dashboard pages and serves as a reference to target it.

To illustrate, let's add a Filter on specific continents of the underlying gapminder data. The Filter requires the column argument, that denotes the target column to be filtered. Each control also has a targets parameter, to specify the data and components targeted by the control. For this dashboard, both charts are listed in the targets parameter, meaning that the filter is be applied to both charts. However, you can apply the Filter to only one specific chart if required.

Configure filter

controls=[
        vm.Filter(column="continent", targets=["box_cont", "line_gdp"]),
    ]
from vizro import Vizro
import vizro.models as vm
import vizro.plotly.express as px

df = px.data.gapminder()
gapminder_data = (
        df.groupby(by=["continent", "year"]).
            agg({"lifeExp": "mean", "pop": "sum", "gdpPercap": "mean"}).reset_index()
    )

first_page = vm.Page(
    title="First Page",
    layout=vm.Layout(grid=[[0, 0], [1, 2], [1, 2], [1, 2]]),
    components=[
        vm.Card(
            text="""
                # First dashboard page
                This pages shows the inclusion of markdown text in a page and how components
                can be structured using Layout.
            """,
        ),
        vm.Graph(
            id="box_cont",
            figure=px.box(gapminder_data, x="continent", y="lifeExp", color="continent",
                            labels={"lifeExp": "Life Expectancy", "continent":"Continent"}),
        ),
        vm.Graph(
            id="line_gdp",
            figure=px.line(gapminder_data, x="year", y="gdpPercap", color="continent",
                            labels={"year": "Year", "continent": "Continent",
                            "gdpPercap":"GDP Per Cap"}),
            ),
    ],
    controls=[
        vm.Filter(column="continent", targets=["box_cont", "line_gdp"]),
    ],
)

dashboard = vm.Dashboard(pages=[first_page])
Vizro().build(dashboard).run()

FirstPage4

Fantastic job! You have completed first dashboard page and gained valuable skills to create an initial figure on a dashboard page, add extra components, arrange them in a layout configuration, and set up an interactive dashboard control.

3. Create a second dashboard page

This section adds a second dashboard page and explains how to use controls and selectors. The new page is structured similarly to the page you created, but contains two charts that visualize the iris data.

The code below illustrates how to add the page, titled second_page to the dashboard by calling vm.Dashboard(pages=[first_page,second_page]). There are two Graph objects added to the list of components. To enable interactivity on those components, we add two Parameters to the list of controls.

In creating a Parameter object, you define the target it applies to. In the code below:

  • The first parameter enables the user to change the color mapping for the virginica category of the iris data, targeting both charts.
  • The second parameter adjusts the opacity of the first chart alone, through scatter_iris.opacity.

In general, targets for Parameters are set following the structure of component_id.argument. In certain cases, you may see a nested structure for the targets. An example of this is scatter_iris.color_discrete_map.virginica. A nested structure targets a specific attribute within a component. In this particular example, it specifies that only the color of the virginica flower type should be changed. More information on how to set targets for Parameters can be found in the how-to guide for parameters.

Second page

iris_data = px.data.iris()
second_page = vm.Page(
    title="Second Page",
    components=[
        vm.Graph(
            id="scatter_iris",
            figure=px.scatter(iris_data, x="sepal_width", y="sepal_length", color="species",
                color_discrete_map={"setosa": "#00b4ff", "versicolor": "#ff9222"},
                labels={"sepal_width": "Sepal Width", "sepal_length": "Sepal Length",
                        "species": "Species"},
            ),
        ),
        vm.Graph(
            id="hist_iris",
            figure=px.histogram(iris_data, x="sepal_width", color="species",
                color_discrete_map={"setosa": "#00b4ff", "versicolor": "#ff9222"},
                labels={"sepal_width": "Sepal Width", "count": "Count",
                        "species": "Species"},
            ),
        ),
    ],
    controls=[
        vm.Parameter(
            targets=["scatter_iris.color_discrete_map.virginica",
                        "hist_iris.color_discrete_map.virginica"],
            selector=vm.Dropdown(
                options=["#ff5267", "#3949ab"], multi=False, value="#3949ab", title="Color Virginica"),
            ),
        vm.Parameter(
            targets=["scatter_iris.opacity"],
            selector=vm.Slider(min=0, max=1, value=0.8, title="Opacity"),
        ),
    ],
)
from vizro import Vizro
import vizro.models as vm
import vizro.plotly.express as px

df = px.data.gapminder()
gapminder_data = (
        df.groupby(by=["continent", "year"]).
            agg({"lifeExp": "mean", "pop": "sum", "gdpPercap": "mean"}).reset_index()
    )
first_page = vm.Page(
    title="First Page",
    layout=vm.Layout(grid=[[0, 0], [1, 2], [1, 2], [1, 2]]),
    components=[
        vm.Card(
            text="""
                # First dashboard page
                This pages shows the inclusion of markdown text in a page and how components
                can be structured using Layout.
            """,
        ),
        vm.Graph(
            id="box_cont",
            figure=px.box(gapminder_data, x="continent", y="lifeExp", color="continent",
                            labels={"lifeExp": "Life Expectancy", "continent":"Continent"}),
        ),
        vm.Graph(
            id="line_gdp",
            figure=px.line(gapminder_data, x="year", y="gdpPercap", color="continent",
                            labels={"year": "Year", "continent": "Continent",
                            "gdpPercap":"GDP Per Cap"}),
            ),
    ],
    controls=[
        vm.Filter(column="continent", targets=["box_cont", "line_gdp"]),
    ],
)

iris_data = px.data.iris()
second_page = vm.Page(
    title="Second Page",
    components=[
        vm.Graph(
            id="scatter_iris",
            figure=px.scatter(iris_data, x="sepal_width", y="sepal_length", color="species",
                color_discrete_map={"setosa": "#00b4ff", "versicolor": "#ff9222"},
                labels={"sepal_width": "Sepal Width", "sepal_length": "Sepal Length",
                        "species": "Species"},
            ),
        ),
        vm.Graph(
            id="hist_iris",
            figure=px.histogram(iris_data, x="sepal_width", color="species",
                color_discrete_map={"setosa": "#00b4ff", "versicolor": "#ff9222"},
                labels={"sepal_width": "Sepal Width", "count": "Count",
                        "species": "Species"},
            ),
        ),
    ],
    controls=[
        vm.Parameter(
            targets=["scatter_iris.color_discrete_map.virginica",
                        "hist_iris.color_discrete_map.virginica"],
            selector=vm.Dropdown(
                options=["#ff5267", "#3949ab"], multi=False, value="#3949ab", title="Color Virginica"),
            ),
        vm.Parameter(
            targets=["scatter_iris.opacity"],
            selector=vm.Slider(min=0, max=1, value=0.8, title="Opacity"),
        ),
    ],
)

dashboard = vm.Dashboard(pages=[first_page,second_page])
Vizro().build(dashboard).run()

SecondPage

3.1. Customize with selectors

The code in the example above uses two different types of selector objects, namely Dropdown and Slider upon the Parameters. The selectors enable configuration of the controls to customize their behavior and appearance.

The first parameter is a Dropdown. It is configured with two available options, disables multi-selection, and has a default value set to blue. Users can choose a single option from the dropdown.

The second parameter is a Slider with a default value of 0.8. Users can adjust a value within the specified range of min=0 and max=1.

You can apply selectors to configure Filters and Parameters to fine-tune the behavior and appearance of the controls. The selectors currently available are as follows:

4. The final touches

This section puts everything together by adding a homepage to the example for navigation between the two separate pages.

For easy navigation within your dashboard, we'll create a page that serves as the entry point for the user. On this homepage are two Cards which serve as tiles that can be customized with a title, some text, and an image. These cards link to the subpages within your dashboard using their href attributes as href="/first-page" and href="/second-page". This establishes the navigation links from the homepage to each of the subpages.

Each page is added to the dashboard using the following line of code: vm.Dashboard(pages=[home_page, first_page, second_page]). This ensures that all the pages are accessible.

The code below illustrates a functional dashboard where you can navigate from the homepage to each of the subpages. Additionally, you can use the navigation panel on the left side to switch between the three pages.

Final dashboard

home_page = vm.Page(
    title="Homepage",
    components=[
        vm.Card(
            text="""
            ![](assets/images/icons/content/collections.svg#icon-top)

            ### First Page

            Exemplary first dashboard page.
            """,
            href="/first-page",
        ),
        vm.Card(
            text="""
            ![](assets/images/icons/content/features.svg#icon-top)

            ### Second Page

            Exemplary second dashboard page.
            """,
            href="/second-page",
        ),
    ],
)
dashboard = vm.Dashboard(pages=[home_page, first_page, second_page])

from vizro import Vizro
import vizro.models as vm
import vizro.plotly.express as px

home_page = vm.Page(
    title="Homepage",
    components=[
        vm.Card(
            text="""
            ![](assets/images/icons/content/collections.svg#icon-top)

            ### First Page

            Exemplary first dashboard page.
            """,
            href="/first-page",
        ),
        vm.Card(
            text="""
            ![](assets/images/icons/content/features.svg#icon-top)

            ### Second Page

            Exemplary second dashboard page.
            """,
            href="/second-page",
        ),
    ],
)

df = px.data.gapminder()
gapminder_data = (
        df.groupby(by=["continent", "year"]).
            agg({"lifeExp": "mean", "pop": "sum", "gdpPercap": "mean"}).reset_index()
    )
first_page = vm.Page(
    title="First Page",
    layout=vm.Layout(grid=[[0, 0], [1, 2], [1, 2], [1, 2]]),
    components=[
        vm.Card(
            text="""
                # First dashboard page
                This pages shows the inclusion of markdown text in a page and how components
                can be structured using Layout.
            """,
        ),
        vm.Graph(
            id="box_cont",
            figure=px.box(gapminder_data, x="continent", y="lifeExp", color="continent",
                            labels={"lifeExp": "Life Expectancy", "continent":"Continent"}),
        ),
        vm.Graph(
            id="line_gdp",
            figure=px.line(gapminder_data, x="year", y="gdpPercap", color="continent",
                            labels={"year": "Year", "continent": "Continent",
                            "gdpPercap":"GDP Per Cap"}),
            ),
    ],
    controls=[
        vm.Filter(column="continent", targets=["box_cont", "line_gdp"]),
    ],
)

iris_data = px.data.iris()
second_page = vm.Page(
    title="Second Page",
    components=[
        vm.Graph(
            id="scatter_iris",
            figure=px.scatter(iris_data, x="sepal_width", y="sepal_length", color="species",
                color_discrete_map={"setosa": "#00b4ff", "versicolor": "#ff9222"},
                labels={"sepal_width": "Sepal Width", "sepal_length": "Sepal Length",
                        "species": "Species"},
            ),
        ),
        vm.Graph(
            id="hist_iris",
            figure=px.histogram(iris_data, x="sepal_width", color="species",
                color_discrete_map={"setosa": "#00b4ff", "versicolor": "#ff9222"},
                labels={"sepal_width": "Sepal Width", "count": "Count",
                        "species": "Species"},
            ),
        ),
    ],
    controls=[
        vm.Parameter(
            targets=["scatter_iris.color_discrete_map.virginica",
                        "hist_iris.color_discrete_map.virginica"],
            selector=vm.Dropdown(
                options=["#ff5267", "#3949ab"], multi=False, value="#3949ab", title="Color Virginica"),
            ),
        vm.Parameter(
            targets=["scatter_iris.opacity"],
            selector=vm.Slider(min=0, max=1, value=0.8, title="Opacity"),
        ),
    ],
)

dashboard = vm.Dashboard(pages=[home_page, first_page, second_page])
Vizro().build(dashboard).run()

FinalPage

FinalPage1

FinalPage2

Congratulations on completing this tutorial! You have acquired the knowledge to configure layouts, add components, and implement interactivity in Vizro dashboards, working across two navigable pages.

Find out more

After completing the tutorial you now 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 the Vizro 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, and we only covered the key features, but there is still much more to explore! You can learn:

  • How to create you own components under custom components.
  • How to add custom styling using custom css.
  • How to use Actions for example, for chart interaction or custom controls.
  • How to create dashboards from yaml, dict or json following the dashboard guide.