We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
xlim of traceplot does not cover all range of values
## Description of your problem

xlim of traceplot may not cover all range of traces for discrete variables. For example, if I get two chains: one with mean 28, another one with mean 32. Then the traceplot will show only one bar at x=28 and xlim from 27.5 to 28.5.

![arcolinux_2019-01-27_16-01-25](https://user-images.githubusercontent.com/2173206/51797762-f7b1e300-224c-11e9-8679-44fa1c58d1db.png)

For discrete values I used DiscreteUniform:
```python
timestep=1.5
with pm.Model() as model_two_switches_11:
    delaymean = pm.Uniform('delaymean',1,28,shape=3)
    k = pm.Uniform('k',0.8,8,shape=3)
    
    switch1 = pm.DiscreteUniform('switch1',df['T'].min()//7,df['T'].max()//7-timestep-1)
    switch2 = pm.DiscreteUniform('switch2',switch1+timestep+1,df['T'].max()//7)
    
    idx = tt.switch(df['t'].values>=(switch1*7),0,1)+tt.switch(df['t'].values>=(switch2*7),0,1)
    
    θ = delaymean/tt.gamma(1+1/k)
    delaysd = pm.Deterministic('delaysd',delaymean/tt.gamma(1+1/k)*tt.sqrt(tt.gamma(1+2/k)-tt.gamma(1+1/k)**2))
    
    delay_p = (1-tt.exp(-(df['δt0'].values/θ[idx])**k[idx]))/(1-tt.exp(-(df['δt'].values/θ[idx])**k[idx]))
    
    confirmed = pm.Poisson('confirmed',\
                    mu=df['confirmed'].values*delay_p+0.001,\
                    observed=df['confirmed0'].values)
    
    start = {'switch1': 22, 'switch2': 28}
    step = pm.Slice([switch1,switch2])
    trace_two_switches_11 = pm.sample(number_of_iterations, tune=length_of_tunein, cores = number_of_jobs,
                                      start=start, step=step)

model_two_switches_11.name = 'Two switches_11'

vrnames = ['switch1','switch2','delaymean','delaysd']
pm.traceplot(trace_two_switches_11,varnames=vrnames);
pm.summary(trace_two_switches_11)
```

ps: I assume that it's because the fraction of those points outside of chosen xlim-range is rather small, but it would be nice to see the consistent picture between left and right panels

## Versions and main components

* PyMC3 Version: 3.6
* Theano Version: 1.0.3
* Python Version: 3.7.1
* Operating system: linux
* How did you install PyMC3: (conda/pip) latest version from github

--- 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/traceplot.py`
Content:
```
1 """Plot histogram and values from MCMC samples."""
2 import matplotlib.pyplot as plt
3 import numpy as np
4 
5 from ..data import convert_to_dataset
6 from .kdeplot import plot_kde
7 from .plot_utils import _scale_fig_size, get_bins, xarray_var_iter, make_label, get_coords
8 from ..utils import _var_names
9 
10 
11 def plot_trace(
12     data,
13     var_names=None,
14     coords=None,
15     divergences="bottom",
16     figsize=None,
17     textsize=None,
18     lines=None,
19     combined=False,
20     kde_kwargs=None,
21     hist_kwargs=None,
22     trace_kwargs=None,
23 ):
24     """Plot samples histograms and values.
25 
26     If `divergences` data is available in `sample_stats`, will plot the location of divergences as
27     dashed vertical lines.
28 
29     Parameters
30     ----------
31     data : obj
32         Any object that can be converted to an az.InferenceData object
33         Refer to documentation of az.convert_to_dataset for details
34     var_names : list of variable names
35         Variables to be plotted, two variables are required.
36     coords : mapping, optional
37         Coordinates of var_names to be plotted. Passed to `Dataset.sel`
38     divergences : {"bottom", "top", None, False}
39         Plot location of divergences on the traceplots. Options are "bottom", "top", or False-y.
40     figsize : figure size tuple
41         If None, size is (12, variables * 2)
42     textsize: float
43         Text size scaling factor for labels, titles and lines. If None it will be autoscaled based
44         on figsize.
45     lines : tuple
46         Tuple of (var_name, {'coord': selection}, [line, positions]) to be overplotted as
47         vertical lines on the density and horizontal lines on the trace.
48     combined : bool
49         Flag for combining multiple chains into a single line. If False (default), chains will be
50         plotted separately.
51     kde_kwargs : dict
52         Extra keyword arguments passed to `arviz.plot_kde`. Only affects continuous variables.
53     hist_kwargs : dict
54         Extra keyword arguments passed to `plt.hist`. Only affects discrete variables.
55     trace_kwargs : dict
56         Extra keyword arguments passed to `plt.plot`
57     Returns
58     -------
59     axes : matplotlib axes
60 
61 
62     Examples
63     --------
64     Plot a subset variables
65 
66     .. plot::
67         :context: close-figs
68 
69         >>> import arviz as az
70         >>> data = az.load_arviz_data('non_centered_eight')
71         >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}
72         >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords)
73 
74     Combine all chains into one distribution and trace
75 
76     .. plot::
77         :context: close-figs
78 
79         >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}
80         >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords, combined=True)
81 
82 
83     Plot reference lines against distribution and trace
84 
85     .. plot::
86         :context: close-figs
87 
88         >>> lines = (('theta_t',{'theta_t_dim_0':0}, [-1]),)
89         >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}
90         >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords, lines=lines)
91     """
92     if divergences:
93         try:
94             divergence_data = convert_to_dataset(data, group="sample_stats").diverging
95         except (ValueError, AttributeError):  # No sample_stats, or no `.diverging`
96             divergences = False
97 
98     data = convert_to_dataset(data, group="posterior")
99     var_names = _var_names(var_names, data)
100 
101     if coords is None:
102         coords = {}
103 
104     if lines is None:
105         lines = ()
106 
107     plotters = list(xarray_var_iter(get_coords(data, coords), var_names=var_names, combined=True))
108 
109     if figsize is None:
110         figsize = (12, len(plotters) * 2)
111 
112     if trace_kwargs is None:
113         trace_kwargs = {}
114 
115     trace_kwargs.setdefault("alpha", 0.35)
116 
117     if kde_kwargs is None:
118         kde_kwargs = {}
119 
120     if hist_kwargs is None:
121         hist_kwargs = {}
122 
123     hist_kwargs.setdefault("alpha", 0.35)
124 
125     figsize, _, titlesize, xt_labelsize, linewidth, _ = _scale_fig_size(
126         figsize, textsize, rows=len(plotters), cols=2
127     )
128     trace_kwargs.setdefault("linewidth", linewidth)
129     kde_kwargs.setdefault("plot_kwargs", {"linewidth": linewidth})
130 
131     _, axes = plt.subplots(
132         len(plotters), 2, squeeze=False, figsize=figsize, constrained_layout=True
133     )
134 
135     colors = {}
136     for idx, (var_name, selection, value) in enumerate(plotters):
137         colors[idx] = []
138         if combined:
139             value = value.flatten()
140         value = np.atleast_2d(value)
141 
142         for row in value:
143             axes[idx, 1].plot(np.arange(len(row)), row, **trace_kwargs)
144 
145             colors[idx].append(axes[idx, 1].get_lines()[-1].get_color())
146             kde_kwargs["plot_kwargs"]["color"] = colors[idx][-1]
147             if row.dtype.kind == "i":
148                 _histplot_op(axes[idx, 0], row, **hist_kwargs)
149             else:
150                 plot_kde(row, textsize=xt_labelsize, ax=axes[idx, 0], **kde_kwargs)
151 
152         axes[idx, 0].set_yticks([])
153         for col in (0, 1):
154             axes[idx, col].set_title(make_label(var_name, selection), fontsize=titlesize, wrap=True)
155             axes[idx, col].tick_params(labelsize=xt_labelsize)
156 
157         xlims = [ax.get_xlim() for ax in axes[idx, :]]
158         ylims = [ax.get_ylim() for ax in axes[idx, :]]
159 
160         if divergences:
161             div_selection = {k: v for k, v in selection.items() if k in divergence_data.dims}
162             divs = divergence_data.sel(**div_selection).values
163             if combined:
164                 divs = divs.flatten()
165             divs = np.atleast_2d(divs)
166 
167             for chain, chain_divs in enumerate(divs):
168                 div_idxs = np.arange(len(chain_divs))[chain_divs]
169                 if div_idxs.size > 0:
170                     if divergences == "top":
171                         ylocs = [ylim[1] for ylim in ylims]
172                     else:
173                         ylocs = [ylim[0] for ylim in ylims]
174                     values = value[chain, div_idxs]
175                     axes[idx, 1].plot(
176                         div_idxs,
177                         np.zeros_like(div_idxs) + ylocs[1],
178                         marker="|",
179                         color="black",
180                         markeredgewidth=1.5,
181                         markersize=30,
182                         linestyle="None",
183                         alpha=hist_kwargs["alpha"],
184                         zorder=-5,
185                     )
186                     axes[idx, 1].set_ylim(*ylims[1])
187                     axes[idx, 0].plot(
188                         values,
189                         np.zeros_like(values) + ylocs[0],
190                         marker="|",
191                         color="black",
192                         markeredgewidth=1.5,
193                         markersize=30,
194                         linestyle="None",
195                         alpha=trace_kwargs["alpha"],
196                         zorder=-5,
197                     )
198                     axes[idx, 0].set_ylim(*ylims[0])
199 
200         for _, _, vlines in (j for j in lines if j[0] == var_name and j[1] == selection):
201             if isinstance(vlines, (float, int)):
202                 line_values = [vlines]
203             else:
204                 line_values = np.atleast_1d(vlines).ravel()
205             axes[idx, 0].vlines(
206                 line_values, *ylims[0], colors=colors[idx][0], linewidth=1.5, alpha=0.75
207             )
208             axes[idx, 1].hlines(
209                 line_values,
210                 *xlims[1],
211                 colors=colors[idx][0],
212                 linewidth=1.5,
213                 alpha=trace_kwargs["alpha"]
214             )
215         axes[idx, 0].set_ylim(bottom=0, top=ylims[0][1])
216         axes[idx, 1].set_xlim(left=0, right=data.draw.max())
217         axes[idx, 1].set_ylim(*ylims[1])
218     return axes
219 
220 
221 def _histplot_op(ax, data, **kwargs):
222     """Add a histogram for the data to the axes."""
223     bins = get_bins(data)
224     ax.hist(data, bins=bins, align="left", density=True, **kwargs)
225     xticks = get_bins(data, max_bins=10, fenceposts=1)
226     ax.set_xticks(xticks)
227     return ax
228
```
--- 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/traceplot.py b/arviz/plots/traceplot.py
--- a/arviz/plots/traceplot.py
+++ b/arviz/plots/traceplot.py
@@ -149,6 +149,9 @@
             else:
                 plot_kde(row, textsize=xt_labelsize, ax=axes[idx, 0], **kde_kwargs)
 
+        if value[0].dtype.kind == "i":
+            xticks = get_bins(value, max_bins=10, fenceposts=1)
+            axes[idx, 0].set_xticks(xticks)
         axes[idx, 0].set_yticks([])
         for col in (0, 1):
             axes[idx, col].set_title(make_label(var_name, selection), fontsize=titlesize, wrap=True)
@@ -222,6 +225,4 @@
     """Add a histogram for the data to the axes."""
     bins = get_bins(data)
     ax.hist(data, bins=bins, align="left", density=True, **kwargs)
-    xticks = get_bins(data, max_bins=10, fenceposts=1)
-    ax.set_xticks(xticks)
     return ax

{"golden_diff": "diff --git a/arviz/plots/traceplot.py b/arviz/plots/traceplot.py\n--- a/arviz/plots/traceplot.py\n+++ b/arviz/plots/traceplot.py\n@@ -149,6 +149,9 @@\n             else:\n                 plot_kde(row, textsize=xt_labelsize, ax=axes[idx, 0], **kde_kwargs)\n \n+        if value[0].dtype.kind == \"i\":\n+            xticks = get_bins(value, max_bins=10, fenceposts=1)\n+            axes[idx, 0].set_xticks(xticks)\n         axes[idx, 0].set_yticks([])\n         for col in (0, 1):\n             axes[idx, col].set_title(make_label(var_name, selection), fontsize=titlesize, wrap=True)\n@@ -222,6 +225,4 @@\n     \"\"\"Add a histogram for the data to the axes.\"\"\"\n     bins = get_bins(data)\n     ax.hist(data, bins=bins, align=\"left\", density=True, **kwargs)\n-    xticks = get_bins(data, max_bins=10, fenceposts=1)\n-    ax.set_xticks(xticks)\n     return ax\n", "issue": "xlim of traceplot does not cover all range of values\n## Description of your problem\r\n\r\nxlim of traceplot may not cover all range of traces for discrete variables. For example, if I get two chains: one with mean 28, another one with mean 32. Then the traceplot will show only one bar at x=28 and xlim from 27.5 to 28.5.\r\n\r\n![arcolinux_2019-01-27_16-01-25](https://user-images.githubusercontent.com/2173206/51797762-f7b1e300-224c-11e9-8679-44fa1c58d1db.png)\r\n\r\nFor discrete values I used DiscreteUniform:\r\n```python\r\ntimestep=1.5\r\nwith pm.Model() as model_two_switches_11:\r\n    delaymean = pm.Uniform('delaymean',1,28,shape=3)\r\n    k = pm.Uniform('k',0.8,8,shape=3)\r\n    \r\n    switch1 = pm.DiscreteUniform('switch1',df['T'].min()//7,df['T'].max()//7-timestep-1)\r\n    switch2 = pm.DiscreteUniform('switch2',switch1+timestep+1,df['T'].max()//7)\r\n    \r\n    idx = tt.switch(df['t'].values>=(switch1*7),0,1)+tt.switch(df['t'].values>=(switch2*7),0,1)\r\n    \r\n    \u03b8 = delaymean/tt.gamma(1+1/k)\r\n    delaysd = pm.Deterministic('delaysd',delaymean/tt.gamma(1+1/k)*tt.sqrt(tt.gamma(1+2/k)-tt.gamma(1+1/k)**2))\r\n    \r\n    delay_p = (1-tt.exp(-(df['\u03b4t0'].values/\u03b8[idx])**k[idx]))/(1-tt.exp(-(df['\u03b4t'].values/\u03b8[idx])**k[idx]))\r\n    \r\n    confirmed = pm.Poisson('confirmed',\\\r\n                    mu=df['confirmed'].values*delay_p+0.001,\\\r\n                    observed=df['confirmed0'].values)\r\n    \r\n    start = {'switch1': 22, 'switch2': 28}\r\n    step = pm.Slice([switch1,switch2])\r\n    trace_two_switches_11 = pm.sample(number_of_iterations, tune=length_of_tunein, cores = number_of_jobs,\r\n                                      start=start, step=step)\r\n\r\nmodel_two_switches_11.name = 'Two switches_11'\r\n\r\nvrnames = ['switch1','switch2','delaymean','delaysd']\r\npm.traceplot(trace_two_switches_11,varnames=vrnames);\r\npm.summary(trace_two_switches_11)\r\n```\r\n\r\nps: I assume that it's because the fraction of those points outside of chosen xlim-range is rather small, but it would be nice to see the consistent picture between left and right panels\r\n\r\n## Versions and main components\r\n\r\n* PyMC3 Version: 3.6\r\n* Theano Version: 1.0.3\r\n* Python Version: 3.7.1\r\n* Operating system: linux\r\n* How did you install PyMC3: (conda/pip) latest version from github\n", "before_files": [{"content": "\"\"\"Plot histogram and values from MCMC samples.\"\"\"\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrom ..data import convert_to_dataset\nfrom .kdeplot import plot_kde\nfrom .plot_utils import _scale_fig_size, get_bins, xarray_var_iter, make_label, get_coords\nfrom ..utils import _var_names\n\n\ndef plot_trace(\n    data,\n    var_names=None,\n    coords=None,\n    divergences=\"bottom\",\n    figsize=None,\n    textsize=None,\n    lines=None,\n    combined=False,\n    kde_kwargs=None,\n    hist_kwargs=None,\n    trace_kwargs=None,\n):\n    \"\"\"Plot samples histograms and values.\n\n    If `divergences` data is available in `sample_stats`, will plot the location of divergences as\n    dashed vertical lines.\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, two variables are required.\n    coords : mapping, optional\n        Coordinates of var_names to be plotted. Passed to `Dataset.sel`\n    divergences : {\"bottom\", \"top\", None, False}\n        Plot location of divergences on the traceplots. Options are \"bottom\", \"top\", or False-y.\n    figsize : figure size tuple\n        If None, size is (12, variables * 2)\n    textsize: float\n        Text size scaling factor for labels, titles and lines. If None it will be autoscaled based\n        on figsize.\n    lines : tuple\n        Tuple of (var_name, {'coord': selection}, [line, positions]) to be overplotted as\n        vertical lines on the density and horizontal lines on the trace.\n    combined : bool\n        Flag for combining multiple chains into a single line. If False (default), chains will be\n        plotted separately.\n    kde_kwargs : dict\n        Extra keyword arguments passed to `arviz.plot_kde`. Only affects continuous variables.\n    hist_kwargs : dict\n        Extra keyword arguments passed to `plt.hist`. Only affects discrete variables.\n    trace_kwargs : dict\n        Extra keyword arguments passed to `plt.plot`\n    Returns\n    -------\n    axes : matplotlib axes\n\n\n    Examples\n    --------\n    Plot a subset variables\n\n    .. plot::\n        :context: close-figs\n\n        >>> import arviz as az\n        >>> data = az.load_arviz_data('non_centered_eight')\n        >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}\n        >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords)\n\n    Combine all chains into one distribution and trace\n\n    .. plot::\n        :context: close-figs\n\n        >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}\n        >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords, combined=True)\n\n\n    Plot reference lines against distribution and trace\n\n    .. plot::\n        :context: close-figs\n\n        >>> lines = (('theta_t',{'theta_t_dim_0':0}, [-1]),)\n        >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}\n        >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords, lines=lines)\n    \"\"\"\n    if divergences:\n        try:\n            divergence_data = convert_to_dataset(data, group=\"sample_stats\").diverging\n        except (ValueError, AttributeError):  # No sample_stats, or no `.diverging`\n            divergences = False\n\n    data = convert_to_dataset(data, group=\"posterior\")\n    var_names = _var_names(var_names, data)\n\n    if coords is None:\n        coords = {}\n\n    if lines is None:\n        lines = ()\n\n    plotters = list(xarray_var_iter(get_coords(data, coords), var_names=var_names, combined=True))\n\n    if figsize is None:\n        figsize = (12, len(plotters) * 2)\n\n    if trace_kwargs is None:\n        trace_kwargs = {}\n\n    trace_kwargs.setdefault(\"alpha\", 0.35)\n\n    if kde_kwargs is None:\n        kde_kwargs = {}\n\n    if hist_kwargs is None:\n        hist_kwargs = {}\n\n    hist_kwargs.setdefault(\"alpha\", 0.35)\n\n    figsize, _, titlesize, xt_labelsize, linewidth, _ = _scale_fig_size(\n        figsize, textsize, rows=len(plotters), cols=2\n    )\n    trace_kwargs.setdefault(\"linewidth\", linewidth)\n    kde_kwargs.setdefault(\"plot_kwargs\", {\"linewidth\": linewidth})\n\n    _, axes = plt.subplots(\n        len(plotters), 2, squeeze=False, figsize=figsize, constrained_layout=True\n    )\n\n    colors = {}\n    for idx, (var_name, selection, value) in enumerate(plotters):\n        colors[idx] = []\n        if combined:\n            value = value.flatten()\n        value = np.atleast_2d(value)\n\n        for row in value:\n            axes[idx, 1].plot(np.arange(len(row)), row, **trace_kwargs)\n\n            colors[idx].append(axes[idx, 1].get_lines()[-1].get_color())\n            kde_kwargs[\"plot_kwargs\"][\"color\"] = colors[idx][-1]\n            if row.dtype.kind == \"i\":\n                _histplot_op(axes[idx, 0], row, **hist_kwargs)\n            else:\n                plot_kde(row, textsize=xt_labelsize, ax=axes[idx, 0], **kde_kwargs)\n\n        axes[idx, 0].set_yticks([])\n        for col in (0, 1):\n            axes[idx, col].set_title(make_label(var_name, selection), fontsize=titlesize, wrap=True)\n            axes[idx, col].tick_params(labelsize=xt_labelsize)\n\n        xlims = [ax.get_xlim() for ax in axes[idx, :]]\n        ylims = [ax.get_ylim() for ax in axes[idx, :]]\n\n        if divergences:\n            div_selection = {k: v for k, v in selection.items() if k in divergence_data.dims}\n            divs = divergence_data.sel(**div_selection).values\n            if combined:\n                divs = divs.flatten()\n            divs = np.atleast_2d(divs)\n\n            for chain, chain_divs in enumerate(divs):\n                div_idxs = np.arange(len(chain_divs))[chain_divs]\n                if div_idxs.size > 0:\n                    if divergences == \"top\":\n                        ylocs = [ylim[1] for ylim in ylims]\n                    else:\n                        ylocs = [ylim[0] for ylim in ylims]\n                    values = value[chain, div_idxs]\n                    axes[idx, 1].plot(\n                        div_idxs,\n                        np.zeros_like(div_idxs) + ylocs[1],\n                        marker=\"|\",\n                        color=\"black\",\n                        markeredgewidth=1.5,\n                        markersize=30,\n                        linestyle=\"None\",\n                        alpha=hist_kwargs[\"alpha\"],\n                        zorder=-5,\n                    )\n                    axes[idx, 1].set_ylim(*ylims[1])\n                    axes[idx, 0].plot(\n                        values,\n                        np.zeros_like(values) + ylocs[0],\n                        marker=\"|\",\n                        color=\"black\",\n                        markeredgewidth=1.5,\n                        markersize=30,\n                        linestyle=\"None\",\n                        alpha=trace_kwargs[\"alpha\"],\n                        zorder=-5,\n                    )\n                    axes[idx, 0].set_ylim(*ylims[0])\n\n        for _, _, vlines in (j for j in lines if j[0] == var_name and j[1] == selection):\n            if isinstance(vlines, (float, int)):\n                line_values = [vlines]\n            else:\n                line_values = np.atleast_1d(vlines).ravel()\n            axes[idx, 0].vlines(\n                line_values, *ylims[0], colors=colors[idx][0], linewidth=1.5, alpha=0.75\n            )\n            axes[idx, 1].hlines(\n                line_values,\n                *xlims[1],\n                colors=colors[idx][0],\n                linewidth=1.5,\n                alpha=trace_kwargs[\"alpha\"]\n            )\n        axes[idx, 0].set_ylim(bottom=0, top=ylims[0][1])\n        axes[idx, 1].set_xlim(left=0, right=data.draw.max())\n        axes[idx, 1].set_ylim(*ylims[1])\n    return axes\n\n\ndef _histplot_op(ax, data, **kwargs):\n    \"\"\"Add a histogram for the data to the axes.\"\"\"\n    bins = get_bins(data)\n    ax.hist(data, bins=bins, align=\"left\", density=True, **kwargs)\n    xticks = get_bins(data, max_bins=10, fenceposts=1)\n    ax.set_xticks(xticks)\n    return ax\n", "path": "arviz/plots/traceplot.py"}], "after_files": [{"content": "\"\"\"Plot histogram and values from MCMC samples.\"\"\"\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nfrom ..data import convert_to_dataset\nfrom .kdeplot import plot_kde\nfrom .plot_utils import _scale_fig_size, get_bins, xarray_var_iter, make_label, get_coords\nfrom ..utils import _var_names\n\n\ndef plot_trace(\n    data,\n    var_names=None,\n    coords=None,\n    divergences=\"bottom\",\n    figsize=None,\n    textsize=None,\n    lines=None,\n    combined=False,\n    kde_kwargs=None,\n    hist_kwargs=None,\n    trace_kwargs=None,\n):\n    \"\"\"Plot samples histograms and values.\n\n    If `divergences` data is available in `sample_stats`, will plot the location of divergences as\n    dashed vertical lines.\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, two variables are required.\n    coords : mapping, optional\n        Coordinates of var_names to be plotted. Passed to `Dataset.sel`\n    divergences : {\"bottom\", \"top\", None, False}\n        Plot location of divergences on the traceplots. Options are \"bottom\", \"top\", or False-y.\n    figsize : figure size tuple\n        If None, size is (12, variables * 2)\n    textsize: float\n        Text size scaling factor for labels, titles and lines. If None it will be autoscaled based\n        on figsize.\n    lines : tuple\n        Tuple of (var_name, {'coord': selection}, [line, positions]) to be overplotted as\n        vertical lines on the density and horizontal lines on the trace.\n    combined : bool\n        Flag for combining multiple chains into a single line. If False (default), chains will be\n        plotted separately.\n    kde_kwargs : dict\n        Extra keyword arguments passed to `arviz.plot_kde`. Only affects continuous variables.\n    hist_kwargs : dict\n        Extra keyword arguments passed to `plt.hist`. Only affects discrete variables.\n    trace_kwargs : dict\n        Extra keyword arguments passed to `plt.plot`\n    Returns\n    -------\n    axes : matplotlib axes\n\n\n    Examples\n    --------\n    Plot a subset variables\n\n    .. plot::\n        :context: close-figs\n\n        >>> import arviz as az\n        >>> data = az.load_arviz_data('non_centered_eight')\n        >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}\n        >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords)\n\n    Combine all chains into one distribution and trace\n\n    .. plot::\n        :context: close-figs\n\n        >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}\n        >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords, combined=True)\n\n\n    Plot reference lines against distribution and trace\n\n    .. plot::\n        :context: close-figs\n\n        >>> lines = (('theta_t',{'theta_t_dim_0':0}, [-1]),)\n        >>> coords = {'theta_t_dim_0': [0, 1], 'school':['Lawrenceville']}\n        >>> az.plot_trace(data, var_names=('theta_t', 'theta'), coords=coords, lines=lines)\n    \"\"\"\n    if divergences:\n        try:\n            divergence_data = convert_to_dataset(data, group=\"sample_stats\").diverging\n        except (ValueError, AttributeError):  # No sample_stats, or no `.diverging`\n            divergences = False\n\n    data = convert_to_dataset(data, group=\"posterior\")\n    var_names = _var_names(var_names, data)\n\n    if coords is None:\n        coords = {}\n\n    if lines is None:\n        lines = ()\n\n    plotters = list(xarray_var_iter(get_coords(data, coords), var_names=var_names, combined=True))\n\n    if figsize is None:\n        figsize = (12, len(plotters) * 2)\n\n    if trace_kwargs is None:\n        trace_kwargs = {}\n\n    trace_kwargs.setdefault(\"alpha\", 0.35)\n\n    if kde_kwargs is None:\n        kde_kwargs = {}\n\n    if hist_kwargs is None:\n        hist_kwargs = {}\n\n    hist_kwargs.setdefault(\"alpha\", 0.35)\n\n    figsize, _, titlesize, xt_labelsize, linewidth, _ = _scale_fig_size(\n        figsize, textsize, rows=len(plotters), cols=2\n    )\n    trace_kwargs.setdefault(\"linewidth\", linewidth)\n    kde_kwargs.setdefault(\"plot_kwargs\", {\"linewidth\": linewidth})\n\n    _, axes = plt.subplots(\n        len(plotters), 2, squeeze=False, figsize=figsize, constrained_layout=True\n    )\n\n    colors = {}\n    for idx, (var_name, selection, value) in enumerate(plotters):\n        colors[idx] = []\n        if combined:\n            value = value.flatten()\n        value = np.atleast_2d(value)\n\n        for row in value:\n            axes[idx, 1].plot(np.arange(len(row)), row, **trace_kwargs)\n\n            colors[idx].append(axes[idx, 1].get_lines()[-1].get_color())\n            kde_kwargs[\"plot_kwargs\"][\"color\"] = colors[idx][-1]\n            if row.dtype.kind == \"i\":\n                _histplot_op(axes[idx, 0], row, **hist_kwargs)\n            else:\n                plot_kde(row, textsize=xt_labelsize, ax=axes[idx, 0], **kde_kwargs)\n\n        if value[0].dtype.kind == \"i\":\n            xticks = get_bins(value, max_bins=10, fenceposts=1)\n            axes[idx, 0].set_xticks(xticks)\n        axes[idx, 0].set_yticks([])\n        for col in (0, 1):\n            axes[idx, col].set_title(make_label(var_name, selection), fontsize=titlesize, wrap=True)\n            axes[idx, col].tick_params(labelsize=xt_labelsize)\n\n        xlims = [ax.get_xlim() for ax in axes[idx, :]]\n        ylims = [ax.get_ylim() for ax in axes[idx, :]]\n\n        if divergences:\n            div_selection = {k: v for k, v in selection.items() if k in divergence_data.dims}\n            divs = divergence_data.sel(**div_selection).values\n            if combined:\n                divs = divs.flatten()\n            divs = np.atleast_2d(divs)\n\n            for chain, chain_divs in enumerate(divs):\n                div_idxs = np.arange(len(chain_divs))[chain_divs]\n                if div_idxs.size > 0:\n                    if divergences == \"top\":\n                        ylocs = [ylim[1] for ylim in ylims]\n                    else:\n                        ylocs = [ylim[0] for ylim in ylims]\n                    values = value[chain, div_idxs]\n                    axes[idx, 1].plot(\n                        div_idxs,\n                        np.zeros_like(div_idxs) + ylocs[1],\n                        marker=\"|\",\n                        color=\"black\",\n                        markeredgewidth=1.5,\n                        markersize=30,\n                        linestyle=\"None\",\n                        alpha=hist_kwargs[\"alpha\"],\n                        zorder=-5,\n                    )\n                    axes[idx, 1].set_ylim(*ylims[1])\n                    axes[idx, 0].plot(\n                        values,\n                        np.zeros_like(values) + ylocs[0],\n                        marker=\"|\",\n                        color=\"black\",\n                        markeredgewidth=1.5,\n                        markersize=30,\n                        linestyle=\"None\",\n                        alpha=trace_kwargs[\"alpha\"],\n                        zorder=-5,\n                    )\n                    axes[idx, 0].set_ylim(*ylims[0])\n\n        for _, _, vlines in (j for j in lines if j[0] == var_name and j[1] == selection):\n            if isinstance(vlines, (float, int)):\n                line_values = [vlines]\n            else:\n                line_values = np.atleast_1d(vlines).ravel()\n            axes[idx, 0].vlines(\n                line_values, *ylims[0], colors=colors[idx][0], linewidth=1.5, alpha=0.75\n            )\n            axes[idx, 1].hlines(\n                line_values,\n                *xlims[1],\n                colors=colors[idx][0],\n                linewidth=1.5,\n                alpha=trace_kwargs[\"alpha\"]\n            )\n        axes[idx, 0].set_ylim(bottom=0, top=ylims[0][1])\n        axes[idx, 1].set_xlim(left=0, right=data.draw.max())\n        axes[idx, 1].set_ylim(*ylims[1])\n    return axes\n\n\ndef _histplot_op(ax, data, **kwargs):\n    \"\"\"Add a histogram for the data to the axes.\"\"\"\n    bins = get_bins(data)\n    ax.hist(data, bins=bins, align=\"left\", density=True, **kwargs)\n    return ax\n", "path": "arviz/plots/traceplot.py"}]}