Repository: arviz-devs/arviz

Issue:
plot_forest() should maintain the order of azdata
**Describe the bug**
When using plot_forest the ordering of variable is not the same as the one in azdata. In my opinion order should be maintained across methods. I can take a look when I have a few spare minutes but currently I don't even understand how the order is determined.

**To Reproduce**
```
data = az.load_arviz_data('centered_eight')

data.posterior

<xarray.Dataset>
Dimensions:  (chain: 4, draw: 500, school: 8)
Coordinates:
  * chain    (chain) int64 0 1 2 3
  * draw     (draw) int64 0 1 2 3 4 5 6 7 8 ... 492 493 494 495 496 497 498 499
  * school   (school) object 'Choate' 'Deerfield' ... "St. Paul's" 'Mt. Hermon'
Data variables:
    mu       (chain, draw) float64 ...
    theta    (chain, draw, school) float64 ...
    tau      (chain, draw) float64 ...
Attributes:
    created_at:                 2018-10-03T14:26:54.822913
    inference_library:          pymc3
    inference_library_version:  3.5

_ = az.plot_forest(data=data, rope=(0,0), combined=True)
```
![demo](https://user-images.githubusercontent.com/28750455/54210026-0ee81f80-44df-11e9-9a4e-3feee9c74f48.png)



**Expected behavior**
The plot should begin with mu, then theta (starting with Choate school and ending with Mt. Hermon) and tau

**Additional context**
arviz 0.3.3

Color problem in plot_forest when comparing data
**Describe the bug**
The shading used to group the parameters of compared models is confusing in forest_plot() 

**To Reproduce**
```
data = az.load_arviz_data('centered_eight')
data2 = az.load_arviz_data('centered_eight')

_ = az.plot_forest(data=[data, data2], model_names=['reduced', 'full'],  rope=(0,0), combined=True, figsize=(10, 6), credible_interval=0.95 )
```
![demo](https://user-images.githubusercontent.com/28750455/54210915-ae59e200-44e0-11e9-8613-99a142dc2ef6.png)

The expected behavior is one parameter (for both models) = one color

arviz 0.3.3



Discussion:
After some investigations I saw that the ordering is quasi random... when not specifying var_names. Hence the **first** problem is that :
```
if var_names is None:
     self.var_names = list(set.union(*[set(datum.data_vars) for datum in self.data]))
else:
     self.var_names = list(reversed(var_names))  # y-values are upside down
```
Here ```list(set.union)``` Breaks var_names order when var_names is not specified by the user (ordering of tau, mu and theta is random).

**Second** the same thing seems to happen for the sub_level (schools in this example) and I don't know where it comes from for now.
By the way the randomness also affects issue #614 so they could be linked.
Thanks @GWeindel. Do you want to send a PR to fix this issue?
Sure, I just have to find a bit time to investigate the sub_level ordering and I send a PR for both.
Hi @GWeindel thanks for taking the time to report this issue. I am not able to reproduce this on master or with arviz 0.3.3.
Weird, I have it with the master or 0.3.3. As said in #613 there is some randomness in the generation of the shaded area, did you try to restart the console & run the code several times ?

Resolving patch:
diff --git a/arviz/plots/forestplot.py b/arviz/plots/forestplot.py
--- a/arviz/plots/forestplot.py
+++ b/arviz/plots/forestplot.py
@@ -1,5 +1,5 @@
 """Forest plot."""
-from collections import defaultdict
+from collections import defaultdict, OrderedDict
 from itertools import tee
 
 import numpy as np
@@ -96,14 +96,11 @@ def plot_forest(
     Returns
     -------
     gridspec : matplotlib GridSpec
-
     Examples
     --------
     Forestpĺot
-
     .. plot::
         :context: close-figs
-
         >>> import arviz as az
         >>> non_centered_data = az.load_arviz_data('non_centered_eight')
         >>> fig, axes = az.plot_forest(non_centered_data,
@@ -113,12 +110,9 @@ def plot_forest(
         >>>                            ridgeplot_overlap=3,
         >>>                            figsize=(9, 7))
         >>> axes[0].set_title('Estimated theta for 8 schools model')
-
     Ridgeplot
-
     .. plot::
         :context: close-figs
-
         >>> fig, axes = az.plot_forest(non_centered_data,
         >>>                            kind='ridgeplot',
         >>>                            var_names=['theta'],
@@ -245,7 +239,14 @@ def __init__(self, datasets, var_names, model_names, combined, colors):
         self.model_names = list(reversed(model_names))  # y-values are upside down
 
         if var_names is None:
-            self.var_names = list(set.union(*[set(datum.data_vars) for datum in self.data]))
+            if len(self.data) > 1:
+                self.var_names = list(
+                    set().union(*[OrderedDict(datum.data_vars) for datum in self.data])
+                )
+            else:
+                self.var_names = list(
+                    reversed(*[OrderedDict(datum.data_vars) for datum in self.data])
+                )
         else:
             self.var_names = list(reversed(var_names))  # y-values are upside down
 
@@ -484,7 +485,7 @@ def iterator(self):
             grouped_data = [datum.groupby("chain") for datum in self.data]
             skip_dims = set()
 
-        label_dict = {}
+        label_dict = OrderedDict()
         for name, grouped_datum in zip(self.model_names, grouped_data):
             for _, sub_data in grouped_datum:
                 datum_iter = xarray_var_iter(
@@ -496,7 +497,7 @@ def iterator(self):
                 for _, selection, values in datum_iter:
                     label = make_label(self.var_name, selection, position="beside")
                     if label not in label_dict:
-                        label_dict[label] = {}
+                        label_dict[label] = OrderedDict()
                     if name not in label_dict[label]:
                         label_dict[label][name] = []
                     label_dict[label][name].append(values)


Test patch: