arviz-devs / arviz-plots

ArviZ modular plotting
https://arviz-plots.readthedocs.io
Apache License 2.0
2 stars 1 forks source link

Behaviour of aesthetics mapping for dimension subset #33

Closed OriolAbril closed 5 months ago

OriolAbril commented 6 months ago

arviz_plots.PlotCollection.generate_aes_dt is the method that takes care of assigning the values given for an aesthetic to the different coordinate value combinations. If the aesthetic is mapped to a single dimension, everything is very clear.

If an aesthetic is mapped to multiple dimensions, everything is clear as long as variables with these dimensions always have all of them. Here is one example:

Take dimensions team, field with sizes 6, 2 respectively. If we map "y" to both team and field, then we get the following pairings:

field\team 0 1 2 ...
0 y[0] y[1] y[2] ...
1 y[6] y[7] y[8] ...

However, we can also find variables that have only the field dimension, and variables that have only the team dimension. Currently, the variables with only the field dimension would get the two first elements in y paired to them, and the variables with only the team dimension would get the 6 first values paired to them.

Which is probably not what we want because then, the value in y[0] is assigned to either of:

Is that ok? Or should variables with only a subset of the dimensions defined in a mapping get no mapping at all?

OriolAbril commented 5 months ago

Extra note: if we only apply mappings if all dimensions match, otherwise none are applied we will need a "neutral" element, which ideally should not be hardcoded (otherwise, dark-mode graphics for example would look extremely bad when using "black" as neutral element and there would be no way to fix it).

One possibility could be to take the first element of the provided property as neutral element, and use [1:] elements for actual mapping.

Current behaviour (works on jupyter, probably not elsewhere):

pc = plot_forest(
     non_centered,
     combined=True,
     pc_kwargs={
         "aes": {"color": ["school"]},
     },
     shade_label="school",
)
pc.add_legend("school", aes={"color"})

imatge

manually modify aes datatree to simulate proposed behaviour:

pc.map(lambda da, target, backend: target.clear(), loop_data="plots", ignore_aes=pc.aes_set)

ds = pc.get_aes_as_dataset("color")
colors = ds["theta"].values
colors[:-1] = colors[1:]
colors[-1] = "#717581"
ds["theta"] = ("school", colors)
ds["theta_t"] = ("school", colors)
pc.update_aes_from_dataset("color", ds)

pc = plot_forest(
    non_centered,
    combined=True,
    plot_collection=pc,
    shade_label="school",
)
pc.add_legend("school", aes={"color"})
pc.viz["chart"].item()

imatge

aloctavodia commented 5 months ago

Taking the first element as neutral seems like a very reasonable approach