Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change kde limits and hdi computation #1215

Merged
merged 4 commits into from
Jun 1, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
### Documentation

## v0.8.3 (2020 May 28)
### New features
* loo-pit plot. The kde is computed over the data interval (this could be shorter than [0, 1]). The hdi is computed analitically (#1215)
OriolAbril marked this conversation as resolved.
Show resolved Hide resolved

### Maintenance and fixes
* Restructured internals of `from_pymc3` to handle old pymc3 releases and
sliced traces and to provide useful warnings (#1211)


## v0.8.2 (2020 May 25)
### Maintenance and fixes
* Fixed bug in `from_pymc3` for sliced `pymc3.MultiTrace` input (#1209)
Expand Down
27 changes: 14 additions & 13 deletions arviz/plots/backends/bokeh/loopitplot.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Bokeh loopitplot."""
import bokeh.plotting as bkp
from bokeh.models import BoxAnnotation
import numpy as np

from . import backend_kwarg_defaults
from .. import show_layout
from ...hdiplot import plot_hdi
from ...kdeplot import _fast_kde


Expand All @@ -21,8 +21,8 @@ def plot_loo_pit(
ecdf_fill,
use_hdi,
x_vals,
unif_densities,
hdi_kwargs,
hdi_odds,
n_unif,
unif,
plot_unif_kwargs,
Expand All @@ -43,7 +43,7 @@ def plot_loo_pit(
if ax is None:
backend_kwargs.setdefault("width", int(figsize[0] * dpi))
backend_kwargs.setdefault("height", int(figsize[1] * dpi))
ax = bkp.figure(**backend_kwargs)
ax = bkp.figure(x_range=(0, 1), **backend_kwargs)

if ecdf:
if plot_kwargs.get("drawstyle") == "steps-mid":
Expand Down Expand Up @@ -115,20 +115,21 @@ def plot_loo_pit(
)
else:
if use_hdi:
plot_hdi(
x_vals,
unif_densities,
backend="bokeh",
ax=ax,
backend_kwargs={},
show=False,
**hdi_kwargs
ax.add_layout(
BoxAnnotation(
bottom=hdi_odds[1],
top=hdi_odds[0],
fill_alpha=hdi_kwargs.pop("alpha"),
fill_color=hdi_kwargs.pop("color"),
**hdi_kwargs
)
)
else:
for idx in range(n_unif):
unif_density, _, _ = _fast_kde(unif[idx, :], xmin=0, xmax=1)
unif_density, xmin, xmax = _fast_kde(unif[idx, :])
x_s = np.linspace(xmin, xmax, len(unif_density))
ax.line(
x_vals,
x_s,
unif_density,
line_color=plot_unif_kwargs.get("color", "black"),
line_alpha=plot_unif_kwargs.get("alpha", 0.1),
Expand Down
16 changes: 10 additions & 6 deletions arviz/plots/backends/matplotlib/loopitplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from . import backend_kwarg_defaults, backend_show
from ....numeric_utils import _fast_kde
from ...hdiplot import plot_hdi


def plot_loo_pit(
Expand All @@ -20,8 +19,8 @@ def plot_loo_pit(
ecdf_fill,
use_hdi,
x_vals,
unif_densities,
hdi_kwargs,
hdi_odds,
n_unif,
unif,
plot_unif_kwargs,
Expand Down Expand Up @@ -54,14 +53,19 @@ def plot_loo_pit(
else:
ax.plot(unif_ecdf, p975 - unif_ecdf, unif_ecdf, p025 - unif_ecdf, **plot_unif_kwargs)
else:
x_ss = np.empty((n_unif, len(loo_pit_kde)))
u_dens = np.empty((n_unif, len(loo_pit_kde)))
if use_hdi:
plot_hdi(x_vals, unif_densities, **hdi_kwargs)
ax.axhspan(*hdi_odds, **hdi_kwargs)
else:
for idx in range(n_unif):
unif_density, _, _ = _fast_kde(unif[idx, :], xmin=0, xmax=1)
ax.plot(x_vals, unif_density, **plot_unif_kwargs)
unif_density, xmin, xmax = _fast_kde(unif[idx, :])
x_s = np.linspace(xmin, xmax, len(unif_density))
x_ss[idx] = x_s
u_dens[idx] = unif_density
ax.plot(x_ss.T, u_dens.T, **plot_unif_kwargs)
ax.plot(x_vals, loo_pit_kde, **plot_kwargs)

ax.set_xlim(0, 1)
ax.tick_params(labelsize=xt_labelsize)
if legend:
if not (use_hdi or (ecdf and ecdf_fill)):
Expand Down
35 changes: 14 additions & 21 deletions arviz/plots/loopitplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ def plot_loo_pit(
n_unif : int, optional
Number of datasets to simulate and overlay from the uniform distribution.
use_hdi : bool, optional
Use plot_hdi to fill between hdi values instead of overlaying the uniform distributions.
Compute expected hdi values instead of overlaying the sampled uniform distributions.
credible_interval : float, optional
Credible interval of the hdi or of the ECDF theoretical credible interval
Theoretical credible interval. Works with ``use_hdi=True`` or ``ecdf=True``.
figsize : figure size tuple, optional
If None, size is (8 + numvars, 8 + numvars)
textsize: int, optional
Expand All @@ -86,7 +86,7 @@ def plot_loo_pit(
Additional keywords passed to ax.plot for overlaid uniform distributions or
for beta credible interval lines if ``ecdf=True``
hdi_kwargs : dict, optional
Additional keywords passed to az.plot_hdi
Additional keywords passed to ax.axhspan
fill_kwargs : dict, optional
Additional kwargs passed to ax.fill_between
backend: str, optional
Expand Down Expand Up @@ -168,8 +168,8 @@ def plot_loo_pit(
p975 = None
p025 = None
loo_pit_kde = None
hdi_odds = None
unif = None
unif_densities = None
x_vals = None

if credible_interval is None:
Expand Down Expand Up @@ -206,20 +206,19 @@ def plot_loo_pit(
)
fill_kwargs.setdefault("label", "{:.3g}% credible interval".format(credible_interval))
else:
loo_pit_kde, _, _ = _fast_kde(loo_pit, xmin=0, xmax=1)
loo_pit_kde, xmin, xmax = _fast_kde(loo_pit)

unif = np.random.uniform(size=(n_unif, loo_pit.size))
x_vals = np.linspace(0, 1, len(loo_pit_kde))
x_vals = np.linspace(xmin, xmax, len(loo_pit_kde))
if use_hdi:
n_obs = loo_pit.size
hdi_ = stats.beta(n_obs / 2, n_obs / 2).ppf((1 - credible_interval) / 2)
hdi_odds = (hdi_ / (1 - hdi_), (1 - hdi_) / hdi_)
if hdi_kwargs is None:
hdi_kwargs = {}
hdi_kwargs.setdefault("color", to_hex(hsv_to_rgb(light_color)))
hdi_fill_kwargs = hdi_kwargs.pop("fill_kwargs", {})
hdi_fill_kwargs.setdefault("label", "Uniform hdi")
hdi_kwargs["fill_kwargs"] = hdi_fill_kwargs
hdi_kwargs["credible_interval"] = credible_interval

unif_densities = np.empty((n_unif, len(loo_pit_kde)))
hdi_kwargs.setdefault("alpha", 0.35)
hdi_kwargs.setdefault("label", "Uniform hdi")

loo_pit_kwargs = dict(
ax=ax,
Expand All @@ -234,8 +233,8 @@ def plot_loo_pit(
ecdf_fill=ecdf_fill,
use_hdi=use_hdi,
x_vals=x_vals,
unif_densities=unif_densities,
hdi_kwargs=hdi_kwargs,
hdi_odds=hdi_odds,
n_unif=n_unif,
unif=unif,
plot_unif_kwargs=plot_unif_kwargs,
Expand All @@ -253,14 +252,8 @@ def plot_loo_pit(
backend = backend.lower()

if backend == "bokeh":

if (
loo_pit_kwargs["hdi_kwargs"] is not None
and "fill_kwargs" in loo_pit_kwargs["hdi_kwargs"]
and loo_pit_kwargs["hdi_kwargs"]["fill_kwargs"] is not None
and "label" in loo_pit_kwargs["hdi_kwargs"]["fill_kwargs"]
):
loo_pit_kwargs["hdi_kwargs"]["fill_kwargs"].pop("label")
if use_hdi:
loo_pit_kwargs["hdi_kwargs"].pop("label", None)
loo_pit_kwargs.pop("legend")
loo_pit_kwargs.pop("xt_labelsize")
loo_pit_kwargs.pop("credible_interval")
Expand Down
4 changes: 2 additions & 2 deletions arviz/tests/base_tests/test_plots_bokeh.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,8 @@ def test_plot_khat_bad_input(models):
{},
{"n_unif": 50},
{"use_hdi": True, "color": "gray"},
{"use_hdi": True, "credible_interval": 0.68, "plot_kwargs": {"alpha": 0.9}},
{"use_hdi": True, "hdi_kwargs": {"smooth": False}},
{"use_hdi": True, "credible_interval": 0.68},
{"use_hdi": True, "hdi_kwargs": {"line_dash": "dashed", "alpha": 0}},
{"ecdf": True},
{"ecdf": True, "ecdf_fill": False, "plot_unif_kwargs": {"line_dash": "--"}},
{"ecdf": True, "credible_interval": 0.97, "fill_kwargs": {"color": "red"}},
Expand Down
4 changes: 2 additions & 2 deletions arviz/tests/base_tests/test_plots_matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1101,8 +1101,8 @@ def test_plot_ess_no_divergences(models):
{},
{"n_unif": 50, "legend": False},
{"use_hdi": True, "color": "gray"},
{"use_hdi": True, "credible_interval": 0.68, "plot_kwargs": {"ls": "--"}},
{"use_hdi": True, "hdi_kwargs": {"smooth": False}},
{"use_hdi": True, "credible_interval": 0.68},
{"use_hdi": True, "hdi_kwargs": {"fill": 0.1}},
{"ecdf": True},
{"ecdf": True, "ecdf_fill": False, "plot_unif_kwargs": {"ls": "--"}},
{"ecdf": True, "credible_interval": 0.97, "fill_kwargs": {"hatch": "/"}},
Expand Down