permit NaN in embedding coordinates (#1631)

* permit NaN in embedding coordinates

* lint
This commit is contained in:
Bruce Martin
2020-07-16 11:43:56 -07:00
committed by GitHub
parent 3c6d90a4db
commit 2f700b377f
3 changed files with 15 additions and 8 deletions

View File

@@ -391,13 +391,13 @@ def create_emb(e_name, emb):
def is_valid_embedding(adata, name, arr):
""" return True if this layout data is a valid array for front-end presentation:
* ndarray, with shape (n_obs, >= 2), dtype float/int/uint
* contains only finite values
* follows ScanPy embedding naming conventions
* with all values finite or NaN (no +Inf or -Inf)
"""
is_valid = type(name) == str and name.startswith("X_") and len(name) > 2
is_valid = is_valid and type(arr) == np.ndarray and arr.dtype.kind in "fiu"
is_valid = is_valid and arr.shape[0] == adata.n_obs and arr.shape[1] >= 2
is_valid = is_valid and np.all(np.isfinite(arr))
is_valid = is_valid and not np.any(np.isinf(arr)) and not np.all(np.isnan(arr))
return is_valid

View File

@@ -197,12 +197,13 @@ class AnndataAdaptor(DataAdaptor):
def _is_valid_layout(self, arr):
""" return True if this layout data is a valid array for front-end presentation:
* ndarray, with shape (n_obs, >= 2), dtype float/int/uint
* contains only finite values
* ndarray, dtype float/int/uint
* with shape (n_obs, >= 2)
* with all values finite or NaN (no +Inf or -Inf)
"""
is_valid = type(arr) == np.ndarray and arr.dtype.kind in "fiu"
is_valid = is_valid and arr.shape[0] == self.data.n_obs and arr.shape[1] >= 2
is_valid = is_valid and np.all(np.isfinite(arr))
is_valid = is_valid and not np.any(np.isinf(arr)) and not np.all(np.isnan(arr))
return is_valid
def _validate_data_types(self):
@@ -291,7 +292,7 @@ class AnndataAdaptor(DataAdaptor):
raise PrepareError("No valid layout data.")
# cap layouts to MAX_LAYOUTS
return layouts[0:MAX_LAYOUTS]
return valid_layouts[0:MAX_LAYOUTS]
def get_embedding_array(self, ename, dims=2):
full_embedding = self.data.obsm[f"X_{ename}"]

View File

@@ -328,8 +328,14 @@ class DataAdaptor(metaclass=ABCMeta):
"""
# scale isotropically
min = embedding.min(axis=0)
max = embedding.max(axis=0)
try:
min = np.nanmin(embedding, axis=0)
max = np.nanmax(embedding, axis=0)
except RuntimeError:
# indicates entire array was NaN, which should propagate
min = np.NaN
max = np.NaN
scale = np.amax(max - min)
normalized_layout = (embedding - min) / scale