We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`plot_density` does not work for models with different variables
**Describe the bug**
When passing data of several models to `plot_density`, it throws an error if both models contain parameters that the other model does not have.
As long the the variables in the one model are a subset of the the variables of the other model it works.
I think that the problem lies in how `plot_density` determines the number of plots to create. It calculates the number of parameters in each model and then uses the maximum:
```
192     length_plotters = []
193     for plotters in to_plot:
194         length_plotters.append(len(plotters))
195         for var_name, selection, _ in plotters:
196             label = make_label(var_name, selection)
197             if label not in all_labels:
198                 all_labels.append(label)
199     length_plotters = max(length_plotters)
```
That does not account for the situation where the union of parameters over all models is larger than the set parameters in each single model.

**To Reproduce**
This simple example should demonstrate what I mean:
```python
import numpy as np
import xarray as xr
import arviz

n_draws = 1000

model_ab = xr.Dataset({
    "a": ("draw", np.random.normal(size=n_draws)),
    "b": ("draw", np.random.normal(size=n_draws)),
})
model_b = xr.Dataset({
    "b": ("draw", np.random.normal(size=n_draws)),
})
model_bc = xr.Dataset({
    "c": ("draw", np.random.normal(size=n_draws)),
    "b": ("draw", np.random.normal(size=n_draws)),
})

# Works
arviz.plot_density([model_ab, model_b], data_labels=["ab", "b"]);

# Does not work
arviz.plot_density([model_ab, model_bc], data_labels=["ab", "bc"]);
```

**Expected behavior**
In the second case, the code should create 3 subplots, for parameters a, b, and c. While the plots for a and c would contain only one density, the plot for b would contain two densities.

**Additional context**
arviz Version: 0.6.1


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `arviz/plots/densityplot.py`
Content:
```
1 """KDE and histogram plots for multiple variables."""
2 from itertools import cycle
3 import warnings
4 
5 import matplotlib.pyplot as plt
6 
7 from ..data import convert_to_dataset
8 from .plot_utils import (
9     _scale_fig_size,
10     make_label,
11     xarray_var_iter,
12     default_grid,
13     get_plotting_function,
14 )
15 from ..rcparams import rcParams
16 from ..utils import _var_names
17 
18 
19 # pylint:disable-msg=too-many-function-args
20 def plot_density(
21     data,
22     group="posterior",
23     data_labels=None,
24     var_names=None,
25     transform=None,
26     credible_interval=None,
27     point_estimate="auto",
28     colors="cycle",
29     outline=True,
30     hpd_markers="",
31     shade=0.0,
32     bw=4.5,
33     figsize=None,
34     textsize=None,
35     ax=None,
36     backend=None,
37     backend_kwargs=None,
38     show=None,
39 ):
40     """Generate KDE plots for continuous variables and histograms for discrete ones.
41 
42     Plots are truncated at their 100*(1-alpha)% credible intervals. Plots are grouped per variable
43     and colors assigned to models.
44 
45     Parameters
46     ----------
47     data : Union[Object, Iterator[Object]]
48         Any object that can be converted to an az.InferenceData object, or an Iterator returning
49         a sequence of such objects.
50         Refer to documentation of az.convert_to_dataset for details about such objects.
51     group: Optional[str]
52         Specifies which InferenceData group should be plotted.  Defaults to 'posterior'.
53         Alternative values include 'prior' and any other strings used as dataset keys in the
54         InferenceData.
55     data_labels : Optional[List[str]]
56         List with names for the datasets passed as "data." Useful when plotting more than one
57         dataset.  Must be the same shape as the data parameter.  Defaults to None.
58     var_names: Optional[List[str]]
59         List of variables to plot.  If multiple datasets are supplied and var_names is not None,
60         will print the same set of variables for each dataset.  Defaults to None, which results in
61         all the variables being plotted.
62     transform : callable
63         Function to transform data (defaults to None i.e. the identity function)
64     credible_interval : float
65         Credible intervals. Should be in the interval (0, 1]. Defaults to 0.94.
66     point_estimate : Optional[str]
67         Plot point estimate per variable. Values should be 'mean', 'median', 'mode' or None.
68         Defaults to 'auto' i.e. it falls back to default set in rcParams.
69     colors : Optional[Union[List[str],str]]
70         List with valid matplotlib colors, one color per model. Alternative a string can be passed.
71         If the string is `cycle`, it will automatically choose a color per model from matplotlib's
72         cycle. If a single color is passed, e.g. 'k', 'C2' or 'red' this color will be used for all
73         models. Defaults to `cycle`.
74     outline : bool
75         Use a line to draw KDEs and histograms. Default to True
76     hpd_markers : str
77         A valid `matplotlib.markers` like 'v', used to indicate the limits of the hpd interval.
78         Defaults to empty string (no marker).
79     shade : Optional[float]
80         Alpha blending value for the shaded area under the curve, between 0 (no shade) and 1
81         (opaque). Defaults to 0.
82     bw : Optional[float]
83         Bandwidth scaling factor for the KDE. Should be larger than 0. The higher this number the
84         smoother the KDE will be. Defaults to 4.5 which is essentially the same as the Scott's rule
85         of thumb (the default rule used by SciPy).
86     figsize : Optional[Tuple[int, int]]
87         Figure size. If None it will be defined automatically.
88     textsize: Optional[float]
89         Text size scaling factor for labels, titles and lines. If None it will be autoscaled based
90         on figsize.
91     ax: axes, optional
92         Matplotlib axes or Bokeh figures.
93     backend: str, optional
94         Select plotting backend {"matplotlib","bokeh"}. Default "matplotlib".
95     backend_kwargs: bool, optional
96         These are kwargs specific to the backend being used. For additional documentation
97         check the plotting method of the backend.
98     show : bool, optional
99         Call backend show function.
100 
101     Returns
102     -------
103     axes : matplotlib axes or bokeh figures
104 
105 
106     Examples
107     --------
108     Plot default density plot
109 
110     .. plot::
111         :context: close-figs
112 
113         >>> import arviz as az
114         >>> centered = az.load_arviz_data('centered_eight')
115         >>> non_centered = az.load_arviz_data('non_centered_eight')
116         >>> az.plot_density([centered, non_centered])
117 
118     Plot subset variables by specifying variable name exactly
119 
120     .. plot::
121         :context: close-figs
122 
123         >>> az.plot_density([centered, non_centered], var_names=["mu"])
124 
125     Plot a specific `az.InferenceData` group
126 
127     .. plot::
128         :context: close-figs
129 
130         >>> az.plot_density([centered, non_centered], var_names=["mu"], group="prior")
131 
132     Specify credible interval
133 
134     .. plot::
135         :context: close-figs
136 
137         >>> az.plot_density([centered, non_centered], var_names=["mu"], credible_interval=.5)
138 
139     Shade plots and/or remove outlines
140 
141     .. plot::
142         :context: close-figs
143 
144         >>> az.plot_density([centered, non_centered], var_names=["mu"], outline=False, shade=.8)
145 
146     Specify binwidth for kernel density estimation
147 
148     .. plot::
149         :context: close-figs
150 
151         >>> az.plot_density([centered, non_centered], var_names=["mu"], bw=.9)
152     """
153     if transform is not None:
154         data = transform(data)
155     if not isinstance(data, (list, tuple)):
156         datasets = [convert_to_dataset(data, group=group)]
157     else:
158         datasets = [convert_to_dataset(datum, group=group) for datum in data]
159 
160     var_names = _var_names(var_names, datasets)
161     n_data = len(datasets)
162 
163     if data_labels is None:
164         if n_data > 1:
165             data_labels = ["{}".format(idx) for idx in range(n_data)]
166         else:
167             data_labels = [""]
168     elif len(data_labels) != n_data:
169         raise ValueError(
170             "The number of names for the models ({}) "
171             "does not match the number of models ({})".format(len(data_labels), n_data)
172         )
173 
174     if colors == "cycle":
175         colors = [
176             prop
177             for _, prop in zip(
178                 range(n_data), cycle(plt.rcParams["axes.prop_cycle"].by_key()["color"])
179             )
180         ]
181     elif isinstance(colors, str):
182         colors = [colors for _ in range(n_data)]
183 
184     if credible_interval is None:
185         credible_interval = rcParams["stats.credible_interval"]
186     else:
187         if not 1 >= credible_interval > 0:
188             raise ValueError("The value of credible_interval should be in the interval (0, 1]")
189 
190     to_plot = [list(xarray_var_iter(data, var_names, combined=True)) for data in datasets]
191     all_labels = []
192     length_plotters = []
193     for plotters in to_plot:
194         length_plotters.append(len(plotters))
195         for var_name, selection, _ in plotters:
196             label = make_label(var_name, selection)
197             if label not in all_labels:
198                 all_labels.append(label)
199     length_plotters = max(length_plotters)
200     max_plots = rcParams["plot.max_subplots"]
201     max_plots = length_plotters if max_plots is None else max_plots
202     if length_plotters > max_plots:
203         warnings.warn(
204             "rcParams['plot.max_subplots'] ({max_plots}) is smaller than the number "
205             "of variables to plot ({len_plotters}) in plot_density, generating only "
206             "{max_plots} plots".format(max_plots=max_plots, len_plotters=length_plotters),
207             UserWarning,
208         )
209         all_labels = all_labels[:max_plots]
210         to_plot = [
211             [
212                 (var_name, selection, values)
213                 for var_name, selection, values in plotters
214                 if make_label(var_name, selection) in all_labels
215             ]
216             for plotters in to_plot
217         ]
218         length_plotters = max_plots
219     rows, cols = default_grid(length_plotters, max_cols=3)
220 
221     (figsize, _, titlesize, xt_labelsize, linewidth, markersize) = _scale_fig_size(
222         figsize, textsize, rows, cols
223     )
224 
225     plot_density_kwargs = dict(
226         ax=ax,
227         all_labels=all_labels,
228         to_plot=to_plot,
229         colors=colors,
230         bw=bw,
231         figsize=figsize,
232         length_plotters=length_plotters,
233         rows=rows,
234         cols=cols,
235         titlesize=titlesize,
236         xt_labelsize=xt_labelsize,
237         linewidth=linewidth,
238         markersize=markersize,
239         credible_interval=credible_interval,
240         point_estimate=point_estimate,
241         hpd_markers=hpd_markers,
242         outline=outline,
243         shade=shade,
244         n_data=n_data,
245         data_labels=data_labels,
246         backend_kwargs=backend_kwargs,
247         show=show,
248     )
249 
250     if backend is None:
251         backend = rcParams["plot.backend"]
252     backend = backend.lower()
253 
254     if backend == "bokeh":
255 
256         plot_density_kwargs["line_width"] = plot_density_kwargs.pop("linewidth")
257         plot_density_kwargs.pop("titlesize")
258         plot_density_kwargs.pop("xt_labelsize")
259         plot_density_kwargs.pop("n_data")
260 
261     # TODO: Add backend kwargs
262     plot = get_plotting_function("plot_density", "densityplot", backend)
263     ax = plot(**plot_density_kwargs)
264     return ax
265
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/arviz/plots/densityplot.py b/arviz/plots/densityplot.py
--- a/arviz/plots/densityplot.py
+++ b/arviz/plots/densityplot.py
@@ -196,7 +196,7 @@
             label = make_label(var_name, selection)
             if label not in all_labels:
                 all_labels.append(label)
-    length_plotters = max(length_plotters)
+    length_plotters = len(all_labels)
     max_plots = rcParams["plot.max_subplots"]
     max_plots = length_plotters if max_plots is None else max_plots
     if length_plotters > max_plots:

{"golden_diff": "diff --git a/arviz/plots/densityplot.py b/arviz/plots/densityplot.py\n--- a/arviz/plots/densityplot.py\n+++ b/arviz/plots/densityplot.py\n@@ -196,7 +196,7 @@\n             label = make_label(var_name, selection)\n             if label not in all_labels:\n                 all_labels.append(label)\n-    length_plotters = max(length_plotters)\n+    length_plotters = len(all_labels)\n     max_plots = rcParams[\"plot.max_subplots\"]\n     max_plots = length_plotters if max_plots is None else max_plots\n     if length_plotters > max_plots:\n", "issue": "`plot_density` does not work for models with different variables\n**Describe the bug**\r\nWhen passing data of several models to `plot_density`, it throws an error if both models contain parameters that the other model does not have.\r\nAs long the the variables in the one model are a subset of the the variables of the other model it works.\r\nI think that the problem lies in how `plot_density` determines the number of plots to create. It calculates the number of parameters in each model and then uses the maximum:\r\n```\r\n192     length_plotters = []\r\n193     for plotters in to_plot:\r\n194         length_plotters.append(len(plotters))\r\n195         for var_name, selection, _ in plotters:\r\n196             label = make_label(var_name, selection)\r\n197             if label not in all_labels:\r\n198                 all_labels.append(label)\r\n199     length_plotters = max(length_plotters)\r\n```\r\nThat does not account for the situation where the union of parameters over all models is larger than the set parameters in each single model.\r\n\r\n**To Reproduce**\r\nThis simple example should demonstrate what I mean:\r\n```python\r\nimport numpy as np\r\nimport xarray as xr\r\nimport arviz\r\n\r\nn_draws = 1000\r\n\r\nmodel_ab = xr.Dataset({\r\n    \"a\": (\"draw\", np.random.normal(size=n_draws)),\r\n    \"b\": (\"draw\", np.random.normal(size=n_draws)),\r\n})\r\nmodel_b = xr.Dataset({\r\n    \"b\": (\"draw\", np.random.normal(size=n_draws)),\r\n})\r\nmodel_bc = xr.Dataset({\r\n    \"c\": (\"draw\", np.random.normal(size=n_draws)),\r\n    \"b\": (\"draw\", np.random.normal(size=n_draws)),\r\n})\r\n\r\n# Works\r\narviz.plot_density([model_ab, model_b], data_labels=[\"ab\", \"b\"]);\r\n\r\n# Does not work\r\narviz.plot_density([model_ab, model_bc], data_labels=[\"ab\", \"bc\"]);\r\n```\r\n\r\n**Expected behavior**\r\nIn the second case, the code should create 3 subplots, for parameters a, b, and c. While the plots for a and c would contain only one density, the plot for b would contain two densities.\r\n\r\n**Additional context**\r\narviz Version: 0.6.1\r\n\n", "before_files": [{"content": "\"\"\"KDE and histogram plots for multiple variables.\"\"\"\nfrom itertools import cycle\nimport warnings\n\nimport matplotlib.pyplot as plt\n\nfrom ..data import convert_to_dataset\nfrom .plot_utils import (\n    _scale_fig_size,\n    make_label,\n    xarray_var_iter,\n    default_grid,\n    get_plotting_function,\n)\nfrom ..rcparams import rcParams\nfrom ..utils import _var_names\n\n\n# pylint:disable-msg=too-many-function-args\ndef plot_density(\n    data,\n    group=\"posterior\",\n    data_labels=None,\n    var_names=None,\n    transform=None,\n    credible_interval=None,\n    point_estimate=\"auto\",\n    colors=\"cycle\",\n    outline=True,\n    hpd_markers=\"\",\n    shade=0.0,\n    bw=4.5,\n    figsize=None,\n    textsize=None,\n    ax=None,\n    backend=None,\n    backend_kwargs=None,\n    show=None,\n):\n    \"\"\"Generate KDE plots for continuous variables and histograms for discrete ones.\n\n    Plots are truncated at their 100*(1-alpha)% credible intervals. Plots are grouped per variable\n    and colors assigned to models.\n\n    Parameters\n    ----------\n    data : Union[Object, Iterator[Object]]\n        Any object that can be converted to an az.InferenceData object, or an Iterator returning\n        a sequence of such objects.\n        Refer to documentation of az.convert_to_dataset for details about such objects.\n    group: Optional[str]\n        Specifies which InferenceData group should be plotted.  Defaults to 'posterior'.\n        Alternative values include 'prior' and any other strings used as dataset keys in the\n        InferenceData.\n    data_labels : Optional[List[str]]\n        List with names for the datasets passed as \"data.\" Useful when plotting more than one\n        dataset.  Must be the same shape as the data parameter.  Defaults to None.\n    var_names: Optional[List[str]]\n        List of variables to plot.  If multiple datasets are supplied and var_names is not None,\n        will print the same set of variables for each dataset.  Defaults to None, which results in\n        all the variables being plotted.\n    transform : callable\n        Function to transform data (defaults to None i.e. the identity function)\n    credible_interval : float\n        Credible intervals. Should be in the interval (0, 1]. Defaults to 0.94.\n    point_estimate : Optional[str]\n        Plot point estimate per variable. Values should be 'mean', 'median', 'mode' or None.\n        Defaults to 'auto' i.e. it falls back to default set in rcParams.\n    colors : Optional[Union[List[str],str]]\n        List with valid matplotlib colors, one color per model. Alternative a string can be passed.\n        If the string is `cycle`, it will automatically choose a color per model from matplotlib's\n        cycle. If a single color is passed, e.g. 'k', 'C2' or 'red' this color will be used for all\n        models. Defaults to `cycle`.\n    outline : bool\n        Use a line to draw KDEs and histograms. Default to True\n    hpd_markers : str\n        A valid `matplotlib.markers` like 'v', used to indicate the limits of the hpd interval.\n        Defaults to empty string (no marker).\n    shade : Optional[float]\n        Alpha blending value for the shaded area under the curve, between 0 (no shade) and 1\n        (opaque). Defaults to 0.\n    bw : Optional[float]\n        Bandwidth scaling factor for the KDE. Should be larger than 0. The higher this number the\n        smoother the KDE will be. Defaults to 4.5 which is essentially the same as the Scott's rule\n        of thumb (the default rule used by SciPy).\n    figsize : Optional[Tuple[int, int]]\n        Figure size. If None it will be defined automatically.\n    textsize: Optional[float]\n        Text size scaling factor for labels, titles and lines. If None it will be autoscaled based\n        on figsize.\n    ax: axes, optional\n        Matplotlib axes or Bokeh figures.\n    backend: str, optional\n        Select plotting backend {\"matplotlib\",\"bokeh\"}. Default \"matplotlib\".\n    backend_kwargs: bool, optional\n        These are kwargs specific to the backend being used. For additional documentation\n        check the plotting method of the backend.\n    show : bool, optional\n        Call backend show function.\n\n    Returns\n    -------\n    axes : matplotlib axes or bokeh figures\n\n\n    Examples\n    --------\n    Plot default density plot\n\n    .. plot::\n        :context: close-figs\n\n        >>> import arviz as az\n        >>> centered = az.load_arviz_data('centered_eight')\n        >>> non_centered = az.load_arviz_data('non_centered_eight')\n        >>> az.plot_density([centered, non_centered])\n\n    Plot subset variables by specifying variable name exactly\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"])\n\n    Plot a specific `az.InferenceData` group\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"], group=\"prior\")\n\n    Specify credible interval\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"], credible_interval=.5)\n\n    Shade plots and/or remove outlines\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"], outline=False, shade=.8)\n\n    Specify binwidth for kernel density estimation\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"], bw=.9)\n    \"\"\"\n    if transform is not None:\n        data = transform(data)\n    if not isinstance(data, (list, tuple)):\n        datasets = [convert_to_dataset(data, group=group)]\n    else:\n        datasets = [convert_to_dataset(datum, group=group) for datum in data]\n\n    var_names = _var_names(var_names, datasets)\n    n_data = len(datasets)\n\n    if data_labels is None:\n        if n_data > 1:\n            data_labels = [\"{}\".format(idx) for idx in range(n_data)]\n        else:\n            data_labels = [\"\"]\n    elif len(data_labels) != n_data:\n        raise ValueError(\n            \"The number of names for the models ({}) \"\n            \"does not match the number of models ({})\".format(len(data_labels), n_data)\n        )\n\n    if colors == \"cycle\":\n        colors = [\n            prop\n            for _, prop in zip(\n                range(n_data), cycle(plt.rcParams[\"axes.prop_cycle\"].by_key()[\"color\"])\n            )\n        ]\n    elif isinstance(colors, str):\n        colors = [colors for _ in range(n_data)]\n\n    if credible_interval is None:\n        credible_interval = rcParams[\"stats.credible_interval\"]\n    else:\n        if not 1 >= credible_interval > 0:\n            raise ValueError(\"The value of credible_interval should be in the interval (0, 1]\")\n\n    to_plot = [list(xarray_var_iter(data, var_names, combined=True)) for data in datasets]\n    all_labels = []\n    length_plotters = []\n    for plotters in to_plot:\n        length_plotters.append(len(plotters))\n        for var_name, selection, _ in plotters:\n            label = make_label(var_name, selection)\n            if label not in all_labels:\n                all_labels.append(label)\n    length_plotters = max(length_plotters)\n    max_plots = rcParams[\"plot.max_subplots\"]\n    max_plots = length_plotters if max_plots is None else max_plots\n    if length_plotters > max_plots:\n        warnings.warn(\n            \"rcParams['plot.max_subplots'] ({max_plots}) is smaller than the number \"\n            \"of variables to plot ({len_plotters}) in plot_density, generating only \"\n            \"{max_plots} plots\".format(max_plots=max_plots, len_plotters=length_plotters),\n            UserWarning,\n        )\n        all_labels = all_labels[:max_plots]\n        to_plot = [\n            [\n                (var_name, selection, values)\n                for var_name, selection, values in plotters\n                if make_label(var_name, selection) in all_labels\n            ]\n            for plotters in to_plot\n        ]\n        length_plotters = max_plots\n    rows, cols = default_grid(length_plotters, max_cols=3)\n\n    (figsize, _, titlesize, xt_labelsize, linewidth, markersize) = _scale_fig_size(\n        figsize, textsize, rows, cols\n    )\n\n    plot_density_kwargs = dict(\n        ax=ax,\n        all_labels=all_labels,\n        to_plot=to_plot,\n        colors=colors,\n        bw=bw,\n        figsize=figsize,\n        length_plotters=length_plotters,\n        rows=rows,\n        cols=cols,\n        titlesize=titlesize,\n        xt_labelsize=xt_labelsize,\n        linewidth=linewidth,\n        markersize=markersize,\n        credible_interval=credible_interval,\n        point_estimate=point_estimate,\n        hpd_markers=hpd_markers,\n        outline=outline,\n        shade=shade,\n        n_data=n_data,\n        data_labels=data_labels,\n        backend_kwargs=backend_kwargs,\n        show=show,\n    )\n\n    if backend is None:\n        backend = rcParams[\"plot.backend\"]\n    backend = backend.lower()\n\n    if backend == \"bokeh\":\n\n        plot_density_kwargs[\"line_width\"] = plot_density_kwargs.pop(\"linewidth\")\n        plot_density_kwargs.pop(\"titlesize\")\n        plot_density_kwargs.pop(\"xt_labelsize\")\n        plot_density_kwargs.pop(\"n_data\")\n\n    # TODO: Add backend kwargs\n    plot = get_plotting_function(\"plot_density\", \"densityplot\", backend)\n    ax = plot(**plot_density_kwargs)\n    return ax\n", "path": "arviz/plots/densityplot.py"}], "after_files": [{"content": "\"\"\"KDE and histogram plots for multiple variables.\"\"\"\nfrom itertools import cycle\nimport warnings\n\nimport matplotlib.pyplot as plt\n\nfrom ..data import convert_to_dataset\nfrom .plot_utils import (\n    _scale_fig_size,\n    make_label,\n    xarray_var_iter,\n    default_grid,\n    get_plotting_function,\n)\nfrom ..rcparams import rcParams\nfrom ..utils import _var_names\n\n\n# pylint:disable-msg=too-many-function-args\ndef plot_density(\n    data,\n    group=\"posterior\",\n    data_labels=None,\n    var_names=None,\n    transform=None,\n    credible_interval=None,\n    point_estimate=\"auto\",\n    colors=\"cycle\",\n    outline=True,\n    hpd_markers=\"\",\n    shade=0.0,\n    bw=4.5,\n    figsize=None,\n    textsize=None,\n    ax=None,\n    backend=None,\n    backend_kwargs=None,\n    show=None,\n):\n    \"\"\"Generate KDE plots for continuous variables and histograms for discrete ones.\n\n    Plots are truncated at their 100*(1-alpha)% credible intervals. Plots are grouped per variable\n    and colors assigned to models.\n\n    Parameters\n    ----------\n    data : Union[Object, Iterator[Object]]\n        Any object that can be converted to an az.InferenceData object, or an Iterator returning\n        a sequence of such objects.\n        Refer to documentation of az.convert_to_dataset for details about such objects.\n    group: Optional[str]\n        Specifies which InferenceData group should be plotted.  Defaults to 'posterior'.\n        Alternative values include 'prior' and any other strings used as dataset keys in the\n        InferenceData.\n    data_labels : Optional[List[str]]\n        List with names for the datasets passed as \"data.\" Useful when plotting more than one\n        dataset.  Must be the same shape as the data parameter.  Defaults to None.\n    var_names: Optional[List[str]]\n        List of variables to plot.  If multiple datasets are supplied and var_names is not None,\n        will print the same set of variables for each dataset.  Defaults to None, which results in\n        all the variables being plotted.\n    transform : callable\n        Function to transform data (defaults to None i.e. the identity function)\n    credible_interval : float\n        Credible intervals. Should be in the interval (0, 1]. Defaults to 0.94.\n    point_estimate : Optional[str]\n        Plot point estimate per variable. Values should be 'mean', 'median', 'mode' or None.\n        Defaults to 'auto' i.e. it falls back to default set in rcParams.\n    colors : Optional[Union[List[str],str]]\n        List with valid matplotlib colors, one color per model. Alternative a string can be passed.\n        If the string is `cycle`, it will automatically choose a color per model from matplotlib's\n        cycle. If a single color is passed, e.g. 'k', 'C2' or 'red' this color will be used for all\n        models. Defaults to `cycle`.\n    outline : bool\n        Use a line to draw KDEs and histograms. Default to True\n    hpd_markers : str\n        A valid `matplotlib.markers` like 'v', used to indicate the limits of the hpd interval.\n        Defaults to empty string (no marker).\n    shade : Optional[float]\n        Alpha blending value for the shaded area under the curve, between 0 (no shade) and 1\n        (opaque). Defaults to 0.\n    bw : Optional[float]\n        Bandwidth scaling factor for the KDE. Should be larger than 0. The higher this number the\n        smoother the KDE will be. Defaults to 4.5 which is essentially the same as the Scott's rule\n        of thumb (the default rule used by SciPy).\n    figsize : Optional[Tuple[int, int]]\n        Figure size. If None it will be defined automatically.\n    textsize: Optional[float]\n        Text size scaling factor for labels, titles and lines. If None it will be autoscaled based\n        on figsize.\n    ax: axes, optional\n        Matplotlib axes or Bokeh figures.\n    backend: str, optional\n        Select plotting backend {\"matplotlib\",\"bokeh\"}. Default \"matplotlib\".\n    backend_kwargs: bool, optional\n        These are kwargs specific to the backend being used. For additional documentation\n        check the plotting method of the backend.\n    show : bool, optional\n        Call backend show function.\n\n    Returns\n    -------\n    axes : matplotlib axes or bokeh figures\n\n\n    Examples\n    --------\n    Plot default density plot\n\n    .. plot::\n        :context: close-figs\n\n        >>> import arviz as az\n        >>> centered = az.load_arviz_data('centered_eight')\n        >>> non_centered = az.load_arviz_data('non_centered_eight')\n        >>> az.plot_density([centered, non_centered])\n\n    Plot subset variables by specifying variable name exactly\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"])\n\n    Plot a specific `az.InferenceData` group\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"], group=\"prior\")\n\n    Specify credible interval\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"], credible_interval=.5)\n\n    Shade plots and/or remove outlines\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"], outline=False, shade=.8)\n\n    Specify binwidth for kernel density estimation\n\n    .. plot::\n        :context: close-figs\n\n        >>> az.plot_density([centered, non_centered], var_names=[\"mu\"], bw=.9)\n    \"\"\"\n    if transform is not None:\n        data = transform(data)\n    if not isinstance(data, (list, tuple)):\n        datasets = [convert_to_dataset(data, group=group)]\n    else:\n        datasets = [convert_to_dataset(datum, group=group) for datum in data]\n\n    var_names = _var_names(var_names, datasets)\n    n_data = len(datasets)\n\n    if data_labels is None:\n        if n_data > 1:\n            data_labels = [\"{}\".format(idx) for idx in range(n_data)]\n        else:\n            data_labels = [\"\"]\n    elif len(data_labels) != n_data:\n        raise ValueError(\n            \"The number of names for the models ({}) \"\n            \"does not match the number of models ({})\".format(len(data_labels), n_data)\n        )\n\n    if colors == \"cycle\":\n        colors = [\n            prop\n            for _, prop in zip(\n                range(n_data), cycle(plt.rcParams[\"axes.prop_cycle\"].by_key()[\"color\"])\n            )\n        ]\n    elif isinstance(colors, str):\n        colors = [colors for _ in range(n_data)]\n\n    if credible_interval is None:\n        credible_interval = rcParams[\"stats.credible_interval\"]\n    else:\n        if not 1 >= credible_interval > 0:\n            raise ValueError(\"The value of credible_interval should be in the interval (0, 1]\")\n\n    to_plot = [list(xarray_var_iter(data, var_names, combined=True)) for data in datasets]\n    all_labels = []\n    length_plotters = []\n    for plotters in to_plot:\n        length_plotters.append(len(plotters))\n        for var_name, selection, _ in plotters:\n            label = make_label(var_name, selection)\n            if label not in all_labels:\n                all_labels.append(label)\n    length_plotters = len(all_labels)\n    max_plots = rcParams[\"plot.max_subplots\"]\n    max_plots = length_plotters if max_plots is None else max_plots\n    if length_plotters > max_plots:\n        warnings.warn(\n            \"rcParams['plot.max_subplots'] ({max_plots}) is smaller than the number \"\n            \"of variables to plot ({len_plotters}) in plot_density, generating only \"\n            \"{max_plots} plots\".format(max_plots=max_plots, len_plotters=length_plotters),\n            UserWarning,\n        )\n        all_labels = all_labels[:max_plots]\n        to_plot = [\n            [\n                (var_name, selection, values)\n                for var_name, selection, values in plotters\n                if make_label(var_name, selection) in all_labels\n            ]\n            for plotters in to_plot\n        ]\n        length_plotters = max_plots\n    rows, cols = default_grid(length_plotters, max_cols=3)\n\n    (figsize, _, titlesize, xt_labelsize, linewidth, markersize) = _scale_fig_size(\n        figsize, textsize, rows, cols\n    )\n\n    plot_density_kwargs = dict(\n        ax=ax,\n        all_labels=all_labels,\n        to_plot=to_plot,\n        colors=colors,\n        bw=bw,\n        figsize=figsize,\n        length_plotters=length_plotters,\n        rows=rows,\n        cols=cols,\n        titlesize=titlesize,\n        xt_labelsize=xt_labelsize,\n        linewidth=linewidth,\n        markersize=markersize,\n        credible_interval=credible_interval,\n        point_estimate=point_estimate,\n        hpd_markers=hpd_markers,\n        outline=outline,\n        shade=shade,\n        n_data=n_data,\n        data_labels=data_labels,\n        backend_kwargs=backend_kwargs,\n        show=show,\n    )\n\n    if backend is None:\n        backend = rcParams[\"plot.backend\"]\n    backend = backend.lower()\n\n    if backend == \"bokeh\":\n\n        plot_density_kwargs[\"line_width\"] = plot_density_kwargs.pop(\"linewidth\")\n        plot_density_kwargs.pop(\"titlesize\")\n        plot_density_kwargs.pop(\"xt_labelsize\")\n        plot_density_kwargs.pop(\"n_data\")\n\n    # TODO: Add backend kwargs\n    plot = get_plotting_function(\"plot_density\", \"densityplot\", backend)\n    ax = plot(**plot_density_kwargs)\n    return ax\n", "path": "arviz/plots/densityplot.py"}]}