prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Allow normalization in plot_parallel
  It would be great if plot_parallel had a keyword arg `normalize` (or standardize), that centers and rescales the variables before plotting. That would make it easier to see things if some posteriors are much more tight than others:
  ![grafik](https://user-images.githubusercontent.com/1882397/48769279-83424d00-ecbb-11e8-8bf3-f1df15455cd0.png)
  
  </issue>
  <code>
  [start of arviz/plots/parallelplot.py]
  1 """Parallel coordinates plot showing posterior points with and without divergences marked."""
  2 import matplotlib.pyplot as plt
  3 import numpy as np
  4 
  5 from ..data import convert_to_dataset
  6 from .plot_utils import _scale_fig_size, xarray_to_ndarray, get_coords
  7 from ..utils import _var_names
  8 
  9 
  10 def plot_parallel(
  11     data,
  12     var_names=None,
  13     coords=None,
  14     figsize=None,
  15     textsize=None,
  16     legend=True,
  17     colornd="k",
  18     colord="C1",
  19     shadend=0.025,
  20     ax=None,
  21 ):
  22     """
  23     Plot parallel coordinates plot showing posterior points with and without divergences.
  24 
  25     Described by https://arxiv.org/abs/1709.01449, suggested by Ari Hartikainen
  26 
  27     Parameters
  28     ----------
  29     data : obj
  30         Any object that can be converted to an az.InferenceData object
  31         Refer to documentation of az.convert_to_dataset for details
  32     var_names : list of variable names
  33         Variables to be plotted, if None all variable are plotted. Can be used to change the order
  34         of the plotted variables
  35     coords : mapping, optional
  36         Coordinates of var_names to be plotted. Passed to `Dataset.sel`
  37     figsize : tuple
  38         Figure size. If None it will be defined automatically.
  39     textsize: float
  40         Text size scaling factor for labels, titles and lines. If None it will be autoscaled based
  41         on figsize.
  42     legend : bool
  43         Flag for plotting legend (defaults to True)
  44     colornd : valid matplotlib color
  45         color for non-divergent points. Defaults to 'k'
  46     colord : valid matplotlib color
  47         color for divergent points. Defaults to 'C1'
  48     shadend : float
  49         Alpha blending value for non-divergent points, between 0 (invisible) and 1 (opaque).
  50         Defaults to .025
  51     ax : axes
  52         Matplotlib axes.
  53 
  54     Returns
  55     -------
  56     ax : matplotlib axes
  57     """
  58     if coords is None:
  59         coords = {}
  60 
  61     # Get diverging draws and combine chains
  62     divergent_data = convert_to_dataset(data, group="sample_stats")
  63     _, diverging_mask = xarray_to_ndarray(divergent_data, var_names=("diverging",), combined=True)
  64     diverging_mask = np.squeeze(diverging_mask)
  65 
  66     # Get posterior draws and combine chains
  67     posterior_data = convert_to_dataset(data, group="posterior")
  68     var_names = _var_names(var_names, posterior_data)
  69     var_names, _posterior = xarray_to_ndarray(
  70         get_coords(posterior_data, coords), var_names=var_names, combined=True
  71     )
  72 
  73     if len(var_names) < 2:
  74         raise ValueError("This plot needs at least two variables")
  75 
  76     figsize, _, _, xt_labelsize, _, _ = _scale_fig_size(figsize, textsize, 1, 1)
  77 
  78     if ax is None:
  79         _, ax = plt.subplots(figsize=figsize, constrained_layout=True)
  80 
  81     ax.plot(_posterior[:, ~diverging_mask], color=colornd, alpha=shadend)
  82 
  83     if np.any(diverging_mask):
  84         ax.plot(_posterior[:, diverging_mask], color=colord, lw=1)
  85 
  86     ax.tick_params(labelsize=textsize)
  87     ax.set_xticks(range(len(var_names)))
  88     ax.set_xticklabels(var_names)
  89 
  90     if legend:
  91         ax.plot([], color=colornd, label="non-divergent")
  92         if np.any(diverging_mask):
  93             ax.plot([], color=colord, label="divergent")
  94         ax.legend(fontsize=xt_labelsize)
  95 
  96     return ax
  97
  [end of arviz/plots/parallelplot.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/arviz/plots/parallelplot.py b/arviz/plots/parallelplot.py
  --- a/arviz/plots/parallelplot.py
  +++ b/arviz/plots/parallelplot.py
  @@ -2,6 +2,7 @@
   import matplotlib.pyplot as plt
   import numpy as np
   
  +from scipy.stats.mstats import rankdata
   from ..data import convert_to_dataset
   from .plot_utils import _scale_fig_size, xarray_to_ndarray, get_coords
   from ..utils import _var_names
  @@ -18,6 +19,7 @@
       colord="C1",
       shadend=0.025,
       ax=None,
  +    norm_method=None,
   ):
       """
       Plot parallel coordinates plot showing posterior points with and without divergences.
  @@ -50,10 +52,33 @@
           Defaults to .025
       ax : axes
           Matplotlib axes.
  +    norm_method : str
  +        Method for normalizing the data. Methods include normal, minmax and rank.
  +        Defaults to none.
   
       Returns
       -------
       ax : matplotlib axes
  +
  +    Examples
  +    --------
  +    Plot default parallel plot
  +
  +    .. plot::
  +        :context: close-figs
  +
  +        >>> import arviz as az
  +        >>> data = az.load_arviz_data('centered_eight')
  +        >>> az.plot_parallel(data, var_names=["mu", "tau"])
  +
  +
  +    Plot parallel plot with normalization
  +
  +    .. plot::
  +        :context: close-figs
  +
  +        >>> az.plot_parallel(data, var_names=["mu", "tau"], norm_method='normal')
  +
       """
       if coords is None:
           coords = {}
  @@ -69,9 +94,23 @@
       var_names, _posterior = xarray_to_ndarray(
           get_coords(posterior_data, coords), var_names=var_names, combined=True
       )
  -
       if len(var_names) < 2:
           raise ValueError("This plot needs at least two variables")
  +    if norm_method is not None:
  +        if norm_method == "normal":
  +            mean = np.mean(_posterior, axis=1)
  +            standard_deviation = np.std(_posterior, axis=1)
  +            for i in range(0, np.shape(mean)[0]):
  +                _posterior[i, :] = (_posterior[i, :] - mean[i]) / standard_deviation[i]
  +        elif norm_method == "minmax":
  +            min_elem = np.min(_posterior, axis=1)
  +            max_elem = np.max(_posterior, axis=1)
  +            for i in range(0, np.shape(min_elem)[0]):
  +                _posterior[i, :] = ((_posterior[i, :]) - min_elem[i]) / (max_elem[i] - min_elem[i])
  +        elif norm_method == "rank":
  +            _posterior = rankdata(_posterior, axis=1)
  +        else:
  +            raise ValueError("{} is not supported. Use normal, minmax or rank.".format(norm_method))
   
       figsize, _, _, xt_labelsize, _, _ = _scale_fig_size(figsize, textsize, 1, 1)
  
verification_info: {"golden_diff": "diff --git a/arviz/plots/parallelplot.py b/arviz/plots/parallelplot.py\n--- a/arviz/plots/parallelplot.py\n+++ b/arviz/plots/parallelplot.py\n@@ -2,6 +2,7 @@\n import matplotlib.pyplot as plt\n import numpy as np\n \n+from scipy.stats.mstats import rankdata\n from ..data import convert_to_dataset\n from .plot_utils import _scale_fig_size, xarray_to_ndarray, get_coords\n from ..utils import _var_names\n@@ -18,6 +19,7 @@\n     colord=\"C1\",\n     shadend=0.025,\n     ax=None,\n+    norm_method=None,\n ):\n     \"\"\"\n     Plot parallel coordinates plot showing posterior points with and without divergences.\n@@ -50,10 +52,33 @@\n         Defaults to .025\n     ax : axes\n         Matplotlib axes.\n+    norm_method : str\n+        Method for normalizing the data. Methods include normal, minmax and rank.\n+        Defaults to none.\n \n     Returns\n     -------\n     ax : matplotlib axes\n+\n+    Examples\n+    --------\n+    Plot default parallel plot\n+\n+    .. plot::\n+        :context: close-figs\n+\n+        >>> import arviz as az\n+        >>> data = az.load_arviz_data('centered_eight')\n+        >>> az.plot_parallel(data, var_names=[\"mu\", \"tau\"])\n+\n+\n+    Plot parallel plot with normalization\n+\n+    .. plot::\n+        :context: close-figs\n+\n+        >>> az.plot_parallel(data, var_names=[\"mu\", \"tau\"], norm_method='normal')\n+\n     \"\"\"\n     if coords is None:\n         coords = {}\n@@ -69,9 +94,23 @@\n     var_names, _posterior = xarray_to_ndarray(\n         get_coords(posterior_data, coords), var_names=var_names, combined=True\n     )\n-\n     if len(var_names) < 2:\n         raise ValueError(\"This plot needs at least two variables\")\n+    if norm_method is not None:\n+        if norm_method == \"normal\":\n+            mean = np.mean(_posterior, axis=1)\n+            standard_deviation = np.std(_posterior, axis=1)\n+            for i in range(0, np.shape(mean)[0]):\n+                _posterior[i, :] = (_posterior[i, :] - mean[i]) / standard_deviation[i]\n+        elif norm_method == \"minmax\":\n+            min_elem = np.min(_posterior, axis=1)\n+            max_elem = np.max(_posterior, axis=1)\n+            for i in range(0, np.shape(min_elem)[0]):\n+                _posterior[i, :] = ((_posterior[i, :]) - min_elem[i]) / (max_elem[i] - min_elem[i])\n+        elif norm_method == \"rank\":\n+            _posterior = rankdata(_posterior, axis=1)\n+        else:\n+            raise ValueError(\"{} is not supported. Use normal, minmax or rank.\".format(norm_method))\n \n     figsize, _, _, xt_labelsize, _, _ = _scale_fig_size(figsize, textsize, 1, 1)\n", "issue": "Allow normalization in plot_parallel\nIt would be great if plot_parallel had a keyword arg `normalize` (or standardize), that centers and rescales the variables before plotting. That would make it easier to see things if some posteriors are much more tight than others:\r\n![grafik](https://user-images.githubusercontent.com/1882397/48769279-83424d00-ecbb-11e8-8bf3-f1df15455cd0.png)\n", "before_files": [{"content": "\"\"\"Parallel coordinates plot showing posterior points with and without divergences marked.\"\"\"\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrom ..data import convert_to_dataset\nfrom .plot_utils import _scale_fig_size, xarray_to_ndarray, get_coords\nfrom ..utils import _var_names\n\n\ndef plot_parallel(\n    data,\n    var_names=None,\n    coords=None,\n    figsize=None,\n    textsize=None,\n    legend=True,\n    colornd=\"k\",\n    colord=\"C1\",\n    shadend=0.025,\n    ax=None,\n):\n    \"\"\"\n    Plot parallel coordinates plot showing posterior points with and without divergences.\n\n    Described by https://arxiv.org/abs/1709.01449, suggested by Ari Hartikainen\n\n    Parameters\n    ----------\n    data : obj\n        Any object that can be converted to an az.InferenceData object\n        Refer to documentation of az.convert_to_dataset for details\n    var_names : list of variable names\n        Variables to be plotted, if None all variable are plotted. Can be used to change the order\n        of the plotted variables\n    coords : mapping, optional\n        Coordinates of var_names to be plotted. Passed to `Dataset.sel`\n    figsize : tuple\n        Figure size. If None it will be defined automatically.\n    textsize: float\n        Text size scaling factor for labels, titles and lines. If None it will be autoscaled based\n        on figsize.\n    legend : bool\n        Flag for plotting legend (defaults to True)\n    colornd : valid matplotlib color\n        color for non-divergent points. Defaults to 'k'\n    colord : valid matplotlib color\n        color for divergent points. Defaults to 'C1'\n    shadend : float\n        Alpha blending value for non-divergent points, between 0 (invisible) and 1 (opaque).\n        Defaults to .025\n    ax : axes\n        Matplotlib axes.\n\n    Returns\n    -------\n    ax : matplotlib axes\n    \"\"\"\n    if coords is None:\n        coords = {}\n\n    # Get diverging draws and combine chains\n    divergent_data = convert_to_dataset(data, group=\"sample_stats\")\n    _, diverging_mask = xarray_to_ndarray(divergent_data, var_names=(\"diverging\",), combined=True)\n    diverging_mask = np.squeeze(diverging_mask)\n\n    # Get posterior draws and combine chains\n    posterior_data = convert_to_dataset(data, group=\"posterior\")\n    var_names = _var_names(var_names, posterior_data)\n    var_names, _posterior = xarray_to_ndarray(\n        get_coords(posterior_data, coords), var_names=var_names, combined=True\n    )\n\n    if len(var_names) < 2:\n        raise ValueError(\"This plot needs at least two variables\")\n\n    figsize, _, _, xt_labelsize, _, _ = _scale_fig_size(figsize, textsize, 1, 1)\n\n    if ax is None:\n        _, ax = plt.subplots(figsize=figsize, constrained_layout=True)\n\n    ax.plot(_posterior[:, ~diverging_mask], color=colornd, alpha=shadend)\n\n    if np.any(diverging_mask):\n        ax.plot(_posterior[:, diverging_mask], color=colord, lw=1)\n\n    ax.tick_params(labelsize=textsize)\n    ax.set_xticks(range(len(var_names)))\n    ax.set_xticklabels(var_names)\n\n    if legend:\n        ax.plot([], color=colornd, label=\"non-divergent\")\n        if np.any(diverging_mask):\n            ax.plot([], color=colord, label=\"divergent\")\n        ax.legend(fontsize=xt_labelsize)\n\n    return ax\n", "path": "arviz/plots/parallelplot.py"}]}