cdxcore 0.1.14__py3-none-any.whl → 0.1.15__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.
Potentially problematic release.
This version of cdxcore might be problematic. Click here for more details.
- cdxcore/__init__.py +1 -1
- cdxcore/crman.py +1 -1
- cdxcore/deferred.py +329 -143
- cdxcore/dynaplot.py +14 -264
- cdxcore/dynaplotlimits.py +245 -0
- cdxcore/util.py +5 -5
- cdxcore/version.py +3 -3
- {cdxcore-0.1.14.dist-info → cdxcore-0.1.15.dist-info}/METADATA +1 -1
- {cdxcore-0.1.14.dist-info → cdxcore-0.1.15.dist-info}/RECORD +15 -13
- docs/source/conf.py +1 -6
- tests/test_deferred.py +23 -3
- tmp/deferred-hierarchical.py +682 -0
- {cdxcore-0.1.14.dist-info → cdxcore-0.1.15.dist-info}/WHEEL +0 -0
- {cdxcore-0.1.14.dist-info → cdxcore-0.1.15.dist-info}/licenses/LICENSE +0 -0
- {cdxcore-0.1.14.dist-info → cdxcore-0.1.15.dist-info}/top_level.txt +0 -0
cdxcore/dynaplot.py
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
Overview
|
|
3
|
+
--------
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Basic utilities for Python such as type management, formatting, some trivial timers.
|
|
6
|
+
|
|
7
|
+
Import
|
|
8
|
+
------
|
|
9
|
+
.. code-block:: python
|
|
10
|
+
|
|
11
|
+
import cdxcore.util as util
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ax.plot(x,y)
|
|
10
|
-
ax = fig.add_subplot()
|
|
11
|
-
ax.plot(x,z)
|
|
12
|
-
fig.close()
|
|
13
|
-
|
|
14
|
-
Hans Buehler 2022
|
|
13
|
+
Documentation
|
|
14
|
+
-------------
|
|
15
15
|
"""
|
|
16
16
|
import matplotlib.pyplot as plt
|
|
17
17
|
from matplotlib.gridspec import GridSpec#NOQA
|
|
@@ -22,260 +22,10 @@ from IPython import display
|
|
|
22
22
|
import io as io
|
|
23
23
|
import gc as gc
|
|
24
24
|
import types as types
|
|
25
|
-
import numpy as np
|
|
26
|
-
from .deferred import Deferred
|
|
27
|
-
from .util import fmt as txtfmt
|
|
28
25
|
from collections.abc import Collection
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
raise exception( txtfmt(text, *args, **kwargs) )
|
|
33
|
-
def verify( cond, text, *args, exception = RuntimeError, **kwargs ):
|
|
34
|
-
if not cond:
|
|
35
|
-
error( text, *args, **kwargs, exception=exception )
|
|
36
|
-
def warn( text, *args, warning=warnings.RuntimeWarning, stack_level=1, **kwargs ):
|
|
37
|
-
warnings.warn( txtfmt(text, *args, **kwargs), warning, stack_level=stack_level )
|
|
38
|
-
def warn_if( cond, text, *args, warning=warnings.RuntimeWarning, stack_level=1, **kwargs ):
|
|
39
|
-
if cond:
|
|
40
|
-
warn( text, *args, warning=warning, stack_level=stack_level, **kwargs )
|
|
41
|
-
|
|
42
|
-
class AutoLimits( object ):
|
|
43
|
-
"""
|
|
44
|
-
Max/Min limit manger for dynamic figures.
|
|
45
|
-
|
|
46
|
-
limits = MinMaxLimit( 0.05, 0.95 )
|
|
47
|
-
ax.add_subplot( x,y ,.. )
|
|
48
|
-
limits.update(x, y)
|
|
49
|
-
ax.add_subplot( x,z,.. )
|
|
50
|
-
limits.update(x, z)
|
|
51
|
-
limits.set_lims(ax)
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
|
-
def __init__(self, low_quantile, high_quantile, min_length : int = 10, lookback : int = None ):
|
|
55
|
-
"""
|
|
56
|
-
Initialize MinMaxLimit.
|
|
57
|
-
|
|
58
|
-
Parameters
|
|
59
|
-
----------
|
|
60
|
-
low_quantile : float
|
|
61
|
-
Lower quantile to use for computing a 'min' y value. Set to 0 to use 'min'.
|
|
62
|
-
high_quantile : float
|
|
63
|
-
Higher quantile to use for computing a 'min' y value. Set to 1 to use 'max'.
|
|
64
|
-
min_length : int
|
|
65
|
-
Minimum length data must have to use quantile(). If less data is presented,
|
|
66
|
-
use min/max, respectively.
|
|
67
|
-
lookback : int
|
|
68
|
-
How many steps to lookback for any calculation. None to use all steps
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
verify( low_quantile >=0., "'low_quantile' must not be negative", exception=ValueError )
|
|
72
|
-
verify( high_quantile <=1., "'high_quantile' must not exceed 1", exception=ValueError )
|
|
73
|
-
verify( low_quantile<=high_quantile, "'low_quantile' not exceed 'high_quantile'", exception=ValueError )
|
|
74
|
-
self.lo_q = low_quantile
|
|
75
|
-
self.hi_q = high_quantile
|
|
76
|
-
self.min_length = int(min_length)
|
|
77
|
-
self.lookback = int(lookback) if not lookback is None else None
|
|
78
|
-
self.max_y = None
|
|
79
|
-
self.min_y = None
|
|
80
|
-
self.min_x = None
|
|
81
|
-
self.max_x = None
|
|
82
|
-
|
|
83
|
-
def update(self, *args, axis=None ):
|
|
84
|
-
"""
|
|
85
|
-
Add a data set to the min/max calc
|
|
86
|
-
|
|
87
|
-
If the x axis is ordinal first dimension of 'y':
|
|
88
|
-
update(y, axis=axis )
|
|
89
|
-
In this case x = np.linspace(1,y.shape[0],y.shape[0])
|
|
90
|
-
|
|
91
|
-
Specifcy x axis
|
|
92
|
-
update(x, y, axis=axis )
|
|
93
|
-
|
|
94
|
-
Parameters
|
|
95
|
-
----------
|
|
96
|
-
*args:
|
|
97
|
-
Either y or x,y
|
|
98
|
-
axis:
|
|
99
|
-
along which axis to compute min/max/quantiles
|
|
100
|
-
"""
|
|
101
|
-
assert len(args) in [1,2], ("'args' must be 1 or 2", len(args))
|
|
102
|
-
|
|
103
|
-
y = args[-1]
|
|
104
|
-
x = args[0] if len(args) > 1 else None
|
|
105
|
-
|
|
106
|
-
if len(y) == 0:
|
|
107
|
-
return
|
|
108
|
-
if axis is None:
|
|
109
|
-
axis = None if len(y.shape) <= 1 else tuple(list(y.shape)[1])
|
|
110
|
-
|
|
111
|
-
y_len = y.shape[0]
|
|
112
|
-
if not self.lookback is None:
|
|
113
|
-
y = y[-self.lookback:,...]
|
|
114
|
-
x = x[-self.lookback:,...] if not x is None else None
|
|
115
|
-
|
|
116
|
-
min_y = np.min( np.quantile( y, self.lo_q, axis=axis ) ) if self.lo_q > 0. and len(y) > self.min_length else np.min( y )
|
|
117
|
-
max_y = np.max( np.quantile( y, self.hi_q, axis=axis ) ) if self.hi_q < 1. and len(y) > self.min_length else np.max( y )
|
|
118
|
-
assert min_y <= max_y, ("Internal error", min_y, max_y, y)
|
|
119
|
-
self.min_y = min_y if self.min_y is None else min( self.min_y, min_y )
|
|
120
|
-
self.max_y = max_y if self.max_y is None else max( self.max_y, max_y )
|
|
121
|
-
|
|
122
|
-
if x is None:
|
|
123
|
-
self.min_x = 1
|
|
124
|
-
self.max_x = y_len if self.max_x is None else max( y_len, self.max_x )
|
|
125
|
-
else:
|
|
126
|
-
min_ = np.min( x )
|
|
127
|
-
max_ = np.max( x )
|
|
128
|
-
self.min_x = min_ if self.max_x is None else min( self.min_x, min_ )
|
|
129
|
-
self.max_x = max_ if self.max_x is None else max( self.max_x, max_ )
|
|
130
|
-
|
|
131
|
-
return self
|
|
132
|
-
|
|
133
|
-
def set( self, *, min_x = None, max_x = None,
|
|
134
|
-
min_y = None, max_y = None ) -> type:
|
|
135
|
-
"""
|
|
136
|
-
Overwrite any of the extrema.
|
|
137
|
-
Imposing an extrema also sets the other side if this would violate the requrest eg if min_x is set the function also floors self.max_x at min_x
|
|
138
|
-
Returns 'self.'
|
|
139
|
-
"""
|
|
140
|
-
verify( min_x is None or max_x is None or min_x <= max_x, "'min_x' and 'max_'x are in wrong order", min_x, max_x, exception=ValueError )
|
|
141
|
-
if not min_x is None:
|
|
142
|
-
self.min_x = min_x
|
|
143
|
-
self.max_x = min( self.max_x, min_x )
|
|
144
|
-
if not max_x is None:
|
|
145
|
-
self.min_x = max( self.min_x, max_x )
|
|
146
|
-
self.max_x = max_x
|
|
147
|
-
|
|
148
|
-
verify( min_y is None or max_y is None or min_y <= max_y, "'min_y' and 'max_'x are in wrong order", min_y, max_y, exception=ValueError )
|
|
149
|
-
if not min_y is None:
|
|
150
|
-
self.min_y = min_y
|
|
151
|
-
self.max_y = min( self.max_y, min_y )
|
|
152
|
-
if not max_y is None:
|
|
153
|
-
self.min_y = max( self.min_y, max_y )
|
|
154
|
-
self.max_y = max_y
|
|
155
|
-
return self
|
|
156
|
-
|
|
157
|
-
def bound( self, *, min_x_at_least = None, max_x_at_most = None, # <= boundary limits
|
|
158
|
-
min_y_at_least = None, max_y_at_most = None,
|
|
159
|
-
):
|
|
160
|
-
"""
|
|
161
|
-
Bound extrema
|
|
162
|
-
"""
|
|
163
|
-
verify( min_x_at_least is None or max_x_at_most is None or min_x_at_least <= max_x_at_most, "'min_x_at_least' and 'max_x_at_most'x are in wrong order", min_x_at_least, max_x_at_most, exception=ValueError )
|
|
164
|
-
if not min_x_at_least is None:
|
|
165
|
-
self.min_x = max( self.min_x, min_x_at_least )
|
|
166
|
-
self.max_x = max( self.max_x, min_x_at_least )
|
|
167
|
-
if not max_x_at_most is None:
|
|
168
|
-
self.min_x = min( self.min_x, max_x_at_most )
|
|
169
|
-
self.max_x = min( self.max_x, max_x_at_most )
|
|
170
|
-
|
|
171
|
-
verify( min_y_at_least is None or max_y_at_most is None or min_y_at_least <= max_y_at_most, "'min_y_at_least' and 'max_y_at_most'x are in wrong order", min_y_at_least, max_y_at_most, exception=ValueError )
|
|
172
|
-
if not min_y_at_least is None:
|
|
173
|
-
self.min_y = max( self.min_y, min_y_at_least )
|
|
174
|
-
self.max_y = max( self.max_y, min_y_at_least )
|
|
175
|
-
if not max_y_at_most is None:
|
|
176
|
-
self.min_y = min( self.min_y, max_y_at_most )
|
|
177
|
-
self.max_y = min( self.max_y, max_y_at_most )
|
|
178
|
-
return self
|
|
179
|
-
|
|
180
|
-
def set_a_lim( self, ax,*, is_x,
|
|
181
|
-
min_d,
|
|
182
|
-
rspace,
|
|
183
|
-
min_set = None,
|
|
184
|
-
max_set = None,
|
|
185
|
-
min_at_least = None,
|
|
186
|
-
max_at_most = None ):
|
|
187
|
-
""" Utility function """
|
|
188
|
-
min_ = self.min_x if is_x else self.min_y
|
|
189
|
-
max_ = self.max_x if is_x else self.max_y
|
|
190
|
-
ax_scale = (ax.get_xaxis() if is_x else ax.get_yaxis()).get_scale()
|
|
191
|
-
label = "x" if is_x else "y"
|
|
192
|
-
f = ax.set_xlim if is_x else ax.set_ylim
|
|
193
|
-
|
|
194
|
-
if min_ is None or max_ is None:
|
|
195
|
-
warn( "No data recevied yet; ignoring call" )
|
|
196
|
-
return
|
|
197
|
-
assert min_ <= max_, ("Internal error (1): min and max are not in order", label, min_, max_)
|
|
198
|
-
|
|
199
|
-
verify( min_set is None or max_set is None or min_set <= max_set, "'min_set_%s' exceeds 'max_set_%s': found %g and %g, respectively", label, label, min_set, max_set, exception=RuntimeError )
|
|
200
|
-
verify( min_at_least is None or max_at_most is None or min_at_least <= max_at_most, "'min_at_least_%s' exceeds 'max_at_most_%s': found %g and %g, respectively", label, label, min_at_least, max_at_most, exception=RuntimeError )
|
|
201
|
-
|
|
202
|
-
if not min_set is None:
|
|
203
|
-
min_ = min_set
|
|
204
|
-
max_ = max(min_set, max_)
|
|
205
|
-
if not max_set is None:
|
|
206
|
-
min_ = min(min_, max_set)
|
|
207
|
-
max_ = max_set
|
|
208
|
-
if not min_at_least is None:
|
|
209
|
-
min_ = max( min_, min_at_least )
|
|
210
|
-
max_ = max( max_, min_at_least )
|
|
211
|
-
if not max_at_most is None:
|
|
212
|
-
min_ = min( min_, max_at_most )
|
|
213
|
-
max_ = min( max_, max_at_most )
|
|
214
|
-
|
|
215
|
-
assert min_ <= max_, ("Internal error (2): min and max are not in order", label, min_, max_)
|
|
216
|
-
|
|
217
|
-
if isinstance( max_, int ):
|
|
218
|
-
verify( ax_scale == "linear", "Only 'linear' %s axis supported for integer based %s coordinates; found '%s'", label, label, ax_scale, exception=AttributeError )
|
|
219
|
-
max_ = max(max_, min_+1)
|
|
220
|
-
f( min_, max_ )
|
|
221
|
-
else:
|
|
222
|
-
d = max( max_-min_, min_d ) * rspace
|
|
223
|
-
if ax_scale == "linear":
|
|
224
|
-
f( min_ - d, max_ + d )
|
|
225
|
-
else:
|
|
226
|
-
verify( ax_scale == "log", "Only 'linear' and 'log' %s axis scales are supported; found '%s'", label, ax_scale, exception=AttributeError )
|
|
227
|
-
verify( min_ > 0., "Minimum for 'log' %s axis must be positive; found %g", label, min_)
|
|
228
|
-
rdx = np.exp( d )
|
|
229
|
-
f( min_ / rdx, max_ * rdx )
|
|
230
|
-
return self
|
|
231
|
-
|
|
232
|
-
def set_ylim(self, ax, *, min_dy : float = 1E-4, yrspace : float = 0.001, min_set_y = None, max_set_y = None, min_y_at_least = None, max_y_at_most = None ):
|
|
233
|
-
"""
|
|
234
|
-
Set x limits for 'ax'. See set_lims()
|
|
235
|
-
"""
|
|
236
|
-
return self.set_a_lim( ax, is_x=False, min_d=min_dy, rspace=yrspace, min_set=min_set_y, max_set=max_set_y, min_at_least=min_y_at_least, max_at_most=max_y_at_most )
|
|
237
|
-
|
|
238
|
-
def set_xlim(self, ax, *, min_dx : float = 1E-4, xrspace : float = 0.001, min_set_x = None, max_set_x = None, min_x_at_least = None, max_x_at_most = None ):
|
|
239
|
-
"""
|
|
240
|
-
Set x limits for 'ax'. See set_lims()
|
|
241
|
-
"""
|
|
242
|
-
return self.set_a_lim( ax, is_x=True, min_d=min_dx, rspace=xrspace, min_set=min_set_x, max_set=max_set_x, min_at_least=min_x_at_least, max_at_most=max_x_at_most )
|
|
243
|
-
|
|
244
|
-
def set_lims( self, ax, *, x : bool = True, y : bool = True,
|
|
245
|
-
min_dx : float = 1E-4, min_dy = 1E-4, xrspace = 0.001, yrspace = 0.001,
|
|
246
|
-
min_set_x = None, max_set_x = None, min_x_at_least = None, max_x_at_most = None,
|
|
247
|
-
min_set_y = None, max_set_y = None, min_y_at_least = None, max_y_at_most = None):
|
|
248
|
-
"""
|
|
249
|
-
Set x and/or y limits for 'ax'.
|
|
250
|
-
|
|
251
|
-
For example for the x axis: let
|
|
252
|
-
dx := max( max_x - min_x, min_dx )*xrspace
|
|
253
|
-
|
|
254
|
-
For linear axes:
|
|
255
|
-
set_xlim( min_x - dy, max_x + dx )
|
|
256
|
-
|
|
257
|
-
For logarithmic axes
|
|
258
|
-
set_xlim( min_x * exp(-dx), max_x * exp(dx) )
|
|
259
|
-
|
|
260
|
-
Parameters
|
|
261
|
-
----------
|
|
262
|
-
ax :
|
|
263
|
-
matplotlib plot
|
|
264
|
-
x, y: bool
|
|
265
|
-
Whether to apply x and y limits.
|
|
266
|
-
min_dx, min_dy:
|
|
267
|
-
Minimum distance
|
|
268
|
-
xrspace, yspace:
|
|
269
|
-
How much of the distance to add to left and right.
|
|
270
|
-
The actual distance added to max_x is dx:=max(min_dx,max_x-min_x)*xrspace
|
|
271
|
-
min_set_x, max_set_x, min_set_y, max_set_y:
|
|
272
|
-
If not None, set the respective min/max accordingly.
|
|
273
|
-
min_x_at_least, max_x_at_most, min_y_at_least, max_y_at_most:
|
|
274
|
-
If not None, bound the respecitve min/max accordingly.
|
|
275
|
-
"""
|
|
276
|
-
if x: self.set_xlim(ax, min_dx=min_dx, xrspace=xrspace, min_set_x=min_set_x, max_set_x=max_set_x, min_x_at_least=min_x_at_least, max_x_at_most=max_x_at_most)
|
|
277
|
-
if y: self.set_ylim(ax, min_dy=min_dy, yrspace=yrspace, min_set_y=min_set_y, max_set_y=max_set_y, min_y_at_least=min_y_at_least, max_y_at_most=max_y_at_most)
|
|
278
|
-
return self
|
|
26
|
+
from .deferred import Deferred
|
|
27
|
+
from .util import verify, warn
|
|
28
|
+
from .dynaplotlimits import AutoLimits
|
|
279
29
|
|
|
280
30
|
class DynamicAx(Deferred):
|
|
281
31
|
"""
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Beta Version Do Not Use
|
|
3
|
+
-----------------------
|
|
4
|
+
"""
|
|
5
|
+
from matplotlib.gridspec import GridSpec#NOQA
|
|
6
|
+
import numpy as np
|
|
7
|
+
from .err import verify, warn
|
|
8
|
+
|
|
9
|
+
class AutoLimits( object ):
|
|
10
|
+
"""
|
|
11
|
+
Max/Min limit manger for dynamic figures.
|
|
12
|
+
|
|
13
|
+
limits = MinMaxLimit( 0.05, 0.95 )
|
|
14
|
+
ax.add_subplot( x,y ,.. )
|
|
15
|
+
limits.update(x, y)
|
|
16
|
+
ax.add_subplot( x,z,.. )
|
|
17
|
+
limits.update(x, z)
|
|
18
|
+
limits.set_lims(ax)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, low_quantile, high_quantile, min_length : int = 10, lookback : int = None ):
|
|
22
|
+
"""
|
|
23
|
+
Initialize MinMaxLimit.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
low_quantile : float
|
|
28
|
+
Lower quantile to use for computing a 'min' y value. Set to 0 to use 'min'.
|
|
29
|
+
high_quantile : float
|
|
30
|
+
Higher quantile to use for computing a 'min' y value. Set to 1 to use 'max'.
|
|
31
|
+
min_length : int
|
|
32
|
+
Minimum length data must have to use quantile(). If less data is presented,
|
|
33
|
+
use min/max, respectively.
|
|
34
|
+
lookback : int
|
|
35
|
+
How many steps to lookback for any calculation. None to use all steps
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
verify( low_quantile >=0., "'low_quantile' must not be negative", exception=ValueError )
|
|
39
|
+
verify( high_quantile <=1., "'high_quantile' must not exceed 1", exception=ValueError )
|
|
40
|
+
verify( low_quantile<=high_quantile, "'low_quantile' not exceed 'high_quantile'", exception=ValueError )
|
|
41
|
+
self.lo_q = low_quantile
|
|
42
|
+
self.hi_q = high_quantile
|
|
43
|
+
self.min_length = int(min_length)
|
|
44
|
+
self.lookback = int(lookback) if not lookback is None else None
|
|
45
|
+
self.max_y = None
|
|
46
|
+
self.min_y = None
|
|
47
|
+
self.min_x = None
|
|
48
|
+
self.max_x = None
|
|
49
|
+
|
|
50
|
+
def update(self, *args, axis=None ):
|
|
51
|
+
"""
|
|
52
|
+
Add a data set to the min/max calc
|
|
53
|
+
|
|
54
|
+
If the x axis is ordinal first dimension of 'y':
|
|
55
|
+
update(y, axis=axis )
|
|
56
|
+
In this case x = np.linspace(1,y.shape[0],y.shape[0])
|
|
57
|
+
|
|
58
|
+
Specifcy x axis
|
|
59
|
+
update(x, y, axis=axis )
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
*args:
|
|
64
|
+
Either y or x,y
|
|
65
|
+
axis:
|
|
66
|
+
along which axis to compute min/max/quantiles
|
|
67
|
+
"""
|
|
68
|
+
assert len(args) in [1,2], ("'args' must be 1 or 2", len(args))
|
|
69
|
+
|
|
70
|
+
y = args[-1]
|
|
71
|
+
x = args[0] if len(args) > 1 else None
|
|
72
|
+
|
|
73
|
+
if len(y) == 0:
|
|
74
|
+
return
|
|
75
|
+
if axis is None:
|
|
76
|
+
axis = None if len(y.shape) <= 1 else tuple(list(y.shape)[1])
|
|
77
|
+
|
|
78
|
+
y_len = y.shape[0]
|
|
79
|
+
if not self.lookback is None:
|
|
80
|
+
y = y[-self.lookback:,...]
|
|
81
|
+
x = x[-self.lookback:,...] if not x is None else None
|
|
82
|
+
|
|
83
|
+
min_y = np.min( np.quantile( y, self.lo_q, axis=axis ) ) if self.lo_q > 0. and len(y) > self.min_length else np.min( y )
|
|
84
|
+
max_y = np.max( np.quantile( y, self.hi_q, axis=axis ) ) if self.hi_q < 1. and len(y) > self.min_length else np.max( y )
|
|
85
|
+
assert min_y <= max_y, ("Internal error", min_y, max_y, y)
|
|
86
|
+
self.min_y = min_y if self.min_y is None else min( self.min_y, min_y )
|
|
87
|
+
self.max_y = max_y if self.max_y is None else max( self.max_y, max_y )
|
|
88
|
+
|
|
89
|
+
if x is None:
|
|
90
|
+
self.min_x = 1
|
|
91
|
+
self.max_x = y_len if self.max_x is None else max( y_len, self.max_x )
|
|
92
|
+
else:
|
|
93
|
+
min_ = np.min( x )
|
|
94
|
+
max_ = np.max( x )
|
|
95
|
+
self.min_x = min_ if self.max_x is None else min( self.min_x, min_ )
|
|
96
|
+
self.max_x = max_ if self.max_x is None else max( self.max_x, max_ )
|
|
97
|
+
|
|
98
|
+
return self
|
|
99
|
+
|
|
100
|
+
def set( self, *, min_x = None, max_x = None,
|
|
101
|
+
min_y = None, max_y = None ) -> type:
|
|
102
|
+
"""
|
|
103
|
+
Overwrite any of the extrema.
|
|
104
|
+
Imposing an extrema also sets the other side if this would violate the requrest eg if min_x is set the function also floors self.max_x at min_x
|
|
105
|
+
Returns 'self.'
|
|
106
|
+
"""
|
|
107
|
+
verify( min_x is None or max_x is None or min_x <= max_x, "'min_x' and 'max_'x are in wrong order", min_x, max_x, exception=ValueError )
|
|
108
|
+
if not min_x is None:
|
|
109
|
+
self.min_x = min_x
|
|
110
|
+
self.max_x = min( self.max_x, min_x )
|
|
111
|
+
if not max_x is None:
|
|
112
|
+
self.min_x = max( self.min_x, max_x )
|
|
113
|
+
self.max_x = max_x
|
|
114
|
+
|
|
115
|
+
verify( min_y is None or max_y is None or min_y <= max_y, "'min_y' and 'max_'x are in wrong order", min_y, max_y, exception=ValueError )
|
|
116
|
+
if not min_y is None:
|
|
117
|
+
self.min_y = min_y
|
|
118
|
+
self.max_y = min( self.max_y, min_y )
|
|
119
|
+
if not max_y is None:
|
|
120
|
+
self.min_y = max( self.min_y, max_y )
|
|
121
|
+
self.max_y = max_y
|
|
122
|
+
return self
|
|
123
|
+
|
|
124
|
+
def bound( self, *, min_x_at_least = None, max_x_at_most = None, # <= boundary limits
|
|
125
|
+
min_y_at_least = None, max_y_at_most = None,
|
|
126
|
+
):
|
|
127
|
+
"""
|
|
128
|
+
Bound extrema
|
|
129
|
+
"""
|
|
130
|
+
verify( min_x_at_least is None or max_x_at_most is None or min_x_at_least <= max_x_at_most, "'min_x_at_least' and 'max_x_at_most'x are in wrong order", min_x_at_least, max_x_at_most, exception=ValueError )
|
|
131
|
+
if not min_x_at_least is None:
|
|
132
|
+
self.min_x = max( self.min_x, min_x_at_least )
|
|
133
|
+
self.max_x = max( self.max_x, min_x_at_least )
|
|
134
|
+
if not max_x_at_most is None:
|
|
135
|
+
self.min_x = min( self.min_x, max_x_at_most )
|
|
136
|
+
self.max_x = min( self.max_x, max_x_at_most )
|
|
137
|
+
|
|
138
|
+
verify( min_y_at_least is None or max_y_at_most is None or min_y_at_least <= max_y_at_most, "'min_y_at_least' and 'max_y_at_most'x are in wrong order", min_y_at_least, max_y_at_most, exception=ValueError )
|
|
139
|
+
if not min_y_at_least is None:
|
|
140
|
+
self.min_y = max( self.min_y, min_y_at_least )
|
|
141
|
+
self.max_y = max( self.max_y, min_y_at_least )
|
|
142
|
+
if not max_y_at_most is None:
|
|
143
|
+
self.min_y = min( self.min_y, max_y_at_most )
|
|
144
|
+
self.max_y = min( self.max_y, max_y_at_most )
|
|
145
|
+
return self
|
|
146
|
+
|
|
147
|
+
def set_a_lim( self, ax,*, is_x,
|
|
148
|
+
min_d,
|
|
149
|
+
rspace,
|
|
150
|
+
min_set = None,
|
|
151
|
+
max_set = None,
|
|
152
|
+
min_at_least = None,
|
|
153
|
+
max_at_most = None ):
|
|
154
|
+
""" Utility function """
|
|
155
|
+
min_ = self.min_x if is_x else self.min_y
|
|
156
|
+
max_ = self.max_x if is_x else self.max_y
|
|
157
|
+
ax_scale = (ax.get_xaxis() if is_x else ax.get_yaxis()).get_scale()
|
|
158
|
+
label = "x" if is_x else "y"
|
|
159
|
+
f = ax.set_xlim if is_x else ax.set_ylim
|
|
160
|
+
|
|
161
|
+
if min_ is None or max_ is None:
|
|
162
|
+
warn( "No data recevied yet; ignoring call" )
|
|
163
|
+
return
|
|
164
|
+
assert min_ <= max_, ("Internal error (1): min and max are not in order", label, min_, max_)
|
|
165
|
+
|
|
166
|
+
verify( min_set is None or max_set is None or min_set <= max_set, lambda : f"'min_set_{label}' exceeds 'max_set_{label}': found {min_set:.4g} and {max_set:.4g}, respectively", exception=RuntimeError )
|
|
167
|
+
verify( min_at_least is None or max_at_most is None or min_at_least <= max_at_most, lambda : f"'min_at_least_{label}' exceeds 'max_at_most_{label}': found {min_at_least:.4g} and {max_at_most:.4g}, respectively", exception=RuntimeError )
|
|
168
|
+
|
|
169
|
+
if not min_set is None:
|
|
170
|
+
min_ = min_set
|
|
171
|
+
max_ = max(min_set, max_)
|
|
172
|
+
if not max_set is None:
|
|
173
|
+
min_ = min(min_, max_set)
|
|
174
|
+
max_ = max_set
|
|
175
|
+
if not min_at_least is None:
|
|
176
|
+
min_ = max( min_, min_at_least )
|
|
177
|
+
max_ = max( max_, min_at_least )
|
|
178
|
+
if not max_at_most is None:
|
|
179
|
+
min_ = min( min_, max_at_most )
|
|
180
|
+
max_ = min( max_, max_at_most )
|
|
181
|
+
|
|
182
|
+
assert min_ <= max_, ("Internal error (2): min and max are not in order", label, min_, max_)
|
|
183
|
+
|
|
184
|
+
if isinstance( max_, int ):
|
|
185
|
+
verify( ax_scale == "linear", lambda : f"Only 'linear' {label} axis supported for integer based {label} coordinates; found '{ax_scale}'", exception=AttributeError )
|
|
186
|
+
max_ = max(max_, min_+1)
|
|
187
|
+
f( min_, max_ )
|
|
188
|
+
else:
|
|
189
|
+
d = max( max_-min_, min_d ) * rspace
|
|
190
|
+
if ax_scale == "linear":
|
|
191
|
+
f( min_ - d, max_ + d )
|
|
192
|
+
else:
|
|
193
|
+
verify( ax_scale == "log", lambda : f"Only 'linear' and 'log' {label} axis scales are supported; found '{ax_scale}'", exception=AttributeError )
|
|
194
|
+
verify( min_ > 0., lambda : f"Minimum for 'log' {label} axis must be positive; found {min_:.4g}", exception=ValueError )
|
|
195
|
+
rdx = np.exp( d )
|
|
196
|
+
f( min_ / rdx, max_ * rdx )
|
|
197
|
+
return self
|
|
198
|
+
|
|
199
|
+
def set_ylim(self, ax, *, min_dy : float = 1E-4, yrspace : float = 0.001, min_set_y = None, max_set_y = None, min_y_at_least = None, max_y_at_most = None ):
|
|
200
|
+
"""
|
|
201
|
+
Set x limits for 'ax'. See set_lims()
|
|
202
|
+
"""
|
|
203
|
+
return self.set_a_lim( ax, is_x=False, min_d=min_dy, rspace=yrspace, min_set=min_set_y, max_set=max_set_y, min_at_least=min_y_at_least, max_at_most=max_y_at_most )
|
|
204
|
+
|
|
205
|
+
def set_xlim(self, ax, *, min_dx : float = 1E-4, xrspace : float = 0.001, min_set_x = None, max_set_x = None, min_x_at_least = None, max_x_at_most = None ):
|
|
206
|
+
"""
|
|
207
|
+
Set x limits for 'ax'. See set_lims()
|
|
208
|
+
"""
|
|
209
|
+
return self.set_a_lim( ax, is_x=True, min_d=min_dx, rspace=xrspace, min_set=min_set_x, max_set=max_set_x, min_at_least=min_x_at_least, max_at_most=max_x_at_most )
|
|
210
|
+
|
|
211
|
+
def set_lims( self, ax, *, x : bool = True, y : bool = True,
|
|
212
|
+
min_dx : float = 1E-4, min_dy = 1E-4, xrspace = 0.001, yrspace = 0.001,
|
|
213
|
+
min_set_x = None, max_set_x = None, min_x_at_least = None, max_x_at_most = None,
|
|
214
|
+
min_set_y = None, max_set_y = None, min_y_at_least = None, max_y_at_most = None):
|
|
215
|
+
"""
|
|
216
|
+
Set x and/or y limits for 'ax'.
|
|
217
|
+
|
|
218
|
+
For example for the x axis: let
|
|
219
|
+
dx := max( max_x - min_x, min_dx )*xrspace
|
|
220
|
+
|
|
221
|
+
For linear axes:
|
|
222
|
+
set_xlim( min_x - dy, max_x + dx )
|
|
223
|
+
|
|
224
|
+
For logarithmic axes
|
|
225
|
+
set_xlim( min_x * exp(-dx), max_x * exp(dx) )
|
|
226
|
+
|
|
227
|
+
Parameters
|
|
228
|
+
----------
|
|
229
|
+
ax :
|
|
230
|
+
matplotlib plot
|
|
231
|
+
x, y: bool
|
|
232
|
+
Whether to apply x and y limits.
|
|
233
|
+
min_dx, min_dy:
|
|
234
|
+
Minimum distance
|
|
235
|
+
xrspace, yspace:
|
|
236
|
+
How much of the distance to add to left and right.
|
|
237
|
+
The actual distance added to max_x is dx:=max(min_dx,max_x-min_x)*xrspace
|
|
238
|
+
min_set_x, max_set_x, min_set_y, max_set_y:
|
|
239
|
+
If not None, set the respective min/max accordingly.
|
|
240
|
+
min_x_at_least, max_x_at_most, min_y_at_least, max_y_at_most:
|
|
241
|
+
If not None, bound the respecitve min/max accordingly.
|
|
242
|
+
"""
|
|
243
|
+
if x: self.set_xlim(ax, min_dx=min_dx, xrspace=xrspace, min_set_x=min_set_x, max_set_x=max_set_x, min_x_at_least=min_x_at_least, max_x_at_most=max_x_at_most)
|
|
244
|
+
if y: self.set_ylim(ax, min_dy=min_dy, yrspace=yrspace, min_set_y=min_set_y, max_set_y=max_set_y, min_y_at_least=min_y_at_least, max_y_at_most=max_y_at_most)
|
|
245
|
+
return self
|
cdxcore/util.py
CHANGED
|
@@ -935,13 +935,13 @@ class TrackTiming(object):
|
|
|
935
935
|
return self._tracked
|
|
936
936
|
|
|
937
937
|
def summary(self, fmat : str = "%(text)s: %(fmt_seconds)s", jn_fmt : str = ", " ) -> str:
|
|
938
|
-
"""
|
|
938
|
+
r"""
|
|
939
939
|
Generate summary string by applying some formatting
|
|
940
940
|
|
|
941
941
|
Parameters
|
|
942
942
|
----------
|
|
943
943
|
fmat : str, optional
|
|
944
|
-
Format string using ``%()``. Arguments are
|
|
944
|
+
Format string using ``%()``. Arguments are ``text``, ``seconds`` (as int) and ``fmt_seconds`` (a string).
|
|
945
945
|
|
|
946
946
|
Default is ``"%(text)s: %(fmt_seconds)s"``.
|
|
947
947
|
|
|
@@ -997,7 +997,7 @@ class Timer(object):
|
|
|
997
997
|
|
|
998
998
|
def interval_test( self, interval : float ) -> bool:
|
|
999
999
|
r"""
|
|
1000
|
-
Tests if
|
|
1000
|
+
Tests if ``interval`` seconds have passed.
|
|
1001
1001
|
If yes, reset timer and return True. Otherwise return False.
|
|
1002
1002
|
|
|
1003
1003
|
Usage::
|
|
@@ -1006,8 +1006,8 @@ class Timer(object):
|
|
|
1006
1006
|
tme = Timer()
|
|
1007
1007
|
for i in range(n):
|
|
1008
1008
|
if tme.test_dt_seconds(2.):
|
|
1009
|
-
print(f"
|
|
1010
|
-
print("
|
|
1009
|
+
print(f"\\r{i+1}/{n} done. Time taken so far {tme}.", end='', flush=True)
|
|
1010
|
+
print("\\rDone. This took {tme}.")
|
|
1011
1011
|
|
|
1012
1012
|
"""
|
|
1013
1013
|
if interval is None:
|
cdxcore/version.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
r"""
|
|
2
2
|
Overview
|
|
3
3
|
--------
|
|
4
4
|
|
|
@@ -117,12 +117,12 @@ Decorated Function Information
|
|
|
117
117
|
A decorated function or class has a member ``version`` of type :class:`cdxcore.version.Version` which has the following
|
|
118
118
|
key properties:
|
|
119
119
|
|
|
120
|
-
* :attr:`cdxcore.version.Version.input`: the input version as defined with :dec:`cdxcore.version.version
|
|
120
|
+
* :attr:`cdxcore.version.Version.input`: the input version as defined with :dec:`cdxcore.version.version`.
|
|
121
121
|
* :attr:`cdxcore.version.Version.full`: a fully qualified version with all dependent functions and classes in human readable form.
|
|
122
122
|
* :attr:`cdxcore.version.Version.unique_id48`,
|
|
123
123
|
:attr:`cdxcore.version.Version.unique_id64`:
|
|
124
124
|
unique hashes of :attr:`cdxcore.version.Version.full` of 48 or 64 characters,
|
|
125
|
-
respectively. You can use the function :meth:`cdxcore.version.Version.unique_id
|
|
125
|
+
respectively. You can use the function :meth:`cdxcore.version.Version.unique_id`
|
|
126
126
|
to compute hash IDs of any length.
|
|
127
127
|
* :attr:`cdxcore.version.Version.dependencies`: a hierarchical list of dependencies for systematic inspection.
|
|
128
128
|
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
cdxcore/__init__.py,sha256=
|
|
1
|
+
cdxcore/__init__.py,sha256=DDe92gvSbMoVPmYZeQq5stY46fOBgfwbVmoWCwe1P3M,127
|
|
2
2
|
cdxcore/config.py,sha256=YnIEJVFtMZ5EHlwzaB2JsSkCPhWPvEw9QSpe6mof_V4,98472
|
|
3
|
-
cdxcore/crman.py,sha256=
|
|
4
|
-
cdxcore/deferred.py,sha256=
|
|
5
|
-
cdxcore/dynaplot.py,sha256=
|
|
3
|
+
cdxcore/crman.py,sha256=D2KE_T5nHi0PdLRiNARHPAy-nidr38BD2dRpj0XHvXM,5760
|
|
4
|
+
cdxcore/deferred.py,sha256=zrMGN9FfDi-0ZJ9SdgNB4C2CeUvjFFoWBSQskFubGlc,40486
|
|
5
|
+
cdxcore/dynaplot.py,sha256=IaAhFPPhs_ag3ptA16ZwY0Z8BX-ogv2WEr--czHxYtI,36578
|
|
6
|
+
cdxcore/dynaplotlimits.py,sha256=YEPUELCbqjvfLtH45VzcXmfKH9_jdGGraM_R2I_KXDU,11530
|
|
6
7
|
cdxcore/err.py,sha256=BwmhilSxofBjN_NSrekCHn8_Oz9U_XbbfTm5qFRUl90,14645
|
|
7
8
|
cdxcore/jcpool.py,sha256=kurdafk6lerCkv52Wjh9UN7EFMP8Xp07iqB2adE5bfY,27302
|
|
8
9
|
cdxcore/pretty.py,sha256=iUpgUCwmI8yb5O-WZFJEk3QvNYcj_GIFHUgZ5lK8F2I,17082
|
|
9
10
|
cdxcore/pretty.py_bak.py,sha256=JgWr5044HzCNGG0wKSAWlWiPRs7-bNzkwiKH0T3n0to,28658
|
|
10
11
|
cdxcore/subdir.py,sha256=NScdtAG-Wrt0D7_FcpO62qzII4bS9ABXFerkILPg4uE,173864
|
|
11
12
|
cdxcore/uniquehash.py,sha256=g-D8pqPIppSdRq5QfdE5aP3paZ-NkXWHfnn-uNB7fmg,50648
|
|
12
|
-
cdxcore/util.py,sha256=
|
|
13
|
+
cdxcore/util.py,sha256=o4J3IY3q2N87ZaUoljAhZroo7co0P2BiGb6JANKeJX4,34201
|
|
13
14
|
cdxcore/verbose.py,sha256=66n9v2TduNWlochcV3mixSqyQzznO_H0LPrDgr9_dEo,30240
|
|
14
|
-
cdxcore/version.py,sha256=
|
|
15
|
-
cdxcore-0.1.
|
|
16
|
-
docs/source/conf.py,sha256=
|
|
15
|
+
cdxcore/version.py,sha256=bEAYXKlDuEVB9mazfaGRldVlpOWobKXZfkT8HrQSDZ4,27176
|
|
16
|
+
cdxcore-0.1.15.dist-info/licenses/LICENSE,sha256=M-cisgK9kb1bqVRJ7vrCxHcMQQfDxdY3c2YFJJWfNQg,1090
|
|
17
|
+
docs/source/conf.py,sha256=uYnpLfkcoaIB4IgrneDIfGwwK6_9T6KTS2k6lI-s4Ww,4038
|
|
17
18
|
tests/test_config.py,sha256=N86mH3y7k3LXEmU8uPLfrmRMZ-80VhlD35nBbpLmebg,15617
|
|
18
19
|
tests/test_crman.py,sha256=YNNEAIcKvqfy9KifV1p1qzpphHIANrhjjPbccJFmzqk,1378
|
|
19
|
-
tests/test_deferred.py,sha256=
|
|
20
|
+
tests/test_deferred.py,sha256=I0VNkAzlivefezT8Cgspt_SYb8yfqipJvtQXrNHS0Xs,7930
|
|
20
21
|
tests/test_err.py,sha256=4Pc7x2I0A_LBuiCMvstKNzN1JAcSPmm78dwLwp-N7s0,3146
|
|
21
22
|
tests/test_jcpool.py,sha256=bcGC3UcJ7SOHVgzZ-cooEJgncLWmhutBfqH7P5qB-iw,7901
|
|
22
23
|
tests/test_pretty.py,sha256=pVwTBjm3XqwEf2jq5GdZvT4cDSTGqiQFBMLqmGJYuB0,11644
|
|
@@ -25,13 +26,14 @@ tests/test_uniquehash.py,sha256=n6ZCkdBw-iRsyzeAEmrnLK0hJLGH6l_Dtt_KIkSa6KA,2463
|
|
|
25
26
|
tests/test_util.py,sha256=MXQMOmGjlBWTEwyW3JBTvZzlpMj5kDzThyhM2JwPZy8,23776
|
|
26
27
|
tests/test_verbose.py,sha256=zXheIqAVOnwML2zsCjLugjYzB_KNzU_S4Xu2CSb4o10,4723
|
|
27
28
|
tests/test_version.py,sha256=m_RODPDFlXTC1jAIczm3t1v6tXzqczDiUFFJtGvRG98,4381
|
|
29
|
+
tmp/deferred-hierarchical.py,sha256=JXzvQa3wiM3S685vdTri2uDBS1jFo7KIljxSUFSVEF4,30714
|
|
28
30
|
tmp/filelock.py,sha256=HqnHZhSCESaOA3ClrdWPW_GZpyo7c3VRSEofAV-khKM,18137
|
|
29
31
|
tmp/np.py,sha256=2MynhiaTfmx984Gz7TwfZH3t7GCmCAQiyeWzDDCL6_k,47686
|
|
30
32
|
tmp/npio.py,sha256=4Kwp5H4MgKHkOEhu4UJ5CcwpM7Pm8UFkaoL5FvOEFRI,10310
|
|
31
33
|
tmp/sharedarray.py,sha256=JuHuSlxA0evD0a-bEZgTFrfdlVPMgzfQNgfSjr1212w,11484
|
|
32
34
|
up/git_message.py,sha256=EfSH7Pit3ZoCiRqSMwRCUN_QyuwreU4LTIyGSutBlm4,123
|
|
33
35
|
up/pip_modify_setup.py,sha256=Esaml4yA9tFsqxLhk5bWSwvKCURONjQqfyChgFV2TSY,1584
|
|
34
|
-
cdxcore-0.1.
|
|
35
|
-
cdxcore-0.1.
|
|
36
|
-
cdxcore-0.1.
|
|
37
|
-
cdxcore-0.1.
|
|
36
|
+
cdxcore-0.1.15.dist-info/METADATA,sha256=PoBrfdw__2k-E7vh2E61vsP2XMOARpT9nkUYv0wy-7g,754
|
|
37
|
+
cdxcore-0.1.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
38
|
+
cdxcore-0.1.15.dist-info/top_level.txt,sha256=phNSwCyJFe7UP2YMoi8o6ykhotatlIbJHjTp9EHM51k,26
|
|
39
|
+
cdxcore-0.1.15.dist-info/RECORD,,
|