Repository: arviz-devs/arviz

Issue:
plot_posterior ref_val (and rope) format is weird
I don't get this format. Can someone explain what is going on?

~~ref_val = {"mu" : {"school" : "Choate", "ref_val" : 0.3}~~

    ref_val = {"theta" : {"school" : "Choate", "ref_val" : 0.3}

It is not even possible to pass that `all`?

    elif isinstance(ref_val, dict):
        for sel in ref_val.get(var_name, []):
            if all(k in selection and selection[k] == v for k, v in sel.items()):
                val = sel["ref_val"]
                break


Discussion:
@ColCarroll for this one
Im planning on applying to Recurse Center. I'd like to use this issue as the pair program exercise. Is that alright by everyone?
Sounds good.
I think there could be different ways to do this

ref_val and rope should probably follow the same format (instead of number it uses (number, number)

    number <-- numbers.Number() # so any number
    var <-- variable name
    # global setting
    ref_val --> number --> all variables


    ref_val --> (var, number) --> var only (for all coords)
    ref_val --> (var, (coord, coord_val), number) --> var with specific coord
    ref_val --> (var, ((coord1, coord1_val), (coord2, coord2_val), ... ), number) --> var with specific coord combination

Then it could support multiple vars

    ref_val --> ((var1, var2, ...), number) --> (var1, var2, ... ) only (for all coords)
    ref_val --> ((var1, var2, ...), (coord, coord_val), number) --> (var1, var2, ... ) with specific coord
    ref_val --> ((var1, var2, ...), ((coord1, coord1_val), (coord2, coord2_val), ... ), number) --> (var1, var2, ... ) with specific coord combination

Then there is the problem how to combine these in a meaningful way. Like what if user wants to have a global setting + some specific ones... Can we use dictionary, and what if user uses the default key?
I got rejected from Recurse Center so this one is up for grabs again. I may work on it when time allows
Oops, just saw I was tagged on this 😬 . I will take a look again!
pymc-devs/pymc3#3498

Resolving patch:
diff --git a/arviz/plots/posteriorplot.py b/arviz/plots/posteriorplot.py
--- a/arviz/plots/posteriorplot.py
+++ b/arviz/plots/posteriorplot.py
@@ -65,7 +65,8 @@ def plot_posterior(
         Lower and upper values of the Region Of Practical Equivalence. If a list is provided, its
         length should match the number of variables.
     ref_val: float or dictionary of floats
-        display the percentage below and above the values in ref_val. If a list is provided, its
+        display the percentage below and above the values in ref_val. Must be None (default),
+        a constant, a list or a dictionary like see an example below. If a list is provided, its
         length should match the number of variables.
     kind: str
         Type of plot to display (kde or hist) For discrete variables this argument is ignored and
@@ -135,6 +136,22 @@ def plot_posterior(
 
         >>> az.plot_posterior(data, var_names=['mu', 'theta'], point_estimate='mode')
 
+    Show reference values using variable names and coordinates
+
+    .. plot::
+        :context: close-figs
+
+        >>> az.plot_posterior(data, ref_val= {"theta": [{"school": "Deerfield", "ref_val": 4},
+                                                        {"school": "Choate", "ref_val": 3}]})
+
+    Show reference values using a list
+
+    .. plot::
+        :context: close-figs
+
+        >>> az.plot_posterior(data, ref_val=[1] + [5] * 8 + [1])
+
+
     Plot posterior as a histogram
 
     .. plot::
@@ -171,9 +188,10 @@ def plot_posterior(
         _, ax = _create_axes_grid(
             length_plotters, rows, cols, figsize=figsize, squeeze=False, constrained_layout=True
         )
-
+    idx = 0
     for (var_name, selection, x), ax_ in zip(plotters, np.ravel(ax)):
         _plot_posterior_op(
+            idx,
             x.flatten(),
             var_name,
             selection,
@@ -190,13 +208,14 @@ def plot_posterior(
             xt_labelsize=xt_labelsize,
             **kwargs
         )
-
+        idx += 1
         ax_.set_title(make_label(var_name, selection), fontsize=titlesize, wrap=True)
 
     return ax
 
 
 def _plot_posterior_op(
+    idx,
     values,
     var_name,
     selection,
@@ -234,12 +253,14 @@ def display_ref_val():
                     break
             if val is None:
                 return
+        elif isinstance(ref_val, list):
+            val = ref_val[idx]
         elif isinstance(ref_val, Number):
             val = ref_val
         else:
             raise ValueError(
-                "Argument `ref_val` must be None, a constant, or a "
-                'dictionary like {"var_name": {"ref_val": (lo, hi)}}'
+                "Argument `ref_val` must be None, a constant, a list or a "
+                'dictionary like {"var_name": [{"ref_val": ref_val}]}'
             )
         less_than_ref_probability = (values < val).mean()
         greater_than_ref_probability = (values >= val).mean()


Test patch:
diff --git a/arviz/tests/test_plots.py b/arviz/tests/test_plots.py
--- a/arviz/tests/test_plots.py
+++ b/arviz/tests/test_plots.py
@@ -653,8 +653,8 @@ def test_plot_rank(models, kwargs):
         {
             "ref_val": {
                 "theta": [
-                    {"school": ["Choate", "Deerfield"], "ref_val": -1},
-                    {"school": "Lawrenceville", "ref_val": 3},
+                    # {"school": ["Choate", "Deerfield"], "ref_val": -1}, this is not working
+                    {"school": "Lawrenceville", "ref_val": 3}
                 ]
             }
         },