diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 388ca345e4..fbb68dada1 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,12 +1,20 @@ # Release Notes -## PyMC3 vNext (TBD) +## PyMC3 3.11.2 (TBD) ### Breaking Changes + ... ### New Features + `pm.math.cartesian` can now handle inputs that are themselves >1D (see [#4482](https://github.com/pymc-devs/pymc3/pull/4482)). -+ ... ++ Statistics and plotting functions that were removed in `3.11.0` were brought back, albeit with deprecation warnings if an old naming scheme is used (see [#4536](https://github.com/pymc-devs/pymc3/pull/4536)). In order to future proof your code, rename these function calls: + + `pm.traceplot` → `pm.plot_trace` + + `pm.compareplot` → `pm.plot_compare` (here you might need to rename some columns in the input according to the [`arviz.plot_compare` documentation](https://arviz-devs.github.io/arviz/api/generated/arviz.plot_compare.html)) + + `pm.autocorrplot` → `pm.plot_autocorr` + + `pm.forestplot` → `pm.plot_forest` + + `pm.kdeplot` → `pm.plot_kde` + + `pm.energyplot` → `pm.plot_energy` + + `pm.densityplot` → `pm.plot_density` + + `pm.pairplot` → `pm.plot_pair` ### Maintenance - ⚠ Our memoization mechanism wasn't robust against hash collisions (#4506), sometimes resulting in incorrect values in, for example, posterior predictives. The `pymc3.memoize` module was removed and replaced with `cachetools`. The `hashable` function and `WithMemoization` class were moved to `pymc3.util` (see #4525). diff --git a/docs/source/api/plots.rst b/docs/source/api/plots.rst index 0dec109b7f..1e2b2e0139 100644 --- a/docs/source/api/plots.rst +++ b/docs/source/api/plots.rst @@ -7,8 +7,7 @@ Plots Plots are delegated to the `ArviZ `_. library, a general purpose library for -"exploratory analysis of Bayesian models." -Refer to its documentation to use the plotting functions directly. +"exploratory analysis of Bayesian models". -.. automodule:: pymc3.plots.posteriorplot - :members: +Functions from the `arviz.plots` module are available through ``pymc3.`` or ``pymc3.plots.``, +but for their API documentation please refer to the :ref:`ArviZ documentation `. diff --git a/docs/source/api/stats.rst b/docs/source/api/stats.rst index bf85bb596d..4cd23c3446 100644 --- a/docs/source/api/stats.rst +++ b/docs/source/api/stats.rst @@ -1,8 +1,13 @@ ***** Stats ***** + +.. currentmodule:: pymc3.stats + Statistics and diagnostics are delegated to the `ArviZ `_. library, a general purpose library for -"exploratory analysis of Bayesian models." -Refer to its documentation to use the diagnostics functions directly. +"exploratory analysis of Bayesian models". + +Functions from the `arviz.stats` module are available through ``pymc3.`` or ``pymc3.stats.``, +but for their API documentation please refer to the :ref:`ArviZ documentation `. diff --git a/pymc3/__init__.py b/pymc3/__init__.py index 1e51deeb64..1378d0d993 100644 --- a/pymc3/__init__.py +++ b/pymc3/__init__.py @@ -61,6 +61,7 @@ def __set_compiler_flags(): from pymc3.plots import * from pymc3.sampling import * from pymc3.smc import * +from pymc3.stats import * from pymc3.step_methods import * from pymc3.tests import test from pymc3.theanof import * diff --git a/pymc3/plots/__init__.py b/pymc3/plots/__init__.py index 5923114cee..03c7715c24 100644 --- a/pymc3/plots/__init__.py +++ b/pymc3/plots/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 The PyMC Developers +# Copyright 2021 The PyMC Developers # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,12 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""PyMC3 Plotting. +"""Alias for the `plots` submodule from ArviZ. -Plots are delegated to the `ArviZ `_ library, a general purpose library for -exploratory analysis of Bayesian models. For more details, see https://arviz-devs.github.io/arviz/. - -Only `plot_posterior_predictive_glm` is kept in the PyMC code base for now, but it will move to ArviZ once the latter adds features for regression plots. +Plots are delegated to the ArviZ library, a general purpose library for +"exploratory analysis of Bayesian models." +See https://arviz-devs.github.io/arviz/ for details on plots. """ import functools import sys @@ -25,6 +24,103 @@ import arviz as az +# Makes this module as identical to arviz.plots as possible +for attr in az.plots.__all__: + obj = getattr(az.plots, attr) + if not attr.startswith("__"): + setattr(sys.modules[__name__], attr, obj) + + +def map_args(func, alias: str): + @functools.wraps(func) + def wrapped(*args, **kwargs): + if "varnames" in kwargs: + raise DeprecationWarning( + f"The `varnames` kwarg was renamed to `var_names`.", stacklevel=2 + ) + original = func.__name__ + warnings.warn( + f"The function `{alias}` from PyMC3 is just an alias for `{original}` from ArviZ. " + f"Please switch to `pymc3.{original}` or `arviz.{original}`.", + DeprecationWarning, + stacklevel=2, + ) + return func(*args, **kwargs) + + return wrapped + + +# Always show the DeprecationWarnings +warnings.filterwarnings("once", category=DeprecationWarning, module="pymc3.plots") + + +# Aliases of ArviZ functions +autocorrplot = map_args(az.plot_autocorr, alias="autocorrplot") +forestplot = map_args(az.plot_forest, alias="forestplot") +kdeplot = map_args(az.plot_kde, alias="kdeplot") +energyplot = map_args(az.plot_energy, alias="energyplot") +densityplot = map_args(az.plot_density, alias="densityplot") +pairplot = map_args(az.plot_pair, alias="pairplot") +traceplot = map_args(az.plot_trace, alias="traceplot") + + +# Customized with kwarg reformatting +@functools.wraps(az.plot_compare) +def compareplot(*args, **kwargs): + warnings.warn( + f"The function `compareplot` from PyMC3 is an alias for `plot_compare` from ArviZ. " + "It also applies some kwarg replacements. Nevertheless, please switch " + f"to `pymc3.plot_compare` or `arviz.plot_compare`.", + DeprecationWarning, + stacklevel=2, + ) + if "comp_df" in kwargs: + comp_df = kwargs["comp_df"].copy() + else: + args = list(args) + comp_df = args[0].copy() + if "WAIC" in comp_df.columns: + comp_df = comp_df.rename( + index=str, + columns={ + "WAIC": "waic", + "pWAIC": "p_waic", + "dWAIC": "d_waic", + "SE": "se", + "dSE": "dse", + "var_warn": "warning", + }, + ) + elif "LOO" in comp_df.columns: + comp_df = comp_df.rename( + index=str, + columns={ + "LOO": "loo", + "pLOO": "p_loo", + "dLOO": "d_loo", + "SE": "se", + "dSE": "dse", + "shape_warn": "warning", + }, + ) + if "comp_df" in kwargs: + kwargs["comp_df"] = comp_df + else: + args[0] = comp_df + return az.plot_compare(*args, **kwargs) + + from pymc3.plots.posteriorplot import plot_posterior_predictive_glm -__all__ = ["plot_posterior_predictive_glm"] +__all__ = tuple(az.plots.__all__) + ( + "autocorrplot", + "compareplot", + "forestplot", + "kdeplot", + "plot_posterior", + "traceplot", + "energyplot", + "densityplot", + "pairplot", + "plot_posterior_predictive_glm", +) diff --git a/pymc3/stats/__init__.py b/pymc3/stats/__init__.py new file mode 100644 index 0000000000..0880ca8b52 --- /dev/null +++ b/pymc3/stats/__init__.py @@ -0,0 +1,31 @@ +# Copyright 2021 The PyMC Developers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Alias for the `stats` submodule from ArviZ. + +Diagnostics and auxiliary statistical functions are delegated to the ArviZ library, a general +purpose library for "exploratory analysis of Bayesian models." +See https://arviz-devs.github.io/arviz/ for details. +""" +import sys + +import arviz as az + +for attr in az.stats.__all__: + obj = getattr(az.stats, attr) + if not attr.startswith("__"): + setattr(sys.modules[__name__], attr, obj) + + +__all__ = tuple(az.stats.__all__)