arviz 0.23.3__py3-none-any.whl → 1.0.0rc0__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 (185) hide show
  1. arviz/__init__.py +52 -367
  2. arviz-1.0.0rc0.dist-info/METADATA +182 -0
  3. arviz-1.0.0rc0.dist-info/RECORD +5 -0
  4. {arviz-0.23.3.dist-info → arviz-1.0.0rc0.dist-info}/WHEEL +1 -2
  5. {arviz-0.23.3.dist-info → arviz-1.0.0rc0.dist-info}/licenses/LICENSE +0 -1
  6. arviz/data/__init__.py +0 -55
  7. arviz/data/base.py +0 -596
  8. arviz/data/converters.py +0 -203
  9. arviz/data/datasets.py +0 -161
  10. arviz/data/example_data/code/radon/radon.json +0 -326
  11. arviz/data/example_data/data/centered_eight.nc +0 -0
  12. arviz/data/example_data/data/non_centered_eight.nc +0 -0
  13. arviz/data/example_data/data_local.json +0 -12
  14. arviz/data/example_data/data_remote.json +0 -58
  15. arviz/data/inference_data.py +0 -2386
  16. arviz/data/io_beanmachine.py +0 -112
  17. arviz/data/io_cmdstan.py +0 -1036
  18. arviz/data/io_cmdstanpy.py +0 -1233
  19. arviz/data/io_datatree.py +0 -23
  20. arviz/data/io_dict.py +0 -462
  21. arviz/data/io_emcee.py +0 -317
  22. arviz/data/io_json.py +0 -54
  23. arviz/data/io_netcdf.py +0 -68
  24. arviz/data/io_numpyro.py +0 -497
  25. arviz/data/io_pyjags.py +0 -378
  26. arviz/data/io_pyro.py +0 -333
  27. arviz/data/io_pystan.py +0 -1095
  28. arviz/data/io_zarr.py +0 -46
  29. arviz/data/utils.py +0 -139
  30. arviz/labels.py +0 -210
  31. arviz/plots/__init__.py +0 -61
  32. arviz/plots/autocorrplot.py +0 -171
  33. arviz/plots/backends/__init__.py +0 -223
  34. arviz/plots/backends/bokeh/__init__.py +0 -166
  35. arviz/plots/backends/bokeh/autocorrplot.py +0 -101
  36. arviz/plots/backends/bokeh/bfplot.py +0 -23
  37. arviz/plots/backends/bokeh/bpvplot.py +0 -193
  38. arviz/plots/backends/bokeh/compareplot.py +0 -167
  39. arviz/plots/backends/bokeh/densityplot.py +0 -239
  40. arviz/plots/backends/bokeh/distcomparisonplot.py +0 -23
  41. arviz/plots/backends/bokeh/distplot.py +0 -183
  42. arviz/plots/backends/bokeh/dotplot.py +0 -113
  43. arviz/plots/backends/bokeh/ecdfplot.py +0 -73
  44. arviz/plots/backends/bokeh/elpdplot.py +0 -203
  45. arviz/plots/backends/bokeh/energyplot.py +0 -155
  46. arviz/plots/backends/bokeh/essplot.py +0 -176
  47. arviz/plots/backends/bokeh/forestplot.py +0 -772
  48. arviz/plots/backends/bokeh/hdiplot.py +0 -54
  49. arviz/plots/backends/bokeh/kdeplot.py +0 -268
  50. arviz/plots/backends/bokeh/khatplot.py +0 -163
  51. arviz/plots/backends/bokeh/lmplot.py +0 -185
  52. arviz/plots/backends/bokeh/loopitplot.py +0 -211
  53. arviz/plots/backends/bokeh/mcseplot.py +0 -184
  54. arviz/plots/backends/bokeh/pairplot.py +0 -328
  55. arviz/plots/backends/bokeh/parallelplot.py +0 -81
  56. arviz/plots/backends/bokeh/posteriorplot.py +0 -324
  57. arviz/plots/backends/bokeh/ppcplot.py +0 -379
  58. arviz/plots/backends/bokeh/rankplot.py +0 -149
  59. arviz/plots/backends/bokeh/separationplot.py +0 -107
  60. arviz/plots/backends/bokeh/traceplot.py +0 -436
  61. arviz/plots/backends/bokeh/violinplot.py +0 -164
  62. arviz/plots/backends/matplotlib/__init__.py +0 -124
  63. arviz/plots/backends/matplotlib/autocorrplot.py +0 -72
  64. arviz/plots/backends/matplotlib/bfplot.py +0 -78
  65. arviz/plots/backends/matplotlib/bpvplot.py +0 -177
  66. arviz/plots/backends/matplotlib/compareplot.py +0 -135
  67. arviz/plots/backends/matplotlib/densityplot.py +0 -194
  68. arviz/plots/backends/matplotlib/distcomparisonplot.py +0 -119
  69. arviz/plots/backends/matplotlib/distplot.py +0 -178
  70. arviz/plots/backends/matplotlib/dotplot.py +0 -116
  71. arviz/plots/backends/matplotlib/ecdfplot.py +0 -70
  72. arviz/plots/backends/matplotlib/elpdplot.py +0 -189
  73. arviz/plots/backends/matplotlib/energyplot.py +0 -113
  74. arviz/plots/backends/matplotlib/essplot.py +0 -180
  75. arviz/plots/backends/matplotlib/forestplot.py +0 -656
  76. arviz/plots/backends/matplotlib/hdiplot.py +0 -48
  77. arviz/plots/backends/matplotlib/kdeplot.py +0 -177
  78. arviz/plots/backends/matplotlib/khatplot.py +0 -241
  79. arviz/plots/backends/matplotlib/lmplot.py +0 -149
  80. arviz/plots/backends/matplotlib/loopitplot.py +0 -144
  81. arviz/plots/backends/matplotlib/mcseplot.py +0 -161
  82. arviz/plots/backends/matplotlib/pairplot.py +0 -355
  83. arviz/plots/backends/matplotlib/parallelplot.py +0 -58
  84. arviz/plots/backends/matplotlib/posteriorplot.py +0 -348
  85. arviz/plots/backends/matplotlib/ppcplot.py +0 -478
  86. arviz/plots/backends/matplotlib/rankplot.py +0 -119
  87. arviz/plots/backends/matplotlib/separationplot.py +0 -97
  88. arviz/plots/backends/matplotlib/traceplot.py +0 -526
  89. arviz/plots/backends/matplotlib/tsplot.py +0 -121
  90. arviz/plots/backends/matplotlib/violinplot.py +0 -148
  91. arviz/plots/bfplot.py +0 -128
  92. arviz/plots/bpvplot.py +0 -308
  93. arviz/plots/compareplot.py +0 -177
  94. arviz/plots/densityplot.py +0 -284
  95. arviz/plots/distcomparisonplot.py +0 -197
  96. arviz/plots/distplot.py +0 -233
  97. arviz/plots/dotplot.py +0 -233
  98. arviz/plots/ecdfplot.py +0 -372
  99. arviz/plots/elpdplot.py +0 -174
  100. arviz/plots/energyplot.py +0 -147
  101. arviz/plots/essplot.py +0 -319
  102. arviz/plots/forestplot.py +0 -304
  103. arviz/plots/hdiplot.py +0 -211
  104. arviz/plots/kdeplot.py +0 -357
  105. arviz/plots/khatplot.py +0 -236
  106. arviz/plots/lmplot.py +0 -380
  107. arviz/plots/loopitplot.py +0 -224
  108. arviz/plots/mcseplot.py +0 -194
  109. arviz/plots/pairplot.py +0 -281
  110. arviz/plots/parallelplot.py +0 -204
  111. arviz/plots/plot_utils.py +0 -599
  112. arviz/plots/posteriorplot.py +0 -298
  113. arviz/plots/ppcplot.py +0 -369
  114. arviz/plots/rankplot.py +0 -232
  115. arviz/plots/separationplot.py +0 -167
  116. arviz/plots/styles/arviz-bluish.mplstyle +0 -1
  117. arviz/plots/styles/arviz-brownish.mplstyle +0 -1
  118. arviz/plots/styles/arviz-colors.mplstyle +0 -2
  119. arviz/plots/styles/arviz-cyanish.mplstyle +0 -1
  120. arviz/plots/styles/arviz-darkgrid.mplstyle +0 -40
  121. arviz/plots/styles/arviz-doc.mplstyle +0 -88
  122. arviz/plots/styles/arviz-docgrid.mplstyle +0 -88
  123. arviz/plots/styles/arviz-grayscale.mplstyle +0 -41
  124. arviz/plots/styles/arviz-greenish.mplstyle +0 -1
  125. arviz/plots/styles/arviz-orangish.mplstyle +0 -1
  126. arviz/plots/styles/arviz-plasmish.mplstyle +0 -1
  127. arviz/plots/styles/arviz-purplish.mplstyle +0 -1
  128. arviz/plots/styles/arviz-redish.mplstyle +0 -1
  129. arviz/plots/styles/arviz-royish.mplstyle +0 -1
  130. arviz/plots/styles/arviz-viridish.mplstyle +0 -1
  131. arviz/plots/styles/arviz-white.mplstyle +0 -40
  132. arviz/plots/styles/arviz-whitegrid.mplstyle +0 -40
  133. arviz/plots/traceplot.py +0 -273
  134. arviz/plots/tsplot.py +0 -440
  135. arviz/plots/violinplot.py +0 -192
  136. arviz/preview.py +0 -58
  137. arviz/py.typed +0 -0
  138. arviz/rcparams.py +0 -606
  139. arviz/sel_utils.py +0 -223
  140. arviz/static/css/style.css +0 -340
  141. arviz/static/html/icons-svg-inline.html +0 -15
  142. arviz/stats/__init__.py +0 -37
  143. arviz/stats/density_utils.py +0 -1013
  144. arviz/stats/diagnostics.py +0 -1013
  145. arviz/stats/ecdf_utils.py +0 -324
  146. arviz/stats/stats.py +0 -2422
  147. arviz/stats/stats_refitting.py +0 -119
  148. arviz/stats/stats_utils.py +0 -609
  149. arviz/tests/__init__.py +0 -1
  150. arviz/tests/base_tests/__init__.py +0 -1
  151. arviz/tests/base_tests/test_data.py +0 -1679
  152. arviz/tests/base_tests/test_data_zarr.py +0 -143
  153. arviz/tests/base_tests/test_diagnostics.py +0 -511
  154. arviz/tests/base_tests/test_diagnostics_numba.py +0 -87
  155. arviz/tests/base_tests/test_helpers.py +0 -18
  156. arviz/tests/base_tests/test_labels.py +0 -69
  157. arviz/tests/base_tests/test_plot_utils.py +0 -342
  158. arviz/tests/base_tests/test_plots_bokeh.py +0 -1288
  159. arviz/tests/base_tests/test_plots_matplotlib.py +0 -2197
  160. arviz/tests/base_tests/test_rcparams.py +0 -317
  161. arviz/tests/base_tests/test_stats.py +0 -925
  162. arviz/tests/base_tests/test_stats_ecdf_utils.py +0 -166
  163. arviz/tests/base_tests/test_stats_numba.py +0 -45
  164. arviz/tests/base_tests/test_stats_utils.py +0 -384
  165. arviz/tests/base_tests/test_utils.py +0 -376
  166. arviz/tests/base_tests/test_utils_numba.py +0 -87
  167. arviz/tests/conftest.py +0 -46
  168. arviz/tests/external_tests/__init__.py +0 -1
  169. arviz/tests/external_tests/test_data_beanmachine.py +0 -78
  170. arviz/tests/external_tests/test_data_cmdstan.py +0 -398
  171. arviz/tests/external_tests/test_data_cmdstanpy.py +0 -496
  172. arviz/tests/external_tests/test_data_emcee.py +0 -166
  173. arviz/tests/external_tests/test_data_numpyro.py +0 -434
  174. arviz/tests/external_tests/test_data_pyjags.py +0 -119
  175. arviz/tests/external_tests/test_data_pyro.py +0 -260
  176. arviz/tests/external_tests/test_data_pystan.py +0 -307
  177. arviz/tests/helpers.py +0 -677
  178. arviz/utils.py +0 -773
  179. arviz/wrappers/__init__.py +0 -13
  180. arviz/wrappers/base.py +0 -236
  181. arviz/wrappers/wrap_pymc.py +0 -36
  182. arviz/wrappers/wrap_stan.py +0 -148
  183. arviz-0.23.3.dist-info/METADATA +0 -264
  184. arviz-0.23.3.dist-info/RECORD +0 -183
  185. arviz-0.23.3.dist-info/top_level.txt +0 -1
arviz/rcparams.py DELETED
@@ -1,606 +0,0 @@
1
- """ArviZ rcparams. Based on matplotlib's implementation."""
2
-
3
- import locale
4
- import logging
5
- import os
6
- import pprint
7
- import re
8
- import sys
9
- import warnings
10
- from collections.abc import MutableMapping
11
- from pathlib import Path
12
- from typing import Any, Dict
13
- from typing_extensions import Literal
14
-
15
- NO_GET_ARGS: bool = False # pylint: disable=invalid-name
16
- try:
17
- from typing_extensions import get_args
18
- except ImportError:
19
- NO_GET_ARGS = True # pylint: disable=invalid-name
20
-
21
-
22
- import numpy as np
23
-
24
- _log = logging.getLogger(__name__)
25
-
26
- ScaleKeyword = Literal["log", "negative_log", "deviance"]
27
- ICKeyword = Literal["loo", "waic"]
28
-
29
- _identity = lambda x: x
30
-
31
-
32
- def _make_validate_choice(accepted_values, allow_none=False, typeof=str):
33
- """Validate value is in accepted_values.
34
-
35
- Parameters
36
- ----------
37
- accepted_values : iterable
38
- Iterable containing all accepted_values.
39
- allow_none: boolean, optional
40
- Whether to accept ``None`` in addition to the values in ``accepted_values``.
41
- typeof: type, optional
42
- Type the values should be converted to.
43
- """
44
- # no blank lines allowed after function docstring by pydocstyle,
45
- # but black requires white line before function
46
-
47
- def validate_choice(value):
48
- if allow_none and (value is None or isinstance(value, str) and value.lower() == "none"):
49
- return None
50
- try:
51
- value = typeof(value)
52
- except (ValueError, TypeError) as err:
53
- raise ValueError(f"Could not convert to {typeof.__name__}") from err
54
- if isinstance(value, str):
55
- value = value.lower()
56
-
57
- if value in accepted_values:
58
- # Convert value to python boolean if string matches
59
- value = {"true": True, "false": False}.get(value, value)
60
- return value
61
- raise ValueError(
62
- f'{value} is not one of {accepted_values}{" nor None" if allow_none else ""}'
63
- )
64
-
65
- return validate_choice
66
-
67
-
68
- def _make_validate_choice_regex(accepted_values, accepted_values_regex, allow_none=False):
69
- """Validate value is in accepted_values with regex.
70
-
71
- Parameters
72
- ----------
73
- accepted_values : iterable
74
- Iterable containing all accepted_values.
75
- accepted_values_regex : iterable
76
- Iterable containing all accepted_values with regex string.
77
- allow_none: boolean, optional
78
- Whether to accept ``None`` in addition to the values in ``accepted_values``.
79
- typeof: type, optional
80
- Type the values should be converted to.
81
- """
82
- # no blank lines allowed after function docstring by pydocstyle,
83
- # but black requires white line before function
84
-
85
- def validate_choice_regex(value):
86
- if allow_none and (value is None or isinstance(value, str) and value.lower() == "none"):
87
- return None
88
- value = str(value)
89
- if isinstance(value, str):
90
- value = value.lower()
91
-
92
- if value in accepted_values:
93
- # Convert value to python boolean if string matches
94
- value = {"true": True, "false": False}.get(value, value)
95
- return value
96
- elif any(re.match(pattern, value) for pattern in accepted_values_regex):
97
- return value
98
- raise ValueError(
99
- f"{value} is not one of {accepted_values} "
100
- f'or in regex {accepted_values_regex}{" nor None" if allow_none else ""}'
101
- )
102
-
103
- return validate_choice_regex
104
-
105
-
106
- def _validate_positive_int(value):
107
- """Validate value is a natural number."""
108
- try:
109
- value = int(value)
110
- except ValueError as err:
111
- raise ValueError("Could not convert to int") from err
112
- if value > 0:
113
- return value
114
- else:
115
- raise ValueError("Only positive values are valid")
116
-
117
-
118
- def _validate_float(value):
119
- """Validate value is a float."""
120
- try:
121
- value = float(value)
122
- except ValueError as err:
123
- raise ValueError("Could not convert to float") from err
124
- return value
125
-
126
-
127
- def _validate_probability(value):
128
- """Validate a probability: a float between 0 and 1."""
129
- value = _validate_float(value)
130
- if (value < 0) or (value > 1):
131
- raise ValueError("Only values between 0 and 1 are valid.")
132
- return value
133
-
134
-
135
- def _validate_boolean(value):
136
- """Validate value is a float."""
137
- if isinstance(value, str):
138
- value = value.lower()
139
- if value not in {True, False, "true", "false"}:
140
- raise ValueError("Only boolean values are valid.")
141
- return value is True or value == "true"
142
-
143
-
144
- def _add_none_to_validator(base_validator):
145
- """Create a validator function that catches none and then calls base_fun."""
146
- # no blank lines allowed after function docstring by pydocstyle,
147
- # but black requires white line before function
148
-
149
- def validate_with_none(value):
150
- if value is None or isinstance(value, str) and value.lower() == "none":
151
- return None
152
- return base_validator(value)
153
-
154
- return validate_with_none
155
-
156
-
157
- def _validate_bokeh_marker(value):
158
- """Validate the markers."""
159
- try:
160
- from bokeh.core.enums import MarkerType
161
- except ImportError:
162
- MarkerType = [
163
- "asterisk",
164
- "circle",
165
- "circle_cross",
166
- "circle_dot",
167
- "circle_x",
168
- "circle_y",
169
- "cross",
170
- "dash",
171
- "diamond",
172
- "diamond_cross",
173
- "diamond_dot",
174
- "dot",
175
- "hex",
176
- "hex_dot",
177
- "inverted_triangle",
178
- "plus",
179
- "square",
180
- "square_cross",
181
- "square_dot",
182
- "square_pin",
183
- "square_x",
184
- "star",
185
- "star_dot",
186
- "triangle",
187
- "triangle_dot",
188
- "triangle_pin",
189
- "x",
190
- "y",
191
- ]
192
- all_markers = list(MarkerType)
193
- if value not in all_markers:
194
- raise ValueError(f"{value} is not one of {all_markers}")
195
- return value
196
-
197
-
198
- def _validate_dict_of_lists(values):
199
- if isinstance(values, dict):
200
- return {key: tuple(item) for key, item in values.items()}
201
- validated_dict = {}
202
- for value in values:
203
- tup = value.split(":", 1)
204
- if len(tup) != 2:
205
- raise ValueError(f"Could not interpret '{value}' as key: list or str")
206
- key, vals = tup
207
- key = key.strip(' "')
208
- vals = [val.strip(' "') for val in vals.strip(" [],").split(",")]
209
- if key in validated_dict:
210
- warnings.warn(f"Repeated key {key} when validating dict of lists")
211
- validated_dict[key] = tuple(vals)
212
- return validated_dict
213
-
214
-
215
- def make_iterable_validator(scalar_validator, length=None, allow_none=False, allow_auto=False):
216
- """Validate value is an iterable datatype."""
217
- # based on matplotlib's _listify_validator function
218
-
219
- def validate_iterable(value):
220
- if allow_none and (value is None or isinstance(value, str) and value.lower() == "none"):
221
- return None
222
- if isinstance(value, str):
223
- if allow_auto and value.lower() == "auto":
224
- return "auto"
225
- value = tuple(v.strip("([ ])") for v in value.split(",") if v.strip())
226
- if np.iterable(value) and not isinstance(value, (set, frozenset)):
227
- val = tuple(scalar_validator(v) for v in value)
228
- if length is not None and len(val) != length:
229
- raise ValueError(f"Iterable must be of length: {length}")
230
- return val
231
- raise ValueError("Only ordered iterable values are valid")
232
-
233
- return validate_iterable
234
-
235
-
236
- _validate_float_or_none = _add_none_to_validator(_validate_float)
237
- _validate_positive_int_or_none = _add_none_to_validator(_validate_positive_int)
238
- _validate_bokeh_bounds = make_iterable_validator( # pylint: disable=invalid-name
239
- _validate_float_or_none, length=2, allow_none=True, allow_auto=True
240
- )
241
-
242
- METAGROUPS = {
243
- "posterior_groups": ["posterior", "posterior_predictive", "sample_stats", "log_likelihood"],
244
- "prior_groups": ["prior", "prior_predictive", "sample_stats_prior"],
245
- "posterior_groups_warmup": [
246
- "_warmup_posterior",
247
- "_warmup_posterior_predictive",
248
- "_warmup_sample_stats",
249
- ],
250
- "latent_vars": ["posterior", "prior"],
251
- "observed_vars": ["posterior_predictive", "observed_data", "prior_predictive"],
252
- }
253
-
254
- defaultParams = { # pylint: disable=invalid-name
255
- "data.http_protocol": ("https", _make_validate_choice({"https", "http"})),
256
- "data.load": ("lazy", _make_validate_choice({"lazy", "eager"})),
257
- "data.metagroups": (METAGROUPS, _validate_dict_of_lists),
258
- "data.index_origin": (0, _make_validate_choice({0, 1}, typeof=int)),
259
- "data.log_likelihood": (True, _validate_boolean),
260
- "data.save_warmup": (False, _validate_boolean),
261
- "plot.backend": ("matplotlib", _make_validate_choice({"matplotlib", "bokeh"})),
262
- "plot.density_kind": ("kde", _make_validate_choice({"kde", "hist"})),
263
- "plot.max_subplots": (40, _validate_positive_int_or_none),
264
- "plot.point_estimate": (
265
- "mean",
266
- _make_validate_choice({"mean", "median", "mode"}, allow_none=True),
267
- ),
268
- "plot.bokeh.bounds_x_range": ("auto", _validate_bokeh_bounds),
269
- "plot.bokeh.bounds_y_range": ("auto", _validate_bokeh_bounds),
270
- "plot.bokeh.figure.dpi": (60, _validate_positive_int),
271
- "plot.bokeh.figure.height": (500, _validate_positive_int),
272
- "plot.bokeh.figure.width": (500, _validate_positive_int),
273
- "plot.bokeh.layout.order": (
274
- "default",
275
- _make_validate_choice_regex(
276
- {"default", r"column", r"row", "square", "square_trimmed"}, {r"\d*column", r"\d*row"}
277
- ),
278
- ),
279
- "plot.bokeh.layout.sizing_mode": (
280
- "fixed",
281
- _make_validate_choice(
282
- {
283
- "fixed",
284
- "stretch_width",
285
- "stretch_height",
286
- "stretch_both",
287
- "scale_width",
288
- "scale_height",
289
- "scale_both",
290
- }
291
- ),
292
- ),
293
- "plot.bokeh.layout.toolbar_location": (
294
- "above",
295
- _make_validate_choice({"above", "below", "left", "right"}, allow_none=True),
296
- ),
297
- "plot.bokeh.marker": ("cross", _validate_bokeh_marker),
298
- "plot.bokeh.output_backend": ("webgl", _make_validate_choice({"canvas", "svg", "webgl"})),
299
- "plot.bokeh.show": (True, _validate_boolean),
300
- "plot.bokeh.tools": (
301
- "reset,pan,box_zoom,wheel_zoom,lasso_select,undo,save,hover",
302
- lambda x: x,
303
- ),
304
- "plot.matplotlib.show": (False, _validate_boolean),
305
- "stats.ci_prob": (0.94, _validate_probability),
306
- "stats.information_criterion": (
307
- "loo",
308
- _make_validate_choice({"loo", "waic"} if NO_GET_ARGS else set(get_args(ICKeyword))),
309
- ),
310
- "stats.ic_pointwise": (True, _validate_boolean),
311
- "stats.ic_scale": (
312
- "log",
313
- _make_validate_choice(
314
- {"log", "negative_log", "deviance"} if NO_GET_ARGS else set(get_args(ScaleKeyword))
315
- ),
316
- ),
317
- "stats.ic_compare_method": (
318
- "stacking",
319
- _make_validate_choice({"stacking", "bb-pseudo-bma", "pseudo-bma"}),
320
- ),
321
- }
322
-
323
- # map from deprecated params to (version, new_param, fold2new, fnew2old)
324
- deprecated_map = {"stats.hdi_prob": ("0.18.0", "stats.ci_prob", _identity, _identity)}
325
-
326
-
327
- class RcParams(MutableMapping):
328
- """Class to contain ArviZ default parameters.
329
-
330
- It is implemented as a dict with validation when setting items.
331
- """
332
-
333
- validate = {key: validate_fun for key, (_, validate_fun) in defaultParams.items()}
334
-
335
- # validate values on the way in
336
- def __init__(self, *args, **kwargs):
337
- self._underlying_storage: Dict[str, Any] = {}
338
- super().__init__()
339
- self.update(*args, **kwargs)
340
-
341
- def __setitem__(self, key, val):
342
- """Add validation to __setitem__ function."""
343
- if key in deprecated_map:
344
- version, key_new, fold2new, _ = deprecated_map[key]
345
- warnings.warn(
346
- f"{key} is deprecated since {version}, use {key_new} instead",
347
- FutureWarning,
348
- )
349
- key = key_new
350
- val = fold2new(val)
351
-
352
- try:
353
- try:
354
- cval = self.validate[key](val)
355
- except ValueError as verr:
356
- raise ValueError(f"Key {key}: {str(verr)}") from verr
357
- self._underlying_storage[key] = cval
358
- except KeyError as err:
359
- raise KeyError(
360
- f"{key} is not a valid rc parameter "
361
- f"(see rcParams.keys() for a list of valid parameters)"
362
- ) from err
363
-
364
- def __getitem__(self, key):
365
- """Use underlying dict's getitem method."""
366
- if key in deprecated_map:
367
- version, key_new, _, fnew2old = deprecated_map[key]
368
- warnings.warn(
369
- f"{key} is deprecated since {version}, use {key_new} instead",
370
- FutureWarning,
371
- )
372
- if key not in self._underlying_storage:
373
- key = key_new
374
- else:
375
- fnew2old = _identity
376
-
377
- return fnew2old(self._underlying_storage[key])
378
-
379
- def __delitem__(self, key):
380
- """Raise TypeError if someone ever tries to delete a key from RcParams."""
381
- raise TypeError("RcParams keys cannot be deleted")
382
-
383
- def clear(self):
384
- """Raise TypeError if someone ever tries to delete all keys from RcParams."""
385
- raise TypeError("RcParams keys cannot be deleted")
386
-
387
- def pop(self, key, default=None):
388
- """Raise TypeError if someone ever tries to delete a key from RcParams."""
389
- raise TypeError(
390
- "RcParams keys cannot be deleted. Use .get(key) of RcParams[key] to check values"
391
- )
392
-
393
- def popitem(self):
394
- """Raise TypeError if someone ever tries to delete a key from RcParams."""
395
- raise TypeError(
396
- "RcParams keys cannot be deleted. Use .get(key) of RcParams[key] to check values"
397
- )
398
-
399
- def setdefault(self, key, default=None):
400
- """Raise error when using setdefault, defaults are handled on initialization."""
401
- raise TypeError(
402
- "Defaults in RcParams are handled on object initialization during library"
403
- "import. Use arvizrc file instead."
404
- ""
405
- )
406
-
407
- def __repr__(self):
408
- """Customize repr of RcParams objects."""
409
- class_name = self.__class__.__name__
410
- indent = len(class_name) + 1
411
- repr_split = pprint.pformat(
412
- self._underlying_storage,
413
- indent=1,
414
- width=80 - indent,
415
- ).split("\n")
416
- repr_indented = ("\n" + " " * indent).join(repr_split)
417
- return f"{class_name}({repr_indented})"
418
-
419
- def __str__(self):
420
- """Customize str/print of RcParams objects."""
421
- return "\n".join(map("{0[0]:<22}: {0[1]}".format, sorted(self._underlying_storage.items())))
422
-
423
- def __iter__(self):
424
- """Yield sorted list of keys."""
425
- yield from sorted(self._underlying_storage.keys())
426
-
427
- def __len__(self):
428
- """Use underlying dict's len method."""
429
- return len(self._underlying_storage)
430
-
431
- def find_all(self, pattern):
432
- """
433
- Find keys that match a regex pattern.
434
-
435
- Return the subset of this RcParams dictionary whose keys match,
436
- using :func:`re.search`, the given ``pattern``.
437
-
438
- Notes
439
- -----
440
- Changes to the returned dictionary are *not* propagated to
441
- the parent RcParams dictionary.
442
- """
443
- pattern_re = re.compile(pattern)
444
- return RcParams((key, value) for key, value in self.items() if pattern_re.search(key))
445
-
446
- def copy(self):
447
- """Get a copy of the RcParams object."""
448
- return dict(self._underlying_storage)
449
-
450
-
451
- def get_arviz_rcfile():
452
- """Get arvizrc file.
453
-
454
- The file location is determined in the following order:
455
-
456
- - ``$PWD/arvizrc``
457
- - ``$ARVIZ_DATA/arvizrc``
458
- - On Linux,
459
- - ``$XDG_CONFIG_HOME/arviz/arvizrc`` (if ``$XDG_CONFIG_HOME``
460
- is defined)
461
- - or ``$HOME/.config/arviz/arvizrc`` (if ``$XDG_CONFIG_HOME``
462
- is not defined)
463
- - On other platforms,
464
- - ``$HOME/.arviz/arvizrc`` if ``$HOME`` is defined
465
-
466
- Otherwise, the default defined in ``rcparams.py`` file will be used.
467
- """
468
- # no blank lines allowed after function docstring by pydocstyle,
469
- # but black requires white line before function
470
-
471
- def gen_candidates():
472
- yield os.path.join(os.getcwd(), "arvizrc")
473
- arviz_data_dir = os.environ.get("ARVIZ_DATA")
474
- if arviz_data_dir:
475
- yield os.path.join(arviz_data_dir, "arvizrc")
476
- xdg_base = os.environ.get("XDG_CONFIG_HOME", str(Path.home() / ".config"))
477
- if sys.platform.startswith(("linux", "freebsd")):
478
- configdir = str(Path(xdg_base, "arviz"))
479
- else:
480
- configdir = str(Path.home() / ".arviz")
481
- yield os.path.join(configdir, "arvizrc")
482
-
483
- for fname in gen_candidates():
484
- if os.path.exists(fname) and not os.path.isdir(fname):
485
- return fname
486
-
487
- return None
488
-
489
-
490
- def read_rcfile(fname):
491
- """Return :class:`arviz.RcParams` from the contents of the given file.
492
-
493
- Unlike `rc_params_from_file`, the configuration class only contains the
494
- parameters specified in the file (i.e. default values are not filled in).
495
- """
496
- _error_details_fmt = 'line #%d\n\t"%s"\n\tin file "%s"'
497
-
498
- config = RcParams()
499
- with open(fname, "r", encoding="utf8") as rcfile:
500
- try:
501
- multiline = False
502
- for line_no, line in enumerate(rcfile, 1):
503
- strippedline = line.split("#", 1)[0].strip()
504
- if not strippedline:
505
- continue
506
- if multiline:
507
- if strippedline == "}":
508
- multiline = False
509
- val = aux_val
510
- else:
511
- aux_val.append(strippedline)
512
- continue
513
- else:
514
- tup = strippedline.split(":", 1)
515
- if len(tup) != 2:
516
- error_details = _error_details_fmt % (line_no, line, fname)
517
- _log.warning("Illegal %s", error_details)
518
- continue
519
- key, val = tup
520
- key = key.strip()
521
- val = val.strip()
522
- if key in config:
523
- _log.warning("Duplicate key in file %r line #%d.", fname, line_no)
524
- if key in {"data.metagroups"}:
525
- aux_val = []
526
- multiline = True
527
- continue
528
- try:
529
- config[key] = val
530
- except ValueError as verr:
531
- error_details = _error_details_fmt % (line_no, line, fname)
532
- raise ValueError(f"Bad val {val} on {error_details}\n\t{str(verr)}") from verr
533
-
534
- except UnicodeDecodeError:
535
- _log.warning(
536
- "Cannot decode configuration file %s with encoding "
537
- "%s, check LANG and LC_* variables.",
538
- fname,
539
- locale.getpreferredencoding(do_setlocale=False) or "utf-8 (default)",
540
- )
541
- raise
542
-
543
- return config
544
-
545
-
546
- def rc_params(ignore_files=False):
547
- """Read and validate arvizrc file."""
548
- fname = None if ignore_files else get_arviz_rcfile()
549
- defaults = RcParams([(key, default) for key, (default, _) in defaultParams.items()])
550
- if fname is not None:
551
- file_defaults = read_rcfile(fname)
552
- defaults.update(file_defaults)
553
- return defaults
554
-
555
-
556
- rcParams = rc_params() # pylint: disable=invalid-name
557
-
558
-
559
- class rc_context: # pylint: disable=invalid-name
560
- """
561
- Return a context manager for managing rc settings.
562
-
563
- Parameters
564
- ----------
565
- rc : dict, optional
566
- Mapping containing the rcParams to modify temporally.
567
- fname : str, optional
568
- Filename of the file containing the rcParams to use inside the rc_context.
569
-
570
- Examples
571
- --------
572
- This allows one to do::
573
-
574
- with az.rc_context(fname='pystan.rc'):
575
- idata = az.load_arviz_data("radon")
576
- az.plot_posterior(idata, var_names=["gamma"])
577
-
578
- The plot would have settings from 'screen.rc'
579
-
580
- A dictionary can also be passed to the context manager::
581
-
582
- with az.rc_context(rc={'plot.max_subplots': None}, fname='pystan.rc'):
583
- idata = az.load_arviz_data("radon")
584
- az.plot_posterior(idata, var_names=["gamma"])
585
-
586
- The 'rc' dictionary takes precedence over the settings loaded from
587
- 'fname'. Passing a dictionary only is also valid.
588
- """
589
-
590
- # Based on mpl.rc_context
591
-
592
- def __init__(self, rc=None, fname=None):
593
- self._orig = rcParams.copy()
594
- if fname:
595
- file_rcparams = read_rcfile(fname)
596
- rcParams.update(file_rcparams)
597
- if rc:
598
- rcParams.update(rc)
599
-
600
- def __enter__(self):
601
- """Define enter method of context manager."""
602
- return self
603
-
604
- def __exit__(self, exc_type, exc_value, exc_tb):
605
- """Define exit method of context manager."""
606
- rcParams.update(self._orig)