Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""Test making a meshgrid from a dataset"""
a = np.linspace(0, 1, 11)
b = np.arange(5)
aa, bb = np.meshgrid(a, b, indexing='ij')
zz = aa * bb
dd = DataDict(
a=dict(values=aa.reshape(-1)),
b=dict(values=bb.reshape(-1)),
z=dict(values=zz.reshape(-1), axes=['a', 'b']),
__info__='some info',
)
dd2 = datadict_to_meshgrid(dd, target_shape=(11, 5))
assert DataDictBase.same_structure(dd, dd2)
assert num.arrays_equal(dd2.data_vals('a'), aa)
assert num.arrays_equal(dd2.data_vals('z'), zz)
dd2 = datadict_to_meshgrid(dd, target_shape=None)
assert DataDictBase.same_structure(dd, dd2)
assert num.arrays_equal(dd2.data_vals('a'), aa)
assert num.arrays_equal(dd2.data_vals('z'), zz)
# test the case where inner/outer
aa, bb = np.meshgrid(a, b, indexing='xy')
zz = aa * bb
dd = DataDict(
a=dict(values=aa.reshape(-1)),
b=dict(values=bb.reshape(-1)),
z=dict(values=zz.reshape(-1), axes=['a', 'b']),
dd = DataDict(
a=dict(values=aa.reshape(-1)),
b=dict(values=bb.reshape(-1)),
z=dict(values=zz.reshape(-1), axes=['a', 'b']),
__info__='some info',
)
dd2 = datadict_to_meshgrid(dd, target_shape=(5, 11),
inner_axis_order=['b', 'a'])
assert DataDictBase.same_structure(dd, dd2)
assert num.arrays_equal(dd2.data_vals('a'), np.transpose(aa, (1, 0)))
assert num.arrays_equal(dd2.data_vals('z'), np.transpose(zz, (1, 0)))
dd2 = datadict_to_meshgrid(dd, target_shape=None)
assert DataDictBase.same_structure(dd, dd2)
assert num.arrays_equal(dd2.data_vals('a'), np.transpose(aa, (1, 0)))
assert num.arrays_equal(dd2.data_vals('z'), np.transpose(zz, (1, 0)))
elif na not in self.axes():
msg += " * '{}' has axis '{}', but no independent " \
"with name '{}' registered.\n".format(
n, na, na)
else:
v['axes'] = []
if 'unit' not in v:
v['unit'] = ''
vals = v.get('values', [])
if type(vals) not in [np.ndarray, np.ma.core.MaskedArray]:
vals = np.array(vals)
v['values'] = vals
if '__shape__' in v and not self.__class__ == DataDictBase:
v['__shape__'] = np.array(v['values']).shape
if msg != '\n':
raise ValueError(msg)
return True
def determinePlotDataType(data: DataDictBase) -> PlotDataType:
"""
Analyze input data and determine most likely :class:`PlotDataType`.
Analysis is simply based on number of dependents and data type.
:param data: data to analyze.
"""
# TODO:
# there's probably ways to be more liberal about what can be plotted.
# like i can always make a 1d scatter...
# a few things will result in unplottable data:
# * wrong data format
if not isinstance(data, DataDictBase):
return PlotDataType.unknown
# * incompatible independents
if not data.axes_are_compatible():
return PlotDataType.unknown
# * too few or too many independents
if len(data.axes()) < 1 or len(data.axes()) > 2:
return PlotDataType.unknown
# * no data to plot
if len(data.dependents()) == 0:
return PlotDataType.unknown
if isinstance(data, MeshgridDataDict):
if len(data.axes()) == 2:
def append(self, newdata):
"""
Append a datadict to this one by appending data values.
:param newdata: DataDict to append.
:raises: ``ValueError``, if the structures are incompatible.
"""
if not DataDictBase.same_structure(self, newdata):
raise ValueError('Incompatible data structures.')
newvals = {}
for k, v in newdata.data_items():
if isinstance(self[k]['values'], list) and isinstance(
v['values'], list):
newvals[k] = self[k]['values'] + v['values']
else:
newvals[k] = np.append(
self[k]['values'],
v['values'],
axis=0
)
# only actually
for k, v in newvals.items():
def process(self, dataIn: DataDictBase=None):
if dataIn is None:
return None
if isinstance(dataIn, DataDictBase):
dtype = type(dataIn)
daxes = dataIn.axes()
ddeps = dataIn.dependents()
dshapes = dataIn.shapes()
_axesChanged = False
_fieldsChanged = False
_typeChanged = False
_structChanged = False
_shapesChanged = False
if daxes != self.dataAxes:
_axesChanged = True
if daxes != self.dataAxes or ddeps != self.dataDependents:
_fieldsChanged = True
:param add_shape: Deprecated -- ignored.
:param include_meta: if `True`, include the meta information in
the returned dict, else clear it.
:param same_type: if `True`, return type will be the one of the
object this is called on. Else, DataDictBase.
:return: The DataDictBase containing the structure only.
"""
if add_shape:
warnings.warn("'add_shape' is deprecated and will be ignored",
DeprecationWarning)
add_shape = False
if self.validate():
s = DataDictBase()
# shapes = {}
for n, v in self.data_items():
v2 = v.copy()
v2.pop('values')
# if not add_shape and '__shape__' in v2:
# v2.pop('__shape__')
s[n] = v2
# if add_shape:
# shapes[n] = np.array(v['values']).shape
if include_meta:
for n, v in self.meta_items():
s.add_meta(n, v)
ret = None
rettype = None
for d in dicts:
if ret is None:
ret = d.copy()
rettype = type(d)
else:
# if we don't have a well defined number of records anymore,
# need to revert the type to DataDictBase
if hasattr(d, 'nrecords') and hasattr(ret, 'nrecords'):
if d.nrecords() != ret.nrecords():
rettype = DataDictBase
else:
rettype = DataDictBase
ret = rettype(**ret)
# First, parse the axes in the to-be-added ddict.
# if dimensions with same names are present already in the current
# return ddict and are not compatible with what's to be added,
# rename the incoming dimension.
ax_map = {}
for d_ax in d.axes():
if d_ax in ret.axes():
if num.arrays_equal(d.data_vals(d_ax), ret.data_vals(d_ax)):
ax_map[d_ax] = d_ax
else:
newax = _find_replacement_name(ret, d_ax)
ax_map[d_ax] = newax
self.setHeaderLabels(['Dimension', 'Role', 'Options', 'Info'])
self._dataStructure = None
self._dataShapes = None
self._dataType = None
self._currentRoles = {}
#: This is a flag to control whether we need to emit signals when
#: a role has changed. broadly speaking, this is only desired when
#: the change comes from the user interacting with the UI, otherwise
#: it might lead to undesired recursion.
self.emitRoleChangeSignal = True
self.choices = {}
self.availableChoices = OrderedDict({
DataDictBase: ['None', ],
DataDict: [],
MeshgridDataDict: [],
})
:return: copy of the dataset with invalid entries (nan/None) masked.
"""
ret = self.copy()
for d, _ in self.data_items():
arr = self.data_vals(d)
vals = np.ma.masked_where(num.is_invalid(arr), arr, copy=True)
try:
vals.fill_value = np.nan
except TypeError:
vals.fill_value = -9999
ret[d]['values'] = vals
return ret
class DataDict(DataDictBase):
"""
The most basic implementation of the DataDict class.
It only enforces that the number of `records` per data field must be
equal for all fields. This refers to the most outer dimension in case
of nested arrays.
The class further implements simple appending of datadicts through the
``DataDict.append`` method, as well as allowing addition of DataDict
instances.
"""
def __add__(self, newdata: 'DataDict') -> 'DataDict':
"""
Adding two datadicts by appending each data array.