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

Bring back stats and plotting aliases #4536

Merged
merged 5 commits into from
Mar 14, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 10 additions & 2 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -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).
Expand Down
7 changes: 3 additions & 4 deletions docs/source/api/plots.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ Plots
Plots are delegated to the
`ArviZ <https://arviz-devs.github.io/arviz/index.html>`_.
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.<function>`` or ``pymc3.plots.<function>``,
but for their API documentation please refer to the :ref:`ArviZ documentation <arviz:plot_api>`.
9 changes: 7 additions & 2 deletions docs/source/api/stats.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
*****
Stats
*****

.. currentmodule:: pymc3.stats

Statistics and diagnostics are delegated to the
`ArviZ <https://arviz-devs.github.io/arviz/index.html>`_.
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.<function>`` or ``pymc3.stats.<function>``,
but for their API documentation please refer to the :ref:`ArviZ documentation <arviz:stats_api>`.
1 change: 1 addition & 0 deletions pymc3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
110 changes: 103 additions & 7 deletions pymc3/plots/__init__.py
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -12,19 +12,115 @@
# 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 <https://arviz-devs.github.io/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
import warnings

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",
)
31 changes: 31 additions & 0 deletions pymc3/stats/__init__.py
Original file line number Diff line number Diff line change
@@ -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("__"):
michaelosthege marked this conversation as resolved.
Show resolved Hide resolved
setattr(sys.modules[__name__], attr, obj)


__all__ = tuple(az.stats.__all__)