internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: scverse/scanpy

Issue:
get.rank_genes_groups() key argument not used
`rank_genes_groups_df` takes    `key` as an argument and the docs says it is the  key differential expression groups were stored under. However, the function does not use that key and fetches DE results from the default 'rank_genes_groups' key.

line 55 under `rank_genes_groups_df() ` in scanpy/get.py
`d[k] = adata.uns["rank_genes_groups"][k][group]` should be changed to `d[k] = adata.uns[key][k][group]`


Discussion:

Resolving patch:
diff --git a/scanpy/get.py b/scanpy/get.py
--- a/scanpy/get.py
+++ b/scanpy/get.py
@@ -52,7 +52,7 @@ def rank_genes_groups_df(
     """
     d = pd.DataFrame()
     for k in ['scores', 'names', 'logfoldchanges', 'pvals', 'pvals_adj']:
-        d[k] = adata.uns["rank_genes_groups"][k][group]
+        d[k] = adata.uns[key][k][group]
     if pval_cutoff is not None:
         d = d[d["pvals_adj"] < pval_cutoff]
     if log2fc_min is not None:


Test patch:
diff --git a/scanpy/tests/test_get.py b/scanpy/tests/test_get.py
--- a/scanpy/tests/test_get.py
+++ b/scanpy/tests/test_get.py
@@ -83,3 +83,11 @@ def test_rank_genes_groups_df():
     assert sc.get.rank_genes_groups_df(adata, "a", log2fc_max=.1).shape[0] == 2
     assert sc.get.rank_genes_groups_df(adata, "a", log2fc_min=.1).shape[0] == 1
     assert sc.get.rank_genes_groups_df(adata, "a", pval_cutoff=.9).shape[0] == 1
+    del adata.uns["rank_genes_groups"]
+    sc.tl.rank_genes_groups(
+        adata, groupby="celltype", method="wilcoxon", key_added="different_key"
+    )
+    with pytest.raises(KeyError):
+        sc.get.rank_genes_groups_df(adata, "a")
+    dedf2 = sc.get.rank_genes_groups_df(adata, "a", key="different_key")
+    pd.testing.assert_frame_equal(dedf, dedf2)
Repository: scverse/scanpy

Issue:
`datasets.pbmc68k_reduced` isn't contained in the pypi package anymore
This still works in `1.4.4.post1`. It's very likely caused by changes to `setup.py`. I experienced similar problems before and fixed them via `package_data`. But this got removed. It's probably only a problem for the source-based installs.

https://github.com/theislab/scanpy/commit/881f0bef31cdfe0df7333641dc847a60894b5c41#diff-2eeaed663bd0d25b7e608891384b7298

```
>>> import scanpy
>>> scanpy.__version__
<Version('1.4.5.post2')>
>>> scanpy.datasets.pbmc68k_reduced()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/alexwolf/miniconda3/lib/python3.6/site-packages/scanpy/datasets/__init__.py", line 239, in pbmc68k_reduced
    return read(filename)
  File "/Users/alexwolf/miniconda3/lib/python3.6/site-packages/scanpy/readwrite.py", line 114, in read
    **kwargs,
  File "/Users/alexwolf/miniconda3/lib/python3.6/site-packages/scanpy/readwrite.py", line 524, in _read
    return read_h5ad(filename, backed=backed)
  File "/Users/alexwolf/miniconda3/lib/python3.6/site-packages/anndata/readwrite/read.py", line 447, in read_h5ad
    constructor_args = _read_args_from_h5ad(filename=filename, chunk_size=chunk_size)
  File "/Users/alexwolf/miniconda3/lib/python3.6/site-packages/anndata/readwrite/read.py", line 481, in _read_args_from_h5ad
    f = h5py.File(filename, 'r')
  File "/Users/alexwolf/miniconda3/lib/python3.6/site-packages/anndata/h5py/h5sparse.py", line 162, in __init__
    **kwds,
  File "/Users/alexwolf/miniconda3/lib/python3.6/site-packages/h5py/_hl/files.py", line 312, in __init__
    fid = make_fid(name, mode, userblock_size, fapl, swmr=swmr)
  File "/Users/alexwolf/miniconda3/lib/python3.6/site-packages/h5py/_hl/files.py", line 142, in make_fid
    fid = h5f.open(name, flags, fapl=fapl)
  File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
  File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
  File "h5py/h5f.pyx", line 78, in h5py.h5f.open
```


Discussion:
On the other hand, the tests are in the source distribution, including test data, blowing up scanpy’s size to 6MB

I usually put tests next to the package and don’t deliver them to users. We should probably start doing that.
Hmm, it’s in the source package and the wheel, but maybe it doesn’t get installed? Maybe `include_package_data=True` needs to be restored.

How did you install from the source package anyway? Pip always uses wheels if possible, right?

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -50,6 +50,7 @@
         ],
     ),
     packages=find_packages(),
+    include_package_data=True,
     entry_points=dict(console_scripts=['scanpy=scanpy.cli:console_main']),
     zip_safe=False,
     classifiers=[


Test patch:
Repository: scverse/scanpy

Issue:
MAGIC in external causes test failures if its not installed
@scottgigante @flying-sheep, on current master the tests fail for me with a MAGIC not installed error. External tests should have some mark to make sure they don't get run if the required package isn't installed.


Discussion:

Resolving patch:
diff --git a/scanpy/external/pp/_magic.py b/scanpy/external/pp/_magic.py
--- a/scanpy/external/pp/_magic.py
+++ b/scanpy/external/pp/_magic.py
@@ -6,12 +6,16 @@
 from anndata import AnnData
 from numpy.random.mtrand import RandomState
 from legacy_api_wrap import legacy_api
+from packaging import version
 
 from ... import logging as logg
 from ..._settings import settings
 from ..._compat import Literal
 
 
+MIN_VERSION = "2.0"
+
+
 @legacy_api('k', 'a')
 def magic(
     adata: AnnData,
@@ -135,12 +139,10 @@ def magic(
             'git+git://github.com/KrishnaswamyLab/MAGIC.git#subdirectory=python`'
         )
     else:
-        version = tuple([int(v) for v in __version__.split(".")[:2]])
-        min_version = (2, 0)
-        if not version >= min_version:
+        if not version.parse(__version__) >= version.parse(MIN_VERSION):
             raise ImportError(
                 'scanpy requires magic-impute >= '
-                f'v{min_version[0]}.{min_version[1]} (detected: v{__version__}). '
+                f'v{MIN_VERSION} (detected: v{__version__}). '
                 'Please update magic package via `pip install --user '
                 '--upgrade magic-impute`'
             )


Test patch:
diff --git a/scanpy/tests/external/test_magic.py b/scanpy/tests/external/test_magic.py
--- a/scanpy/tests/external/test_magic.py
+++ b/scanpy/tests/external/test_magic.py
@@ -4,6 +4,8 @@
 
 import scanpy as sc
 
+pytest.importorskip("magic", minversion=sc.external.pp._magic.MIN_VERSION)
+
 A_list = [
     [0, 0, 7, 0, 0],
     [8, 5, 0, 2, 0],
Repository: scverse/scanpy

Issue:
Single color on sc.pl.scatter plotts
It seems like the default color for scatterplots are gray. I think I read somewhere that it's the middle color for the gray color sale from matplotlib.

Is there a way to plot a scatterplot with a single color given as an argument to `sc.pl.scatter`?



Discussion:
Actually the gray is hardcoded:

https://github.com/theislab/scanpy/blob/b3dc34a57ccaa6ac9a4ac8718fe9f128c967e3dc/scanpy/plotting/_anndata.py#L303

But you can simply use a color-like string to specify your favourite color (Unless you happend to have an `.obs` column named `#fe57a1` or so :grin:):

https://github.com/theislab/scanpy/blob/b3dc34a57ccaa6ac9a4ac8718fe9f128c967e3dc/scanpy/plotting/_anndata.py#L384-L386
Documented in 5ab9def681264a95acd48aeda45b46ad0b86fee8
Thanks for the answer and for your suggestion @flying-sheep.

I can't make this work though. The color choice does not work while also using scatter plot to plot `x` and `y` values.
The suggested code only works when `basis is not None`. However using the plain basis function e.g. `sc.pl.umap` will fail earlier than this for inputting a color.

### In summary,

this will not work:
```
sc.pl.umap(adata, color=#fe57a1)
```
this will work
```
sc.pl.scatter(adata, basis='umap', color=#fe57a1)
```
this will not work (what I actually want to do)
```
sc.pl.scatter(adata, x='dpt_pseudotime', y='SOMEGENE', color=#fe57a1)
```
For the last command the code makes a check already before passing the color argument to the plotting function
https://github.com/theislab/scanpy/blob/5ab9def681264a95acd48aeda45b46ad0b86fee8/scanpy/plotting/_anndata.py#L121


EDITED so it links to the correct code line.



Simply adding the matplotlib `is_color_like` seems to do the trick
```
and (color is None or color in adata.obs.keys() or color in adata.var.index or is_color_like(color))):
```

@Xparx I had this issue as well. Your modification worked for me, thanks!

Resolving patch:
diff --git a/scanpy/plotting/_anndata.py b/scanpy/plotting/_anndata.py
--- a/scanpy/plotting/_anndata.py
+++ b/scanpy/plotting/_anndata.py
@@ -210,7 +210,14 @@ def _scatter_obs(
     if isinstance(components, str):
         components = components.split(',')
     components = np.array(components).astype(int) - 1
-    keys = ['grey'] if color is None else [color] if isinstance(color, str) else color
+    # color can be a obs column name or a matplotlib color specification
+    keys = (
+        ['grey']
+        if color is None
+        else [color]
+        if isinstance(color, str) or is_color_like(color)
+        else color
+    )
     if title is not None and isinstance(title, str):
         title = [title]
     highlights = adata.uns['highlights'] if 'highlights' in adata.uns else []


Test patch:
Repository: scverse/scanpy

Issue:
sc.datasets.ebi_expression_atlas errors
I wanted to use ` sc.datasets.ebi_expression_atlas` but  I get an error that seems to be related to code only valid in python 3.8. This error happens with python version `3.6.7`.

Code:
```python
adata = sc.datasets.ebi_expression_atlas("E-GEOD-98556")
```

<!-- Put your Error output in this code block (if applicable, else delete the block): -->
```pytb
/scanpy/scanpy/datasets/_ebi_expression_atlas.py in download_experiment(accession)
     41
     42     _download(
---> 43         download_url + "experiment-design", experiment_dir / "experimental_design.tsv",
     44     )
     45     _download(

/scanpy/scanpy/readwrite.py in _download(url, path)
    877         except Exception:
    878             # Make sure file doesn’t exist half-downloaded
--> 879             path.unlink(missing_ok=True)
    880             raise
    881

TypeError: unlink() got an unexpected keyword argument 'missing_ok'

...
```
`missing_ok` was added to python v. 3.8 (https://docs.python.org/3/library/pathlib.html#pathlib.Path.unlink)



Discussion:

Resolving patch:
diff --git a/scanpy/readwrite.py b/scanpy/readwrite.py
--- a/scanpy/readwrite.py
+++ b/scanpy/readwrite.py
@@ -876,7 +876,8 @@ def update_to(b=1, bsize=1, tsize=None):
             urlretrieve(url, str(path), reporthook=update_to)
         except Exception:
             # Make sure file doesn’t exist half-downloaded
-            path.unlink(missing_ok=True)
+            if path.is_file():
+                path.unlink()
             raise
 
 


Test patch:
diff --git a/scanpy/tests/test_datasets.py b/scanpy/tests/test_datasets.py
--- a/scanpy/tests/test_datasets.py
+++ b/scanpy/tests/test_datasets.py
@@ -70,3 +70,10 @@ def test_toggleswitch():
 
 def test_pbmc68k_reduced():
     sc.datasets.pbmc68k_reduced()
+
+
+def test_download_failure():
+    from urllib.error import HTTPError
+
+    with pytest.raises(HTTPError):
+        sc.datasets.ebi_expression_atlas("not_a_real_accession")
Repository: scverse/scanpy

Issue:
Bug in _download_visium_dataset()
<!-- Please give a clear and concise description of what the bug is: -->
After creating a fresh conda environment on Mac OS Mojave and starting to replicate the "Analysis and visualization of spatial transcriptomics data" tutorial, after running

```python
adata = sc.datasets.visium_sge()
```
I get 
<!-- Put your Error output in this code block (if applicable, else delete the block): -->
```pytb
FileNotFoundError: [Errno 2] No such file or directory: '/Users/lisa/data/V1_Breast_Cancer_Block_A_Section_1'
```
I figured it is because the intermediate folder "/data" is missing as well  - 

```python
sample_dir.mkdir(exist_ok=True)
```
in ```_download_visium_dataset()``` cannot create it, it would need the flag ```parents=True``` to do so (https://docs.python.org/3/library/pathlib.html#pathlib.Path.mkdir).


#### Versions:

scanpy==1.4.7.dev52+g590d4230 anndata==0.7.1 umap==0.4.1 numpy==1.18.1 scipy==1.4.1 pandas==1.0.3 scikit-learn==0.22.2.post1 statsmodels==0.11.1




Discussion:

Resolving patch:
diff --git a/scanpy/datasets/_datasets.py b/scanpy/datasets/_datasets.py
--- a/scanpy/datasets/_datasets.py
+++ b/scanpy/datasets/_datasets.py
@@ -313,7 +313,7 @@ def _download_visium_dataset(sample_id: str, base_dir: Optional[Path] = None):
     url_prefix = f'http://cf.10xgenomics.com/samples/spatial-exp/1.0.0/{sample_id}/'
 
     sample_dir = base_dir / sample_id
-    sample_dir.mkdir(exist_ok=True)
+    sample_dir.mkdir(exist_ok=True, parents=True)
 
     # Download spatial data
     tar_filename = f"{sample_id}_spatial.tar.gz"


Test patch:
Repository: scverse/scanpy

Issue:
Scanpy spatial bug in visualisation defaults
Looks like the default values for plotting Visium spots are way outsized.

Try this in your lymph node notebook:
```python
sc.pl.spatial(adata, img_key = "hires", cmap='magma',
              color=['total_counts', 'n_genes_by_counts'],
              gene_symbols='SYMBOL')
```
This is what I get:
...
![image](https://user-images.githubusercontent.com/22567383/83098134-acf2e600-a0a1-11ea-9248-c611f7330547.png)

#### Versions:
scanpy==1.5.1 anndata==0.7.1 umap==0.3.10 numpy==1.17.3 scipy==1.4.1 pandas==0.25.3 scikit-learn==0.22.1 statsmodels==0.10.2 python-igraph==0.7.1 louvain==0.6.1 leidenalg==0.7.0



Discussion:

Resolving patch:
diff --git a/scanpy/plotting/_tools/scatterplots.py b/scanpy/plotting/_tools/scatterplots.py
--- a/scanpy/plotting/_tools/scatterplots.py
+++ b/scanpy/plotting/_tools/scatterplots.py
@@ -778,7 +778,7 @@ def spatial(
             (k for k in ['hires', 'lowres'] if k in spatial_data['images']), None,
         )
 
-    if img_key is None and size is None:
+    if size is None:
         size = 1.0
 
     return embedding(


Test patch:
diff --git a/scanpy/tests/_images/master_spatial_visium_default.png b/scanpy/tests/_images/master_spatial_visium_default.png
new file mode 100644
Binary files /dev/null and b/scanpy/tests/_images/master_spatial_visium_default.png differ
diff --git a/scanpy/tests/test_plotting.py b/scanpy/tests/test_plotting.py
--- a/scanpy/tests/test_plotting.py
+++ b/scanpy/tests/test_plotting.py
@@ -943,6 +943,16 @@ def test_visium_circles(image_comparer):
     save_and_compare_images('master_spatial_visium')
 
 
+def test_visium_default(image_comparer):
+    save_and_compare_images = image_comparer(ROOT, FIGS, tol=15)
+    adata = sc.read_visium(HERE / '_data' / 'visium_data' / '1.0.0')
+    adata.obs = adata.obs.astype({'array_row': 'str'})
+
+    sc.pl.spatial(adata,)
+
+    save_and_compare_images('master_spatial_visium_default')
+
+
 def test_visium_empty_img_key(image_comparer):
     save_and_compare_images = image_comparer(ROOT, FIGS, tol=15)
     adata = sc.read_visium(HERE / '_data' / 'visium_data' / '1.0.0')
Repository: scverse/scanpy

Issue:
10x Genomics dataset loading feature
Is there any interest in writing a function to load any of the public datasets offered by 10x genomics? 


Discussion:

Resolving patch:
diff --git a/scanpy/readwrite.py b/scanpy/readwrite.py
--- a/scanpy/readwrite.py
+++ b/scanpy/readwrite.py
@@ -136,7 +136,10 @@ def read(
 
 
 def read_10x_h5(
-    filename: Union[str, Path], genome: Optional[str] = None, gex_only: bool = True,
+    filename: Union[str, Path],
+    genome: Optional[str] = None,
+    gex_only: bool = True,
+    backup_url: Optional[str] = None,
 ) -> AnnData:
     """\
     Read 10x-Genomics-formatted hdf5 file.
@@ -151,6 +154,8 @@ def read_10x_h5(
     gex_only
         Only keep 'Gene Expression' data and ignore other feature types,
         e.g. 'Antibody Capture', 'CRISPR Guide Capture', or 'Custom'
+    backup_url
+        Retrieve the file from an URL if not present on disk.
 
     Returns
     -------
@@ -169,6 +174,9 @@ def read_10x_h5(
         Feature types
     """
     start = logg.info(f'reading {filename}')
+    is_present = _check_datafile_present_and_download(filename, backup_url=backup_url,)
+    if not is_present:
+        logg.debug(f'... did not find original file {filename}')
     with tables.open_file(str(filename), 'r') as f:
         v3 = '/matrix' in f
     if v3:


Test patch:
Repository: scverse/scanpy

Issue:
Using list(map(lambda)) is suboptimal
As the title suggests, it can be suboptimal w.r.t computation time to use

```python
list(map(lambda x: ..., SOME_LIST))
```

In `readwrite.py` [here](https://github.com/theislab/scanpy/blob/f704f724529def21769ee6407f9b47b5c161564c/scanpy/readwrite.py#L190) for example, instead of chaining of the three functions, we can simply compare to a `pandas.Series`:

```python
adata = adata[:, adata.var['genome'] == f"{genome}"]
```

This improves readability and is slightly faster.

In a quick check I ran in Jupyter Lab, this approach is three times faster. The following code should run in Jupyter Lab as is:

```python
import random
import string

import numpy as np
import pandas as pd


from anndata import AnnData

letters = string.ascii_lowercase

adata = AnnData(pd.DataFrame(np.random.randn(1000, 30000)))
adata.var["genome"] = np.array([random.choice(letters) for _ in range(30000)]).reshape(-1, 1)

genome = 'g'
%timeit adata[:, list(map(lambda x: x == f"{genome}", adata.var['genome']))]

%timeit adata[:, adata.var['genome'] == f"{genome}"]
```




Discussion:

Resolving patch:
diff --git a/scanpy/readwrite.py b/scanpy/readwrite.py
--- a/scanpy/readwrite.py
+++ b/scanpy/readwrite.py
@@ -187,12 +187,9 @@ def read_10x_h5(
                     f"Could not find data corresponding to genome '{genome}' in '{filename}'. "
                     f'Available genomes are: {list(adata.var["genome"].unique())}.'
                 )
-            adata = adata[:, list(map(lambda x: x == str(genome), adata.var['genome']))]
+            adata = adata[:, adata.var['genome'] == genome]
         if gex_only:
-            adata = adata[
-                :,
-                list(map(lambda x: x == 'Gene Expression', adata.var['feature_types'])),
-            ]
+            adata = adata[:, adata.var['feature_types'] == 'Gene Expression']
         if adata.is_view:
             adata = adata.copy()
     else:


Test patch:
Repository: scverse/scanpy

Issue:
Docs for `scanpy.tl.rank_genes_groups` are displayed incorrectly
The docs for `scanpy.tl.rank_genes_groups` are displayed incorrectly [here](https://scanpy.readthedocs.io/en/stable/api/scanpy.tl.rank_genes_groups.html#scanpy.tl.rank_genes_groups). The problem is the empty line [here](https://github.com/theislab/scanpy/blob/f704f724529def21769ee6407f9b47b5c161564c/scanpy/tools/_rank_genes_groups.py#L518).


Discussion:

Resolving patch:
diff --git a/scanpy/tools/_rank_genes_groups.py b/scanpy/tools/_rank_genes_groups.py
--- a/scanpy/tools/_rank_genes_groups.py
+++ b/scanpy/tools/_rank_genes_groups.py
@@ -515,8 +515,7 @@ def rank_genes_groups(
     >>> import scanpy as sc
     >>> adata = sc.datasets.pbmc68k_reduced()
     >>> sc.tl.rank_genes_groups(adata, 'bulk_labels', method='wilcoxon')
-
-    # to visualize the results
+    >>> # to visualize the results
     >>> sc.pl.rank_genes_groups(adata)
     """
     if method is None:


Test patch:
Repository: scverse/scanpy

Issue:
Use `np.array` instead of `np.matrix`
## Description

Numpy does not recommend the usage of the matrix subclass. Since the introduction of the matmul operator `@` in python 3.5, the biggest advantage of the matrix subclass does not exist anymore. Since `scanpy` works with python 3.6 and python 3.7 and `numpy>=1.17.0`, there is no apparent reason why to use `np.matrix` instead of `np.array`.

Currently, `np.matrix` is used in `scanpy/plotting/_anndata.py` causing, for example, the `PendingDeprecationWarning`

```pytb
PendingDeprecationWarning: the matrix subclass is not the recommended way to represent matrices or deal with linear algebra (see https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users.html). Please adjust your code to use regular ndarray.
    np.matrix([label2code[lab] for lab in obs_tidy.index])
```


Discussion:

Resolving patch:
diff --git a/scanpy/plotting/_anndata.py b/scanpy/plotting/_anndata.py
--- a/scanpy/plotting/_anndata.py
+++ b/scanpy/plotting/_anndata.py
@@ -1242,7 +1242,7 @@ def heatmap(
                 arr += [idx] * (pos[1] + 1 - pos[0])
 
             gene_groups_ax.imshow(
-                np.matrix(arr).T, aspect='auto', cmap=groupby_cmap, norm=norm
+                np.array([arr]).T, aspect='auto', cmap=groupby_cmap, norm=norm
             )
             gene_groups_ax.axis('off')
 
@@ -1497,7 +1497,7 @@ def tracksplot(
             arr += [idx] * (pos[1] + 1 - pos[0])
 
         gene_groups_ax.imshow(
-            np.matrix(arr).T, aspect='auto', cmap=groupby_cmap, norm=norm
+            np.array([arr]).T, aspect='auto', cmap=groupby_cmap, norm=norm
         )
         gene_groups_ax.axis('off')
 
@@ -2311,7 +2311,7 @@ def _plot_categories_as_colorblocks(
 
     if orientation == 'left':
         groupby_ax.imshow(
-            np.matrix([label2code[lab] for lab in obs_tidy.index]).T,
+            np.array([[label2code[lab] for lab in obs_tidy.index]]).T,
             aspect='auto',
             cmap=groupby_cmap,
             norm=norm,
@@ -2334,7 +2334,7 @@ def _plot_categories_as_colorblocks(
         groupby_ax.set_ylabel(groupby)
     else:
         groupby_ax.imshow(
-            np.matrix([label2code[lab] for lab in obs_tidy.index]),
+            np.array([[label2code[lab] for lab in obs_tidy.index]]),
             aspect='auto',
             cmap=groupby_cmap,
             norm=norm,


Test patch:
Repository: scverse/scanpy

Issue:
moignard15 dataset link broken
`sc.datasets.moignard15()` results in a 404. The previous link http://www.nature.com/nbt/journal/v33/n3/extref/nbt.3154-S3.xlsx seems to not be working anymore.

It looks like supp info is still there, so links probably just need to be updated: https://www.nature.com/articles/nbt.3154#Sec24

Alternatively, maybe springer needs the 10k in publishing fees to keep their servers running.


Discussion:

Resolving patch:
diff --git a/scanpy/datasets/_datasets.py b/scanpy/datasets/_datasets.py
--- a/scanpy/datasets/_datasets.py
+++ b/scanpy/datasets/_datasets.py
@@ -119,11 +119,11 @@ def moignard15() -> AnnData:
     Annotated data matrix.
     """
     filename = settings.datasetdir / 'moignard15/nbt.3154-S3.xlsx'
-    backup_url = 'http://www.nature.com/nbt/journal/v33/n3/extref/nbt.3154-S3.xlsx'
+    backup_url = 'https://static-content.springer.com/esm/art%3A10.1038%2Fnbt.3154/MediaObjects/41587_2015_BFnbt3154_MOESM4_ESM.xlsx'
     adata = read(filename, sheet='dCt_values.txt', backup_url=backup_url)
     # filter out 4 genes as in Haghverdi et al. (2016)
     gene_subset = ~np.in1d(adata.var_names, ['Eif2b1', 'Mrpl19', 'Polr2a', 'Ubc'])
-    adata = adata[:, gene_subset]  # retain non-removed genes
+    adata = adata[:, gene_subset].copy()  # retain non-removed genes
     # choose root cell for DPT analysis as in Haghverdi et al. (2016)
     adata.uns["iroot"] = 532  # note that in Matlab/R, counting starts at 1
     # annotate with Moignard et al. (2015) experimental cell groups


Test patch: