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

Tooltip and grouping information? #68

Open
OriolAbril opened this issue Jul 6, 2024 · 2 comments
Open

Tooltip and grouping information? #68

OriolAbril opened this issue Jul 6, 2024 · 2 comments
Labels
question Further information is requested

Comments

@OriolAbril
Copy link
Member

We might want to provide tooltip and grouping information somehow as part of the common plotting interface. Even if some backends can't include that into the plot, it would be a great win for those that can.

@OriolAbril OriolAbril added the question Further information is requested label Jul 6, 2024
@OriolAbril
Copy link
Member Author

Here is an example of getting an interactive legend working with plot_dist. As we can pass arbitrary elements as aesthetics and as plot_kwargs everything is feasible already, but we might want to set that behaviour as the default (maybe only when there are multiple models for example, with docs on doing that also for plot_dist with chains as different colors...).

Note: to make that a default the legendgroup argument should become part of the common interface (with this or another name) and be ignored for backends where it makes no sense.

Screencast.de.9-7-24.22.32.03.webm
Code to reproduce

At the time of writing, this requires the plotly_poc branch

import numpy as np
import arviz_plots as azp
from arviz_base import load_arviz_data

import plotly.io as pio

pio.renderers.default = "browser"

c = load_arviz_data("centered_eight")
n = load_arviz_data("non_centered_eight")

pc = azp.plot_dist(
    {"centered": c, "non_centered": n},
    backend="plotly",
    pc_kwargs={"aes": {"legendgroup": ["model"]}, "legendgroup": ["centered", "non_centered"]},
    aes_map={
        "credible_interval": {"color", "y", "legendgroup"},
        "point_estimate": {"color", "y", "legendgroup"},
    },
    plot_kwargs={
        "kde": {"showlegend": False},
        "credible_interval": {"showlegend": False},
        "point_estimate": {"showlegend": False},
        "point_estimate_text": {"showlegend": False},
    }
)

# generate interactive legend
colors = pc.aes["mu"]["color"].values
plot = pc.viz["chart"].item()
obj_centered = pc.viz["mu"]["kde"].sel(model="centered").item()
obj_non_centered = pc.viz["mu"]["kde"].sel(model="non_centered").item()
plot.update_traces(
    selector=lambda trace: (trace.y.shape == obj_centered.y.shape) and np.allclose(trace.y, obj_centered.y),
    name="centered",
    legendgroup="centered",
    showlegend=True,
)
plot.update_traces(
    selector=lambda trace: (trace.y.shape == obj_non_centered.y.shape) and np.allclose(trace.y, obj_non_centered.y),
    name="non centered",
    legendgroup="non_centered",
    showlegend=True,
)
# ------
pc.show()

or with plot_forest:

Screencast.de.9-7-24.22.30.39.webm
Code to reproduce

At the time of writing, this requires the plotly_poc branch

import numpy as np
import arviz_plots as azp
from arviz_base import load_arviz_data

import plotly.io as pio

pio.renderers.default = "browser"

c = load_arviz_data("centered_eight")
n = load_arviz_data("non_centered_eight")
pc = azp.plot_forest(
    {"centered": c, "non_centered": n},
    backend="plotly",
    pc_kwargs={"aes": {"legendgroup": ["model"]}, "legendgroup": ["centered", "non_centered"]},
    plot_kwargs={
        "trunk": {"showlegend": False},
        "twig": {"showlegend": False},
        "point_estimate": {"showlegend": False},
        "labels": {"showlegend": False},
    }
)

# generate interactive legend
colors = pc.aes["mu"]["color"].values
plot = pc.viz["plot"].sel(column="forest").item()
obj_centered = pc.viz["mu"]["point_estimate"].sel(chain=0, model="centered").item()
obj_non_centered = pc.viz["mu"]["point_estimate"].sel(chain=0, model="non_centered").item()
plot.update_traces(
    selector=lambda trace: np.allclose(trace.y, obj_centered.y) & np.allclose(trace.x, obj_centered.x),
    name="centered",
    mode="lines+markers",
    legendgroup="centered",
    showlegend=True,
    line={"color": colors[0]}
)
plot.update_traces(
    selector=lambda trace: np.allclose(trace.y, obj_non_centered.y) & np.allclose(trace.x, obj_non_centered.x),
    name="non centered",
    mode="lines+markers",
    legendgroup="non_centered",
    showlegend=True,
    line={"color": colors[1]}
)
# ------
pc.show()

@aloctavodia
Copy link
Contributor

At least some of this functionality is supported by matplotlib. See here https://matplotlib.org/stable/gallery/event_handling/legend_picking.html

Do we want to support interactivity for matplotlib too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants