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

Dynamic data with sliders stops working with added action #799

Closed
1 task done
gtauzin opened this issue Oct 8, 2024 · 2 comments
Closed
1 task done

Dynamic data with sliders stops working with added action #799

gtauzin opened this issue Oct 8, 2024 · 2 comments
Assignees
Labels
General Question ❓ Issue contains a general question

Comments

@gtauzin
Copy link

gtauzin commented Oct 8, 2024

Which package?

vizro

Package version

0.1.24

Description

I am building a dashboard using a dynamic data source. I have a control slider to choose the plotted data but I would also like to set up an action to save the slider value.

With such an action added, the slider has no effect on the plot and the action itself no longer works.

How to Reproduce

The following example can be ran in PyCafe:

from vizro import Vizro
import pandas as pd
import vizro.plotly.express as px
import vizro.models as vm
from vizro.models.types import capture

from vizro.managers import data_manager

def load_iris_data(number_of_points=10): 
    iris = px.data.iris()
    return iris.sample(number_of_points) 

data_manager["iris"] = load_iris_data 

@capture("action")
def print_name(name):
    print(name)

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")) 
    ],
    controls=[
        vm.Parameter(
            id="slider",
            targets=["graph.data_frame.number_of_points"], 
            selector=vm.Slider(
                min=10, max=100, step=10, value=10,
                actions=[
                    vm.Action(function=print_name(), inputs=["slider.value"])
                ],
            ),
        )
    ],
)

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

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

Output

No response

Code of Conduct

@gtauzin gtauzin added Bug Report 🐛 Issue contains a bug report Needs triage 🔍 Issue needs triaging labels Oct 8, 2024
@petar-qb petar-qb self-assigned this Oct 9, 2024
@petar-qb
Copy link
Contributor

petar-qb commented Oct 9, 2024

Hi @gtauzin and thanks for using Vizro! 😃

In Vizro, when you configure a vm.Parameter, for example like this:

vm.Parameter(
    targets=["graph.data_frame.number_of_points"],
    selector=vm.Slider(
        id="slider",
        min=10, max=100, step=10, value=10
    )
)

internally, the private _parameter Vizro action is assigned to the slider, and the model is adjusted to this:

vm.Parameter(
    targets=["graph.data_frame.number_of_points"],
    selector=vm.Slider(
        id="slider",
        min=10, max=100, step=10, value=10,
        actions=[
            vm.Action(function=_parameter(targets=["graph.data_frame.number_of_points"]))
        ]
    )
)

And, because you provided your action (vm.Action(function=print_name(), inputs=["slider.value"])) inside the parameter selector, Vizro does not overwrite it with the private _parameter action, which causes that the "parametrisation" is not going to happen.

This private _parameter action (and many other vizro actions enhancements) are going to become public, once we decide to merge -> #363.

So, while waiting for fully native Vizro support for achieving this use-case, I'm sending you workaround solution that includes using the private Vizro _parameter action.

from vizro import Vizro
import pandas as pd
import vizro.plotly.express as px
import vizro.models as vm
from vizro.models.types import capture
from vizro.actions._parameter_action import _parameter

from vizro.managers import data_manager


def load_iris_data(number_of_points=10):
    iris = px.data.iris()
    return iris.sample(number_of_points) 


data_manager["iris"] = load_iris_data 


@capture("action")
def print_name(name):
    print(name)


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")) 
    ],
    controls=[
        vm.Parameter(
            targets=["graph.data_frame.number_of_points"],
            selector=vm.Slider(
                id="slider",
                min=10, max=100, step=10, value=10,
                actions=[
                    vm.Action(function=_parameter(targets=["graph.data_frame.number_of_points"])),
                    vm.Action(function=print_name(), inputs=["slider.value"])
                ],
            ),
        )
    ],
)

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

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

Also, you can aways combine vizro actions with dash callbacks if you need to implement something hacky.

@petar-qb petar-qb added General Question ❓ Issue contains a general question and removed Bug Report 🐛 Issue contains a bug report Needs triage 🔍 Issue needs triaging labels Oct 9, 2024
@gtauzin
Copy link
Author

gtauzin commented Oct 9, 2024

Thank you @petar-qb! It is now very clear :)

@petar-qb petar-qb closed this as completed Oct 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
General Question ❓ Issue contains a general question
Projects
None yet
Development

No branches or pull requests

2 participants