Repository: arviz-devs/arviz

Issue:
plot_density has no filter_vars argument
I think it should have the argument. It may be a little more complicated given the multiple idata input but is should still be feasible.



Discussion:
Given that `var_names` already supports multiple idata inputs and their filtering, we're looking for separate filtering for each input idata right?
I think `_var_names` must always be a list of strings and it's datasets what can be a list of xarray datasets or a single dataset. Therefore, it does not seem really useful to try and apply different filtering schemes to each dataset given that the var_names will be the same (strings in var_names will not generally be compatible with all filtering schemes). 

I would therefore pass `filter_vars` from `plot_density` to `_var_names` and test it works, I think it should work straight away.
> I would therefore pass filter_vars from plot_density to _var_names and test it works, I think it should work straight away.

Yeah, it should work. The "complicated" got me thinking about the requirement of separating the filtering and I started thinking about a `dict` based revamp for `_var_names` 😅
Hi @OriolAbril is the issue still open? I would like to work over this. 
You can work on this @prahasR 
Thanks @OriolAbril! I have some questions regarding the issue can you please clarify them. Over https://github.com/arviz-devs/arviz/blob/main/arviz/utils.py I found that `filter_vars` can take only 3 values that are `None`, `like` and `regex`. So one of these values should be passed to `_var_names` as `filter_vars` at https://github.com/arvizdevs/arviz/blob/main/arviz/plots/densityplot.py#L189? Right? 

If this is the case then can you please help me understand that what value of `filter_vars` should be passed to `_var_names`? 

I apologise if the questions were too simple. I request you to please clarify my doubts, its my first time contributing here.

Thank You.



`filter_vars` is what should be passed to `_var_names` whatever value it is storing. See for example https://github.com/arviz-devs/arviz/blob/main/arviz/plots/essplot.py#L194. You need to add `filter_vars` as a parameter in the function definition, document it in the docstring and update the call to `_var_names` to pass also `filter_vars`. Then you'll need to test the behaviour manually and add tests on https://github.com/arviz-devs/arviz/blob/main/arviz/tests/base_tests/test_plots_matplotlib.py. 

> I apologise if the questions were too simple. I request you to please clarify my doubts, its my first time contributing here.

No need to apologize, I do have a question if I may. What thing specific to this issue called/interested you and made you decide to chose it before issues labeled beginner friendly? You (like anyone) are free to work on it, I just want to make sure you know what you are getting into before you end up spending too much time on this. 

Resolving patch:
diff --git a/arviz/plots/densityplot.py b/arviz/plots/densityplot.py
--- a/arviz/plots/densityplot.py
+++ b/arviz/plots/densityplot.py
@@ -17,6 +17,7 @@ def plot_density(
     group="posterior",
     data_labels=None,
     var_names=None,
+    filter_vars=None,
     transform=None,
     hdi_prob=None,
     point_estimate="auto",
@@ -58,6 +59,11 @@ def plot_density(
         List of variables to plot.  If multiple datasets are supplied and var_names is not None,
         will print the same set of variables for each dataset.  Defaults to None, which results in
         all the variables being plotted.
+    filter_vars: {None, "like", "regex"}, optional, default=None
+        If `None` (default), interpret var_names as the real variables names. If "like",
+        interpret var_names as substrings of the real variables names. If "regex",
+        interpret var_names as regular expressions on the real variables names. A la
+        ``pandas.filter``.
     transform : callable
         Function to transform data (defaults to None i.e. the identity function)
     hdi_prob : float
@@ -186,7 +192,7 @@ def plot_density(
     if labeller is None:
         labeller = BaseLabeller()
 
-    var_names = _var_names(var_names, datasets)
+    var_names = _var_names(var_names, datasets, filter_vars)
     n_data = len(datasets)
 
     if data_labels is None:


Test patch:
diff --git a/arviz/tests/base_tests/test_plots_matplotlib.py b/arviz/tests/base_tests/test_plots_matplotlib.py
--- a/arviz/tests/base_tests/test_plots_matplotlib.py
+++ b/arviz/tests/base_tests/test_plots_matplotlib.py
@@ -163,6 +163,9 @@ def test_plot_density_bad_kwargs(models):
     with pytest.raises(ValueError):
         plot_density(obj, hdi_prob=2)
 
+    with pytest.raises(ValueError):
+        plot_density(obj, filter_vars="bad_value")
+
 
 @pytest.mark.parametrize(
     "kwargs",
diff --git a/arviz/tests/base_tests/test_utils.py b/arviz/tests/base_tests/test_utils.py
--- a/arviz/tests/base_tests/test_utils.py
+++ b/arviz/tests/base_tests/test_utils.py
@@ -66,6 +66,25 @@ def test_var_names_key_error(data):
         _var_names(("theta", "tau", "bad_var_name"), data)
 
 
+@pytest.mark.parametrize(
+    "var_args",
+    [
+        (["ta"], ["beta1", "beta2", "theta"], "like"),
+        (["~beta"], ["phi", "theta"], "like"),
+        (["beta[0-9]+"], ["beta1", "beta2"], "regex"),
+        (["^p"], ["phi"], "regex"),
+        (["~^t"], ["beta1", "beta2", "phi"], "regex"),
+    ],
+)
+def test_var_names_filter_multiple_input(var_args):
+    samples = np.random.randn(10)
+    data1 = dict_to_dataset({"beta1": samples, "beta2": samples, "phi": samples})
+    data2 = dict_to_dataset({"beta1": samples, "beta2": samples, "theta": samples})
+    data = [data1, data2]
+    var_names, expected, filter_vars = var_args
+    assert _var_names(var_names, data, filter_vars) == expected
+
+
 @pytest.mark.parametrize(
     "var_args",
     [