Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] Enable parametrisation of dynamic data functions #482

Merged
merged 99 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from 84 commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
304f058
Initial attempt to remove component_to_data. Put data_frame string in…
antonymilne May 1, 2024
4161a09
POC of dynamic data function with Parameter argument
antonymilne May 1, 2024
b5cd1ae
Cache works well!
antonymilne May 1, 2024
f4a748b
Captured callable works but need to set name and qualname
antonymilne May 1, 2024
ca1624d
POC of Parameter(targets=["graph.data_frame.points"])
antonymilne May 1, 2024
7662b56
Simpler version that still works
antonymilne May 1, 2024
92e6c68
Address nested parameters of captured callable - possible but don't e…
antonymilne May 2, 2024
9442b2b
Revert "Address nested parameters of captured callable - possible but…
antonymilne May 2, 2024
ec988d7
Giving CC qualname and name works well
antonymilne May 2, 2024
8185617
Consider moving DM logic to CC - decided not to
antonymilne May 2, 2024
a980cec
Revert POC stuff and tidy
antonymilne May 2, 2024
8aa743d
Finish tidy
antonymilne May 2, 2024
e864356
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 2, 2024
96fc5ce
Finish tidy
antonymilne May 2, 2024
a9d26c6
Fix tests
antonymilne May 2, 2024
f7f07cc
Fix tests
antonymilne May 2, 2024
d4fbd26
Final tidy
antonymilne May 2, 2024
3b341fd
Merge branch 'main' into tidy/data-source-mapping
antonymilne May 2, 2024
365b5aa
Revert change to dev app
antonymilne May 2, 2024
2ba74cb
Add changelog
antonymilne May 2, 2024
bb9b9fa
Merge branch 'main' into tidy/data-source-mapping
antonymilne May 8, 2024
6582099
Add *args, **kwargs to load and many more tests
antonymilne May 14, 2024
04d2c11
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 14, 2024
abb7eeb
Version that sets __caching_id__ and __qualname__ for bound methods t…
antonymilne May 14, 2024
8321652
Change approach to use partial, so less hacking needed
antonymilne May 14, 2024
5a8aa65
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 14, 2024
867c5bf
Remove memoize decorator so it's done inside load method instead
antonymilne May 14, 2024
7e03672
Add debug logger to make testing easier
antonymilne May 14, 2024
0ee9729
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 14, 2024
700ea7c
Update vizro-core/tests/unit/vizro/integrations/kedro/fixtures/test_c…
antonymilne May 14, 2024
dbd1f62
Add changelog
antonymilne May 14, 2024
d57a2ec
Merge branch 'main' into feat/dynamic-data-load-with-args
antonymilne May 14, 2024
893b63f
Oops
antonymilne May 14, 2024
8c5d858
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 14, 2024
069ce26
Merge branch 'main' into feat/dynamic-data-load-with-args
antonymilne May 15, 2024
cab9740
Add update_wrapper and __module__ assignment for partial(data)
antonymilne May 15, 2024
850a62c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 15, 2024
d8269c8
First attempt at docs
antonymilne May 15, 2024
a49e660
First attempt at docs
antonymilne May 15, 2024
815393a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 15, 2024
c7746d6
Adding the _dev/app.py file to make testing easier for other reviewers
petar-qb May 17, 2024
03e24a9
Main merged into feature branch
petar-qb May 17, 2024
a28e544
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 17, 2024
11b2d02
Linting
petar-qb May 17, 2024
e6511cb
Merge branch 'feat/dynamic-data-load-with-args' of https://github.com…
petar-qb May 17, 2024
3fa57d4
Merge branch 'feat/dynamic-data-load-with-args' of https://github.com…
petar-qb May 17, 2024
8ef927d
Fix docs
antonymilne May 15, 2024
10f2545
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 20, 2024
0d6f58b
Add DynamicData function arguments parametrisation + export_data acti…
petar-qb May 20, 2024
853b798
Merge branch 'feat/parametrise-dynamic-data' of https://github.com/mc…
petar-qb May 20, 2024
70587e8
Minor Parameter validation added
petar-qb May 20, 2024
4c0ed90
Merge branch 'main' into feat/parametrise-dynamic-data
antonymilne May 20, 2024
cbe7d16
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 20, 2024
f4d369f
Docs and demo_example fixed
petar-qb May 21, 2024
2f08331
Parameter data_frame action test added
petar-qb May 21, 2024
f4b5cf9
Linting
petar-qb May 21, 2024
b463bc1
Add new parameter data_frame test
petar-qb May 22, 2024
773e8af
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 22, 2024
7078134
Fixing docs examples
petar-qb May 23, 2024
369dc9b
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/pa…
petar-qb May 23, 2024
a838c98
Fix loading iris in example and minor docs changes to include info ab…
petar-qb May 23, 2024
3907c4a
Merge main into the feature branch
petar-qb May 23, 2024
7ea420e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 23, 2024
92120e0
New _dev/app example
petar-qb May 23, 2024
d3d32e8
Conflict solved
petar-qb May 23, 2024
2a1e8be
More representative _dev/app.py example
petar-qb May 23, 2024
a658e43
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 23, 2024
183fd22
A small refactoring in _callback_mapping.py
petar-qb May 23, 2024
32ee7c7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 23, 2024
afd91c6
Refactor _actions_utils and minor rewording
antonymilne May 23, 2024
7f17980
Update docs
antonymilne May 23, 2024
2a7620d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 23, 2024
b6bf444
Add changelog
antonymilne May 23, 2024
99ef1fe
Update vizro-core/docs/pages/user-guides/actions.md
antonymilne May 23, 2024
2cf4ff4
Improve test_multiple_data_frame_parameters_multiple_targets so it te…
antonymilne May 23, 2024
80238ec
Gif added
petar-qb May 23, 2024
e192e68
Merge branch 'feat/parametrise-dynamic-data' of https://github.com/mc…
petar-qb May 23, 2024
ce01152
More linting
petar-qb May 23, 2024
1fefdfd
Fixing vale errors
petar-qb May 23, 2024
f9e560f
One test fixed
petar-qb May 23, 2024
4242a32
Unit tests refactoring
petar-qb May 23, 2024
e64c978
More tests refactoring
petar-qb May 23, 2024
ac599a2
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/pa…
petar-qb May 23, 2024
35478b6
Final refactoring
petar-qb May 23, 2024
e513015
Adjusting schemas
petar-qb May 24, 2024
a8f8cae
Update vizro-core/docs/pages/user-guides/actions.md
petar-qb May 24, 2024
e62370e
Update vizro-core/docs/pages/user-guides/custom-charts.md
petar-qb May 24, 2024
d13a060
Update vizro-core/docs/pages/user-guides/data.md
petar-qb May 24, 2024
ff5504b
Minor docs and dev/app.py changes
petar-qb May 24, 2024
4fb0265
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/pa…
petar-qb May 27, 2024
17d5d9f
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/pa…
petar-qb May 28, 2024
a0d889e
Add 'test_data_frame_parameters_one_target' test
petar-qb May 28, 2024
f32b538
Minor docs changes
petar-qb May 28, 2024
1a646f1
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/pa…
petar-qb May 28, 2024
bd6b0b8
Add new changelog file
petar-qb May 28, 2024
f93886e
Minor docs change
petar-qb May 28, 2024
c69deb2
Minor docs change
petar-qb May 28, 2024
2bc4dfc
Minor docs change
petar-qb May 28, 2024
2815ea6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions .vale/styles/Microsoft/ignore.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,7 @@ Plotly's
Gunicorn
dataframe
streamlit
memoization
setosa
versicolor
virginica
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Highlights ✨

- A bullet item for the Highlights ✨ category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX ([#1](https://github.com/mckinsey/vizro/pull/1))
- Enable dynamic data parametrization, so that different data can be loaded while the dashboard is running ([#482](https://github.com/mckinsey/vizro/pull/482))
petar-qb marked this conversation as resolved.
Show resolved Hide resolved

-->
<!--
### Removed

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions vizro-core/docs/pages/user-guides/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ The below sections are guides on how to use pre-defined action functions.
To enable downloading data, you can add the [`export_data`][vizro.actions.export_data] action function to the [`Button`][vizro.models.Button] component. Hence, as
a result, when a dashboard user now clicks the button, all data on the page will be downloaded.

!!! info
petar-qb marked this conversation as resolved.
Show resolved Hide resolved

When data from a [custom chart](custom-charts.md) is exported then the content of the `data_frame` input argument is what will be exported. Any transformations to the `data_frame` done inside the chart function will not be reflected in the exported data.
petar-qb marked this conversation as resolved.
Show resolved Hide resolved


!!! example "`export_data`"

=== "app.py"
Expand Down
3 changes: 2 additions & 1 deletion vizro-core/docs/pages/user-guides/custom-charts.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ def minimal_example(data_frame:pd.DataFrame=None):

Building on the above, there are several routes one can take. The following examples are guides on the most common custom requests, but also serve as an illustration of more general principles.

If you wish to alter the data contained in the `data_frame` argument then you should also consider using a [Filter](filters.md) or [parametrized data loading](data.md/#parametrize-data-loading) and [dynamic data](data.md/#dynamic-data). The `data_frame` argument input to a custom chart contains the data after filters and parameters have been applied.
petar-qb marked this conversation as resolved.
Show resolved Hide resolved

!!! tip

Custom charts can be targeted by [Filters](filters.md) or [Parameters](parameters.md) without any additional configuration. We will showcase both possibilities in the following examples. In particular the `Parameters` in combination with custom charts can be highly versatile in achieving custom functionality.


## Enhanced `plotly.express` chart with reference line

The below examples shows a case where we enhance an existing `plotly.express` chart. We add a new argument (`hline`), that is used to draw a grey reference line at the height determined by the value of `hline`. The important thing to note is that we then
Expand Down
85 changes: 80 additions & 5 deletions vizro-core/docs/pages/user-guides/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ The below example uses the Iris data saved to a file `iris.csv` in the same dire
page = vm.Page(
title="Static data example",
components=[
vm.Graph(figure=px.box("iris", x="species", y="petal_width", color="species")),
vm.Graph(figure=px.box(iris, x="species", y="petal_width", color="species")),
]
)

Expand Down Expand Up @@ -137,7 +137,6 @@ Unlike static data, dynamic data cannot be supplied directly into the `data_fram

The example below shows how data is fetched dynamically every time the page is refreshed. When you run the code and refresh the page the function `load_iris_data` is re-run, which returns different data each time. The example uses the Iris data saved to a file `iris.csv` in the same directory as `app.py`. This data can be generated using `px.data.iris()` or [downloaded](../../assets/user_guides/data/iris.csv).


!!! example "Dynamic data"
=== "app.py"
```py
Expand Down Expand Up @@ -167,7 +166,7 @@ The example below shows how data is fetched dynamically every time the page is r
```

1. `iris` is a pandas DataFrame created by reading from the CSV file `iris.csv`.
2. To demonstrate that dynamic data can change when the page is refreshed, select 30 points at random. This simulates what would happen if your file `iris.csv` were constantly changing.
2. To demonstrate that dynamic data can change when the page is refreshed, select 50 points at random. This simulates what would happen if your file `iris.csv` were constantly changing.
3. To use `load_iris_data` as dynamic data it must be added to the data manager. You should **not** actually call the function as `load_iris_data()`; doing so would result in static data that cannot be reloaded.
4. Dynamic data is referenced by the name of the data source `"iris"`.

Expand Down Expand Up @@ -217,8 +216,6 @@ In a development environment the easiest way to enable caching is to use a [simp
Vizro().build(dashboard).run()
```



By default, when caching is turned on, dynamic data is cached in the data manager for 5 minutes. A refresh of the dashboard within this time interval will fetch the pandas DataFrame from the cache and _not_ re-run the data loading function. Once the cache timeout period has elapsed, the next refresh of the dashboard will re-execute the dynamic data loading function. The resulting pandas DataFrame will again be put into the cache and not expire until another 5 minutes has elapsed.

If you would like to alter some options, such as the default cache timeout, then you can specify a different cache configuration:
Expand Down Expand Up @@ -268,3 +265,81 @@ data_manager["slow_expire_data"].timeout = 60 * 60
data_manager["no_expire_data"] = load_iris_data
data_manager["no_expire_data"].timeout = 0
```

### Parametrize data loading

You can supply arguments to your dynamic data loading function that can be modified from the dashboard. For example, if you are handling big data then you might like to load on demand only one chunk of the data.
petar-qb marked this conversation as resolved.
Show resolved Hide resolved

To add a parameter to control a dynamic data source, do the following:

- add the appropriate argument to your dynamic data function and specify a default value for the argument.
petar-qb marked this conversation as resolved.
Show resolved Hide resolved
- give an `id` to all components that have the data source you wish to alter through a parameter.
- [add a parameter](parameters.md) with `targets` of the form `<target_component_id>.data_frame.<dynamic_data_argument>` and a suitable [selector](selectors.md).

For example, let us extend the [dynamic data example](#dynamic-data) above to show how the `load_iris_data` can take an argument `number_of_points` controlled from the dashboard with a [`Slider`][vizro.models.Slider].

!!! example "Parametrized dynamic data"
=== "app.py"
```py hl_lines="8 10 20-23"
from vizro import Vizro
import pandas as pd
import vizro.plotly.express as px
import vizro.models as vm

from vizro.managers import data_manager

def load_iris_data(number_of_points=10): # (1)!
iris = pd.read_csv("iris.csv") # (2)!
return iris.sample(number_of_points) # (3)!

data_manager["iris"] = load_iris_data # (4)!

page = vm.Page(
title="Update the chart on page refresh",
components=[
vm.Graph(id="graph", figure=px.box("iris", x="species", y="petal_width", color="species")) # (5)!
maxschulz-COL marked this conversation as resolved.
Show resolved Hide resolved
],
controls=[
vm.Parameter(
targets=["graph.data_frame.number_of_points"], # (6)!
selector=vm.Slider(min=1, max=20, step=1, value=10),
)
],
)

dashboard = vm.Dashboard(pages=[page])

Vizro().build(dashboard).run()
```

1. `load_iris_data` now takes a single argument, `number_of_points`, with a default value of 10.
petar-qb marked this conversation as resolved.
Show resolved Hide resolved
2. `iris` is still a pandas DataFrame created by reading from the CSV file `iris.csv`.
3. Sample points at random, where `number_of_points` gives the number of points selected.
4. To use `load_iris_data` as dynamic data it must be added to the data manager. You should **not** actually call the function as `load_iris_data()` or `load_iris_data(number_of_points=...)`; doing so would result in static data that cannot be reloaded.
5. Give the `vm.Graph` component `id="graph"` so that the `vm.Parameter` can target it. Dynamic data is referenced by the name of the data source `"iris"`.
6. Create a `vm.Parameter` to target the `number_of_points` argument for the `data_frame` used in `graph`.

=== "Result"
[![ParametrizedDynamicData]][ParametrizedDynamicData]

[ParametrizedDynamicData]: ../../assets/user_guides/data/parametrized_dynamic_data.gif

Parametrized data loading is compatible with [caching](#configure-cache). The cache uses [memoization](https://flask-caching.readthedocs.io/en/latest/#memoization), so that the dynamic data function's arguments are included in the cache key. This means that, for example `load_iris_data(number_of_points=10)` is cached independently of `load_iris_data(number_of_points=20)`.
petar-qb marked this conversation as resolved.
Show resolved Hide resolved

!!! warning

You should always [treat the content of user input as untrusted](https://community.plotly.com/t/writing-secure-dash-apps-community-thread/54619). For example, you should not expose as a parameter a filepath to load without passing it through a function like [`werkzeug.utils.secure_filename`](https://werkzeug.palletsprojects.com/en/3.0.x/utils/#werkzeug.utils.secure_filename); otherwise you might enable a user to access arbitrary files on your server.
petar-qb marked this conversation as resolved.
Show resolved Hide resolved

It is not possible to pass [nested parameters](parameters.md#nested-parameters) to dynamic data. You can only target top-level arguments of the data loading function and not address nested keys in a dictionary.

### Filter update limitation

If your dashboard includes a [filter](filters.md) then the values shown on a filter's [selector](selectors.md) _do not_ update while the dashboard is running. This is a known limitation that will be lifted in future releases, but if is problematic for you already then [raise an issue on our GitHub repo](https://github.com/mckinsey/vizro/issues/).

This limitation is why all arguments of your dynamic data loading function must have a default value. Regardless of the value of the `vm.Parameter` selected in the dashboard, these default parameter values are used when the `vm.Filter` is built. This determines the type of selector used in a filter and the options shown, which cannot currently be changed while the dashboard is running.

Although a selector is automatically chosen for you in a filter when your dashboard is built, remember that [you can change this choice](filters.md#changing-selectors). For example, we could ensure that a dropdown always contains the options "setosa", "versicolor" and "virginica" by explicitly specifying your filter as follows.

```py
vm.Filter(column="species", selector=vm.Dropdown(options=["setosa", "versicolor", "virginica"])
```
2 changes: 1 addition & 1 deletion vizro-core/docs/pages/user-guides/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Currently available selectors are [`Checklist`][vizro.models.Checklist], [`Dropd
vm.Graph(figure=px.scatter(iris, x="sepal_length", y="petal_width")),
],
controls=[
vm.Filter(column="species",selector=vm.RadioItems()),
vm.Filter(column="species", selector=vm.RadioItems()),
],
)

Expand Down
6 changes: 5 additions & 1 deletion vizro-core/docs/pages/user-guides/parameters.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# How to use parameters

This guide shows you how to add parameters to your dashboard. One main way to interact with the charts/components on your page is by changing the parameters of the underlying function that creates the chart/component.
This guide shows you how to add parameters to your dashboard. One main way to interact with the charts/components on your page is by changing the parameters of the underlying function (`figure` argument) that creates the chart/component. Parameters can also be used to [modify the data loaded into the dashboard itself](data.md/#parametrize-data-loading).

The [`Page`][vizro.models.Page] model accepts the `controls` argument, where you can enter a [`Parameter`][vizro.models.Parameter] model. For example, if the charting function has a `title` argument, you could configure a parameter that enables the user to select the chart title with a dropdown.

Expand Down Expand Up @@ -177,3 +177,7 @@ If you want to change nested parameters, you can specify the `targets` argument
In the above example, the object passed to the function argument `color_discrete_map` is a dictionary which maps the different flower species to fixed colors (for example, `{"virginica":"blue"}`). In this case, only the value `blue` should be changed instead of the entire dictionary. This can be achieved by specifying a target as `scatter.color_discrete_map.virginica`.

Note that in the above example, one parameter affects multiple targets.

## Dynamic data parameters

If you use [dynamic data](data.md/#dynamic-data) that can be updated while the dashboard is running then you can pass parameters to the dynamic data function to alter the data loaded into your dashboard. For detailed instructions, refer to the section on [parametrized data loading](data.md/#parametrize-data-loading).
110 changes: 80 additions & 30 deletions vizro-core/examples/_dev/app.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,98 @@
"""Dev app to try things out."""
"""Example to show dashboard configuration."""

import numpy as np
import vizro.models as vm
import vizro.plotly.express as px
from flask_caching import Cache
from vizro import Vizro
from vizro.tables import dash_data_table
from vizro.actions import export_data
from vizro.managers import data_manager

df = px.data.gapminder()

dropdown_column = "Label"
dropdown_options = ["-- A --", "-- B --", "-- C --"]
# Note need to specify default value if have Filter since that calls data load function
# Then have problem that filter options don't get updated when data source changes
def load_iris_data(points=1, additional_points=1):
"""Load iris data."""
iris = px.data.iris()
return iris.sample(points + additional_points)

# Add a 'Label' column to the data where options are randomly selected between 'A', 'B', 'C'
df[dropdown_column] = np.random.choice(dropdown_options, size=len(df))

# Drop the 'iso_alpha' and 'iso_num' columns
df.drop(["iso_alpha", "iso_num"], axis=1, inplace=True)
data_manager["iris"] = load_iris_data

# SimpleCache
data_manager.cache = Cache(config={"CACHE_TYPE": "SimpleCache"})

page = vm.Page(
title="Table Page",
# RedisCache
# data_manager.cache = Cache(
# config={"CACHE_TYPE": "RedisCache", "CACHE_REDIS_HOST": "localhost", "CACHE_REDIS_PORT": 6379}
# )

# Timeout
data_manager["iris"].timeout = 30


# TEST CASE:
# There are 2 Parameters per page that control the number of points and additional points.
# Set all of them to same number and see that the output for all of them will be the same if cache is configured,
# otherwise the output will be different.

page_1 = vm.Page(
title="My first page",
components=[
vm.Table(
title="Table",
figure=dash_data_table(
data_frame=df,
columns=[
{"name": i, "id": i, "presentation": "dropdown"} if i == dropdown_column else {"name": i, "id": i}
for i in df.columns
],
editable=True,
dropdown={
dropdown_column: {
"options": [{"label": i, "value": i} for i in dropdown_options],
"clearable": False,
},
},
),
vm.Graph(
id="graph_1", figure=px.scatter(data_frame="iris", x="sepal_length", y="petal_width", color="species")
),
vm.Graph(
id="graph_2", figure=px.scatter(data_frame="iris", x="sepal_length", y="petal_width", color="species")
),
vm.Button(text="Export", actions=[vm.Action(function=export_data())]),
],
controls=[
vm.Parameter(
targets=["graph_1.x", "graph_2.x"], selector=vm.RadioItems(options=["sepal_length", "sepal_width"])
),
vm.Parameter(
targets=["graph_1.data_frame.points", "graph_1.data_frame.additional_points"],
selector=vm.Slider(title="Graph 1 points / Graph 1 additional_points", min=1, max=10, step=1),
),
vm.Parameter(
targets=["graph_2.data_frame.points", "graph_2.data_frame.additional_points"],
selector=vm.Slider(title="Graph 2 points / Graph 2 additional_points", min=1, max=10, step=1),
),
vm.Filter(column="species", selector=vm.Dropdown(options=["setosa", "versicolor", "virginica"])),
],
)

page_2 = vm.Page(
title="My second page",
components=[
vm.Graph(
id="graph_second_1",
figure=px.scatter(data_frame="iris", x="sepal_length", y="petal_width", color="species"),
),
vm.Graph(
id="graph_second_2",
figure=px.scatter(data_frame="iris", x="sepal_length", y="petal_width", color="species"),
),
vm.Button(text="Export", actions=[vm.Action(function=export_data())]),
],
controls=[
vm.Parameter(
targets=["graph_second_1.x", "graph_second_2.x"],
selector=vm.RadioItems(options=["sepal_length", "sepal_width"]),
),
vm.Parameter(
targets=["graph_second_1.data_frame.points", "graph_second_2.data_frame.points"],
selector=vm.Slider(title="Graph 1 points / Graph 2 points", min=1, max=10, step=1),
),
vm.Parameter(
targets=["graph_second_1.data_frame.additional_points", "graph_second_2.data_frame.additional_points"],
selector=vm.Slider(title="Graph 1 additional_points / Graph 2 additional_points", min=1, max=10, step=1),
),
vm.Filter(column="species", selector=vm.Dropdown(options=["setosa", "versicolor", "virginica"])),
],
controls=[vm.Filter(column="continent")],
)

dashboard = vm.Dashboard(pages=[page])
dashboard = vm.Dashboard(pages=[page_1, page_2])

if __name__ == "__main__":
Vizro().build(dashboard).run()
5 changes: 3 additions & 2 deletions vizro-core/examples/demo/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
.agg({"lifeExp": "mean", "pop": "mean", "gdpPercap": "mean"})
.reset_index()
)
gapminder_mean_2007 = gapminder_mean.query("year == 2007")

gapminder_transformed = gapminder.copy()
gapminder_transformed["lifeExp"] = gapminder.groupby(by=["continent", "year"])["lifeExp"].transform("mean")
Expand Down Expand Up @@ -84,7 +85,7 @@ def variable_boxplot(y: str, data_frame: pd.DataFrame = None):
def variable_bar(x: str, data_frame: pd.DataFrame = None):
"""Custom bar figure that needs post update calls."""
fig = px.bar(
data_frame.query("year == 2007"),
data_frame,
x=x,
y="continent",
orientation="h",
Expand Down Expand Up @@ -254,7 +255,7 @@ def create_variable_analysis():
),
vm.Graph(
id="variable_bar",
figure=variable_bar(data_frame=gapminder_mean, x="lifeExp"),
figure=variable_bar(data_frame=gapminder_mean_2007, x="lifeExp"),
),
],
controls=[
Expand Down