arviz 0.18.0__py3-none-any.whl → 0.20.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. arviz/__init__.py +2 -1
  2. arviz/data/base.py +18 -7
  3. arviz/data/converters.py +7 -3
  4. arviz/data/inference_data.py +8 -0
  5. arviz/data/io_cmdstan.py +4 -0
  6. arviz/data/io_numpyro.py +1 -1
  7. arviz/plots/backends/bokeh/ecdfplot.py +1 -2
  8. arviz/plots/backends/bokeh/khatplot.py +8 -3
  9. arviz/plots/backends/bokeh/pairplot.py +2 -6
  10. arviz/plots/backends/matplotlib/ecdfplot.py +1 -2
  11. arviz/plots/backends/matplotlib/khatplot.py +7 -3
  12. arviz/plots/backends/matplotlib/traceplot.py +1 -1
  13. arviz/plots/bpvplot.py +2 -2
  14. arviz/plots/compareplot.py +4 -4
  15. arviz/plots/densityplot.py +1 -1
  16. arviz/plots/dotplot.py +2 -2
  17. arviz/plots/ecdfplot.py +213 -89
  18. arviz/plots/essplot.py +2 -2
  19. arviz/plots/forestplot.py +3 -3
  20. arviz/plots/hdiplot.py +2 -2
  21. arviz/plots/kdeplot.py +9 -2
  22. arviz/plots/khatplot.py +23 -6
  23. arviz/plots/loopitplot.py +2 -2
  24. arviz/plots/mcseplot.py +3 -1
  25. arviz/plots/plot_utils.py +2 -4
  26. arviz/plots/posteriorplot.py +1 -1
  27. arviz/plots/rankplot.py +2 -2
  28. arviz/plots/violinplot.py +1 -1
  29. arviz/preview.py +17 -0
  30. arviz/rcparams.py +27 -2
  31. arviz/stats/diagnostics.py +13 -9
  32. arviz/stats/ecdf_utils.py +168 -10
  33. arviz/stats/stats.py +41 -20
  34. arviz/stats/stats_utils.py +8 -6
  35. arviz/tests/base_tests/test_data.py +11 -2
  36. arviz/tests/base_tests/test_data_zarr.py +0 -1
  37. arviz/tests/base_tests/test_diagnostics_numba.py +2 -7
  38. arviz/tests/base_tests/test_helpers.py +2 -2
  39. arviz/tests/base_tests/test_plot_utils.py +5 -13
  40. arviz/tests/base_tests/test_plots_matplotlib.py +95 -2
  41. arviz/tests/base_tests/test_rcparams.py +12 -0
  42. arviz/tests/base_tests/test_stats.py +1 -1
  43. arviz/tests/base_tests/test_stats_ecdf_utils.py +15 -2
  44. arviz/tests/base_tests/test_stats_numba.py +2 -7
  45. arviz/tests/base_tests/test_utils_numba.py +2 -5
  46. arviz/tests/external_tests/test_data_pystan.py +5 -5
  47. arviz/tests/helpers.py +17 -9
  48. arviz/utils.py +4 -0
  49. {arviz-0.18.0.dist-info → arviz-0.20.0.dist-info}/METADATA +23 -19
  50. {arviz-0.18.0.dist-info → arviz-0.20.0.dist-info}/RECORD +53 -52
  51. {arviz-0.18.0.dist-info → arviz-0.20.0.dist-info}/WHEEL +1 -1
  52. {arviz-0.18.0.dist-info → arviz-0.20.0.dist-info}/LICENSE +0 -0
  53. {arviz-0.18.0.dist-info → arviz-0.20.0.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  # pylint: disable=redefined-outer-name
2
2
  import importlib
3
+ import os
3
4
 
4
5
  import numpy as np
5
6
  import pytest
@@ -20,10 +21,10 @@ from ...rcparams import rc_context
20
21
  from ...sel_utils import xarray_sel_iter, xarray_to_ndarray
21
22
  from ...stats.density_utils import get_bins
22
23
  from ...utils import get_coords
23
- from ..helpers import running_on_ci
24
24
 
25
25
  # Check if Bokeh is installed
26
26
  bokeh_installed = importlib.util.find_spec("bokeh") is not None # pylint: disable=invalid-name
27
+ skip_tests = (not bokeh_installed) and ("ARVIZ_REQUIRE_ALL_DEPS" not in os.environ)
27
28
 
28
29
 
29
30
  @pytest.mark.parametrize(
@@ -212,10 +213,7 @@ def test_filter_plotter_list_warning():
212
213
  assert len(plotters_filtered) == 5
213
214
 
214
215
 
215
- @pytest.mark.skipif(
216
- not (bokeh_installed or running_on_ci()),
217
- reason="test requires bokeh which is not installed",
218
- )
216
+ @pytest.mark.skipif(skip_tests, reason="test requires bokeh which is not installed")
219
217
  def test_bokeh_import():
220
218
  """Tests that correct method is returned on bokeh import"""
221
219
  plot = get_plotting_function("plot_dist", "distplot", "bokeh")
@@ -290,10 +288,7 @@ def test_mpl_dealiase_sel_kwargs():
290
288
  assert res["line_color"] == "red"
291
289
 
292
290
 
293
- @pytest.mark.skipif(
294
- not (bokeh_installed or running_on_ci()),
295
- reason="test requires bokeh which is not installed",
296
- )
291
+ @pytest.mark.skipif(skip_tests, reason="test requires bokeh which is not installed")
297
292
  def test_bokeh_dealiase_sel_kwargs():
298
293
  """Check bokeh dealiase_sel_kwargs behaviour.
299
294
 
@@ -315,10 +310,7 @@ def test_bokeh_dealiase_sel_kwargs():
315
310
  assert res["line_color"] == "red"
316
311
 
317
312
 
318
- @pytest.mark.skipif(
319
- not (bokeh_installed or running_on_ci()),
320
- reason="test requires bokeh which is not installed",
321
- )
313
+ @pytest.mark.skipif(skip_tests, reason="test requires bokeh which is not installed")
322
314
  def test_set_bokeh_circular_ticks_labels():
323
315
  """Assert the axes returned after placing ticks and tick labels for circular plots."""
324
316
  import bokeh.plotting as bkp
@@ -46,12 +46,13 @@ from ...plots import (
46
46
  from ...rcparams import rc_context, rcParams
47
47
  from ...stats import compare, hdi, loo, waic
48
48
  from ...stats.density_utils import kde as _kde
49
- from ...utils import _cov
49
+ from ...utils import _cov, BehaviourChangeWarning
50
50
  from ...plots.plot_utils import plot_point_interval
51
51
  from ...plots.dotplot import wilkinson_algorithm
52
52
  from ..helpers import ( # pylint: disable=unused-import
53
53
  create_model,
54
54
  create_multidimensional_model,
55
+ does_not_warn,
55
56
  eight_schools_params,
56
57
  models,
57
58
  multidim_models,
@@ -261,7 +262,7 @@ def test_plot_trace_legend(compact, combined):
261
262
  axes = plot_trace(
262
263
  idata, var_names=["home", "atts_star"], compact=compact, combined=combined, legend=True
263
264
  )
264
- assert axes[0, 0].get_legend()
265
+ assert axes[0, 1].get_legend()
265
266
  compact_legend = axes[1, 0].get_legend()
266
267
  if compact:
267
268
  assert axes.shape == (2, 2)
@@ -1272,6 +1273,27 @@ def test_plot_ecdf_basic():
1272
1273
  assert axes is not None
1273
1274
 
1274
1275
 
1276
+ def test_plot_ecdf_eval_points():
1277
+ """Check that BehaviourChangeWarning is raised if eval_points is not specified."""
1278
+ data = np.random.randn(4, 1000)
1279
+ eval_points = np.linspace(-3, 3, 100)
1280
+ with pytest.warns(BehaviourChangeWarning):
1281
+ axes = plot_ecdf(data)
1282
+ assert axes is not None
1283
+ with does_not_warn(BehaviourChangeWarning):
1284
+ axes = plot_ecdf(data, eval_points=eval_points)
1285
+ assert axes is not None
1286
+
1287
+
1288
+ @pytest.mark.parametrize("confidence_bands", [True, "pointwise", "optimized", "simulated"])
1289
+ @pytest.mark.parametrize("ndraws", [100, 10_000])
1290
+ def test_plot_ecdf_confidence_bands(confidence_bands, ndraws):
1291
+ """Check that all confidence_bands values correctly accepted"""
1292
+ data = np.random.randn(4, ndraws // 4)
1293
+ axes = plot_ecdf(data, confidence_bands=confidence_bands, cdf=norm(0, 1).cdf)
1294
+ assert axes is not None
1295
+
1296
+
1275
1297
  def test_plot_ecdf_values2():
1276
1298
  data = np.random.randn(4, 1000)
1277
1299
  data2 = np.random.randn(4, 1000)
@@ -1286,6 +1308,77 @@ def test_plot_ecdf_cdf():
1286
1308
  assert axes is not None
1287
1309
 
1288
1310
 
1311
+ def test_plot_ecdf_error():
1312
+ """Check that all error conditions are correctly raised."""
1313
+ dist = norm(0, 1)
1314
+ data = dist.rvs(1000)
1315
+
1316
+ # cdf not specified
1317
+ with pytest.raises(ValueError):
1318
+ plot_ecdf(data, confidence_bands=True)
1319
+ plot_ecdf(data, confidence_bands=True, cdf=dist.cdf)
1320
+ with pytest.raises(ValueError):
1321
+ plot_ecdf(data, difference=True)
1322
+ plot_ecdf(data, difference=True, cdf=dist.cdf)
1323
+ with pytest.raises(ValueError):
1324
+ plot_ecdf(data, pit=True)
1325
+ plot_ecdf(data, pit=True, cdf=dist.cdf)
1326
+
1327
+ # contradictory confidence band types
1328
+ with pytest.raises(ValueError):
1329
+ plot_ecdf(data, cdf=dist.cdf, confidence_bands="simulated", pointwise=True)
1330
+ with pytest.raises(ValueError):
1331
+ plot_ecdf(data, cdf=dist.cdf, confidence_bands="optimized", pointwise=True)
1332
+ plot_ecdf(data, cdf=dist.cdf, confidence_bands=True, pointwise=True)
1333
+ plot_ecdf(data, cdf=dist.cdf, confidence_bands="pointwise")
1334
+
1335
+ # contradictory band probabilities
1336
+ with pytest.raises(ValueError):
1337
+ plot_ecdf(data, cdf=dist.cdf, confidence_bands=True, ci_prob=0.9, fpr=0.1)
1338
+ plot_ecdf(data, cdf=dist.cdf, confidence_bands=True, ci_prob=0.9)
1339
+ plot_ecdf(data, cdf=dist.cdf, confidence_bands=True, fpr=0.1)
1340
+
1341
+ # contradictory reference
1342
+ data2 = dist.rvs(200)
1343
+ with pytest.raises(ValueError):
1344
+ plot_ecdf(data, data2, cdf=dist.cdf, difference=True)
1345
+ plot_ecdf(data, data2, difference=True)
1346
+ plot_ecdf(data, cdf=dist.cdf, difference=True)
1347
+
1348
+
1349
+ def test_plot_ecdf_deprecations():
1350
+ """Check that deprecations are raised correctly."""
1351
+ dist = norm(0, 1)
1352
+ data = dist.rvs(1000)
1353
+ # base case, no deprecations
1354
+ with does_not_warn(FutureWarning):
1355
+ axes = plot_ecdf(data, cdf=dist.cdf, confidence_bands=True)
1356
+ assert axes is not None
1357
+
1358
+ # values2 is deprecated
1359
+ data2 = dist.rvs(200)
1360
+ with pytest.warns(FutureWarning):
1361
+ axes = plot_ecdf(data, values2=data2, difference=True)
1362
+
1363
+ # pit is deprecated
1364
+ with pytest.warns(FutureWarning):
1365
+ axes = plot_ecdf(data, cdf=dist.cdf, pit=True)
1366
+ assert axes is not None
1367
+
1368
+ # fpr is deprecated
1369
+ with does_not_warn(FutureWarning):
1370
+ axes = plot_ecdf(data, cdf=dist.cdf, ci_prob=0.9)
1371
+ with pytest.warns(FutureWarning):
1372
+ axes = plot_ecdf(data, cdf=dist.cdf, confidence_bands=True, fpr=0.1)
1373
+ assert axes is not None
1374
+
1375
+ # pointwise is deprecated
1376
+ with does_not_warn(FutureWarning):
1377
+ axes = plot_ecdf(data, cdf=dist.cdf, confidence_bands="pointwise")
1378
+ with pytest.warns(FutureWarning):
1379
+ axes = plot_ecdf(data, cdf=dist.cdf, confidence_bands=True, pointwise=True)
1380
+
1381
+
1289
1382
  @pytest.mark.parametrize(
1290
1383
  "kwargs",
1291
1384
  [
@@ -127,6 +127,18 @@ def test_choice_bad_values(param):
127
127
  rcParams[param] = "bad_value"
128
128
 
129
129
 
130
+ @pytest.mark.parametrize("args", [("stats.hdi_prob", "stats.ci_prob", 0.7, 0.7)])
131
+ def test_deprecated_param(args):
132
+ """Test value and warning message correctly set for deprecated rcparams."""
133
+ param_old, param_new, val_old, val_new = args
134
+ assert param_new in rcParams
135
+ assert not np.isclose(rcParams[param_new], val_new)
136
+ msg = f"{param_old} is deprecated since .*, use {param_new} instead"
137
+ with pytest.warns(FutureWarning, match=msg):
138
+ with rc_context(rc={param_old: val_old}):
139
+ assert np.isclose(rcParams[param_new], val_new)
140
+
141
+
130
142
  @pytest.mark.parametrize("allow_none", (True, False))
131
143
  @pytest.mark.parametrize("typeof", (str, int))
132
144
  @pytest.mark.parametrize("args", [("not one", 10), (False, None), (False, 4)])
@@ -179,7 +179,7 @@ def test_compare_same(centered_eight, multidim_models, method, multidim):
179
179
  else:
180
180
  data_dict = {"first": centered_eight, "second": centered_eight}
181
181
 
182
- weight = compare(data_dict, method=method)["weight"]
182
+ weight = compare(data_dict, method=method)["weight"].to_numpy()
183
183
  assert_allclose(weight[0], weight[1])
184
184
  assert_allclose(np.sum(weight), 1.0)
185
185
 
@@ -10,6 +10,13 @@ from ...stats.ecdf_utils import (
10
10
  _get_pointwise_confidence_band,
11
11
  )
12
12
 
13
+ try:
14
+ import numba # pylint: disable=unused-import
15
+
16
+ numba_options = [True, False]
17
+ except ImportError:
18
+ numba_options = [False]
19
+
13
20
 
14
21
  def test_compute_ecdf():
15
22
  """Test compute_ecdf function."""
@@ -109,9 +116,15 @@ def test_get_pointwise_confidence_band(dist, prob, ndraws, num_trials=1_000, see
109
116
  ids=["continuous", "continuous default rvs", "discrete"],
110
117
  )
111
118
  @pytest.mark.parametrize("ndraws", [10_000])
112
- @pytest.mark.parametrize("method", ["pointwise", "simulated"])
113
- def test_ecdf_confidence_band(dist, rvs, prob, ndraws, method, num_trials=1_000, seed=57):
119
+ @pytest.mark.parametrize("method", ["pointwise", "optimized", "simulated"])
120
+ @pytest.mark.parametrize("use_numba", numba_options)
121
+ def test_ecdf_confidence_band(
122
+ dist, rvs, prob, ndraws, method, use_numba, num_trials=1_000, seed=57
123
+ ):
114
124
  """Test test_ecdf_confidence_band."""
125
+ if use_numba and method != "optimized":
126
+ pytest.skip("Numba only used in optimized method")
127
+
115
128
  eval_points = np.linspace(*dist.interval(0.99), 10)
116
129
  cdf_at_eval_points = dist.cdf(eval_points)
117
130
  random_state = np.random.default_rng(seed)
@@ -1,6 +1,4 @@
1
1
  # pylint: disable=redefined-outer-name, no-member
2
- import importlib
3
-
4
2
  import numpy as np
5
3
  import pytest
6
4
 
@@ -9,15 +7,12 @@ from ...stats import r2_score, summary
9
7
  from ...utils import Numba
10
8
  from ..helpers import ( # pylint: disable=unused-import
11
9
  check_multiple_attrs,
10
+ importorskip,
12
11
  multidim_models,
13
- running_on_ci,
14
12
  )
15
13
  from .test_stats import centered_eight, non_centered_eight # pylint: disable=unused-import
16
14
 
17
- pytestmark = pytest.mark.skipif( # pylint: disable=invalid-name
18
- (importlib.util.find_spec("numba") is None) and not running_on_ci(),
19
- reason="test requires numba which is not installed",
20
- )
15
+ numba = importorskip("numba")
21
16
 
22
17
  rcParams["data.load"] = "eager"
23
18
 
@@ -8,13 +8,10 @@ import pytest
8
8
 
9
9
  from ...stats.stats_utils import stats_variance_2d as svar
10
10
  from ...utils import Numba, _numba_var, numba_check
11
- from ..helpers import running_on_ci
11
+ from ..helpers import importorskip
12
12
  from .test_utils import utils_with_numba_import_fail # pylint: disable=unused-import
13
13
 
14
- pytestmark = pytest.mark.skipif( # pylint: disable=invalid-name
15
- (importlib.util.find_spec("numba") is None) and not running_on_ci(),
16
- reason="test requires numba which is not installed",
17
- )
14
+ importorskip("numba")
18
15
 
19
16
 
20
17
  def test_utils_fixture(utils_with_numba_import_fail):
@@ -1,6 +1,7 @@
1
1
  # pylint: disable=no-member, invalid-name, redefined-outer-name, too-many-function-args
2
2
  import importlib
3
3
  from collections import OrderedDict
4
+ import os
4
5
 
5
6
  import numpy as np
6
7
  import pytest
@@ -16,19 +17,18 @@ from ..helpers import ( # pylint: disable=unused-import
16
17
  importorskip,
17
18
  load_cached_models,
18
19
  pystan_version,
19
- running_on_ci,
20
20
  )
21
21
 
22
22
  # Check if either pystan or pystan3 is installed
23
23
  pystan_installed = (importlib.util.find_spec("pystan") is not None) or (
24
24
  importlib.util.find_spec("stan") is not None
25
25
  )
26
- pytestmark = pytest.mark.skipif(
27
- not (pystan_installed | running_on_ci()),
28
- reason="test requires pystan/pystan3 which is not installed",
29
- )
30
26
 
31
27
 
28
+ @pytest.mark.skipif(
29
+ not (pystan_installed or "ARVIZ_REQUIRE_ALL_DEPS" in os.environ),
30
+ reason="test requires pystan/pystan3 which is not installed",
31
+ )
32
32
  class TestDataPyStan:
33
33
  @pytest.fixture(scope="class")
34
34
  def data(self, eight_schools_params, draws, chains):
arviz/tests/helpers.py CHANGED
@@ -6,6 +6,8 @@ import logging
6
6
  import os
7
7
  import sys
8
8
  from typing import Any, Dict, List, Optional, Tuple, Union
9
+ import warnings
10
+ from contextlib import contextmanager
9
11
 
10
12
  import cloudpickle
11
13
  import numpy as np
@@ -29,6 +31,18 @@ class RandomVariableTestClass:
29
31
  return self.name
30
32
 
31
33
 
34
+ @contextmanager
35
+ def does_not_warn(warning=Warning):
36
+ with warnings.catch_warnings(record=True) as caught_warnings:
37
+ warnings.simplefilter("always")
38
+ yield
39
+ for w in caught_warnings:
40
+ if issubclass(w.category, warning):
41
+ raise AssertionError(
42
+ f"Expected no {warning.__name__} but caught warning with message: {w.message}"
43
+ )
44
+
45
+
32
46
  @pytest.fixture(scope="module")
33
47
  def eight_schools_params():
34
48
  """Share setup for eight schools."""
@@ -620,11 +634,6 @@ def test_precompile_models(eight_schools_params, draws, chains):
620
634
  load_cached_models(eight_schools_params, draws, chains)
621
635
 
622
636
 
623
- def running_on_ci() -> bool:
624
- """Return True if running on CI machine."""
625
- return os.environ.get("ARVIZ_CI_MACHINE") is not None
626
-
627
-
628
637
  def importorskip(
629
638
  modname: str, minversion: Optional[str] = None, reason: Optional[str] = None
630
639
  ) -> Any:
@@ -643,11 +652,10 @@ def importorskip(
643
652
  Example::
644
653
  docutils = pytest.importorskip("docutils")
645
654
  """
646
- # ARVIZ_CI_MACHINE is True if tests run on CI, where ARVIZ_CI_MACHINE env variable exists
647
- ARVIZ_CI_MACHINE = running_on_ci()
648
- if not ARVIZ_CI_MACHINE:
655
+ # Unless ARVIZ_REQUIRE_ALL_DEPS is defined, tests that require a missing dependency are skipped
656
+ # if set, missing optional dependencies trigger failed tests.
657
+ if "ARVIZ_REQUIRE_ALL_DEPS" not in os.environ:
649
658
  return pytest.importorskip(modname=modname, minversion=minversion, reason=reason)
650
- import warnings
651
659
 
652
660
  compile(modname, "", "eval") # to catch syntaxerrors
653
661
 
arviz/utils.py CHANGED
@@ -17,6 +17,10 @@ from .rcparams import rcParams
17
17
  STATIC_FILES = ("static/html/icons-svg-inline.html", "static/css/style.css")
18
18
 
19
19
 
20
+ class BehaviourChangeWarning(Warning):
21
+ """Custom warning to ease filtering it."""
22
+
23
+
20
24
  def _check_tilde_start(x):
21
25
  return bool(isinstance(x, str) and x.startswith("~"))
22
26
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arviz
3
- Version: 0.18.0
3
+ Version: 0.20.0
4
4
  Summary: Exploratory analysis of Bayesian models
5
5
  Home-page: http://github.com/arviz-devs/arviz
6
6
  Author: ArviZ Developers
@@ -21,26 +21,30 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
21
21
  Requires-Python: >=3.10
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
- Requires-Dist: setuptools >=60.0.0
25
- Requires-Dist: matplotlib >=3.5
26
- Requires-Dist: numpy <2.0,>=1.23.0
27
- Requires-Dist: scipy >=1.9.0
24
+ Requires-Dist: setuptools>=60.0.0
25
+ Requires-Dist: matplotlib>=3.5
26
+ Requires-Dist: numpy>=1.23.0
27
+ Requires-Dist: scipy>=1.9.0
28
28
  Requires-Dist: packaging
29
- Requires-Dist: pandas >=1.5.0
30
- Requires-Dist: dm-tree >=0.1.8
31
- Requires-Dist: xarray >=2022.6.0
32
- Requires-Dist: h5netcdf >=1.0.2
33
- Requires-Dist: typing-extensions >=4.1.0
34
- Requires-Dist: xarray-einstats >=0.3
29
+ Requires-Dist: pandas>=1.5.0
30
+ Requires-Dist: xarray>=2022.6.0
31
+ Requires-Dist: h5netcdf>=1.0.2
32
+ Requires-Dist: typing-extensions>=4.1.0
33
+ Requires-Dist: xarray-einstats>=0.3
35
34
  Provides-Extra: all
36
- Requires-Dist: numba ; extra == 'all'
37
- Requires-Dist: netcdf4 ; extra == 'all'
38
- Requires-Dist: bokeh <3.0,>=1.4.0 ; extra == 'all'
39
- Requires-Dist: contourpy ; extra == 'all'
40
- Requires-Dist: ujson ; extra == 'all'
41
- Requires-Dist: dask[distributed] ; extra == 'all'
42
- Requires-Dist: zarr >=2.5.0 ; extra == 'all'
43
- Requires-Dist: xarray-datatree ; extra == 'all'
35
+ Requires-Dist: numba; extra == "all"
36
+ Requires-Dist: netcdf4; extra == "all"
37
+ Requires-Dist: bokeh>=3; extra == "all"
38
+ Requires-Dist: contourpy; extra == "all"
39
+ Requires-Dist: ujson; extra == "all"
40
+ Requires-Dist: dask[distributed]; extra == "all"
41
+ Requires-Dist: zarr<3,>=2.5.0; extra == "all"
42
+ Requires-Dist: xarray-datatree; extra == "all"
43
+ Requires-Dist: dm-tree>=0.1.8; extra == "all"
44
+ Provides-Extra: preview
45
+ Requires-Dist: arviz-base[h5netcdf]; extra == "preview"
46
+ Requires-Dist: arviz-stats[xarray]; extra == "preview"
47
+ Requires-Dist: arviz-plots; extra == "preview"
44
48
 
45
49
  <img src="https://raw.githubusercontent.com/arviz-devs/arviz-project/main/arviz_logos/ArviZ.png#gh-light-mode-only" width=200></img>
46
50
  <img src="https://raw.githubusercontent.com/arviz-devs/arviz-project/main/arviz_logos/ArviZ_white.png#gh-dark-mode-only" width=200></img>