Repository: scverse/scanpy

Issue:
Recent changes in sc.tl.rank_genes_groups broke y-axis range in sc.pl.rank_genes_groups
<!-- Please give a clear and concise description of what the bug is: -->

y-axis range of sc.pl.rank_genes_groups seems unnecessarily long:

![image](https://user-images.githubusercontent.com/1140359/88754278-41bea200-d12c-11ea-9d8c-aeb013ea6a02.png)


<!-- Put a minimal reproducible example that reproduces the bug in the code block below: -->
```python
import scanpy as sc

sc.set_figure_params(dpi=72)
adata = sc.datasets.paul15()
sc.pp.log1p(adata)
sc.tl.rank_genes_groups(adata, groupby='paul15_clusters', method='t-test')
sc.pl.rank_genes_groups(adata, sharey=False)
```

#### Versions:
<!-- Output of scanpy.logging.print_versions() -->

scanpy==1.5.2.dev52+g10937f5f anndata==0.7.4 umap==0.4.6 numpy==1.19.0 scipy==1.5.1 pandas==1.0.5 scikit-learn==0.23.1 statsmodels==0.11.1




Discussion:
Output of the same code with scanpy 1.5.1:

![image](https://user-images.githubusercontent.com/1140359/88754404-8fd3a580-d12c-11ea-9ae6-866ab1da1255.png)

It'd be great have a test for this to catch such bugs next time, like checking the range of the scores.

Resolving patch:
diff --git a/scanpy/plotting/_tools/__init__.py b/scanpy/plotting/_tools/__init__.py
--- a/scanpy/plotting/_tools/__init__.py
+++ b/scanpy/plotting/_tools/__init__.py
@@ -229,7 +229,7 @@ def rank_genes_groups(
     groups: Union[str, Sequence[str]] = None,
     n_genes: int = 20,
     gene_symbols: Optional[str] = None,
-    key: Optional[str] = None,
+    key: Optional[str] = 'rank_genes_groups',
     fontsize: int = 8,
     ncols: int = 4,
     sharey: bool = True,
@@ -265,8 +265,6 @@ def rank_genes_groups(
         n_panels_per_row = kwds['n_panels_per_row']
     else:
         n_panels_per_row = ncols
-    if key is None:
-        key = 'rank_genes_groups'
     reference = str(adata.uns[key]['params']['reference'])
     group_names = adata.uns[key]['names'].dtype.names if groups is None else groups
     # one panel for each group
@@ -288,43 +286,48 @@ def rank_genes_groups(
     ymin = np.Inf
     ymax = -np.Inf
     for count, group_name in enumerate(group_names):
-        if sharey is True:
+        gene_names = adata.uns[key]['names'][group_name][:n_genes]
+        scores = adata.uns[key]['scores'][group_name][:n_genes]
+
+        # Setting up axis, calculating y bounds
+        if sharey:
+            ymin = min(ymin, np.min(scores))
+            ymax = max(ymax, np.max(scores))
+
             if ax0 is None:
                 ax = fig.add_subplot(gs[count])
                 ax0 = ax
             else:
                 ax = fig.add_subplot(gs[count], sharey=ax0)
         else:
+            ymin = np.min(scores)
+            ymax = np.max(scores)
+            ymax += 0.3 * (ymax - ymin)
+
             ax = fig.add_subplot(gs[count])
+            ax.set_ylim(ymin, ymax)
+
+        ax.set_xlim(-0.9, n_genes - 0.1)
 
-        gene_names = adata.uns[key]['names'][group_name]
-        scores = adata.uns[key]['scores'][group_name]
-        for ig, g in enumerate(gene_names[:n_genes]):
-            gene_name = gene_names[ig]
+        # Mapping to gene_symbols
+        if gene_symbols is not None:
             if adata.raw is not None and adata.uns[key]['params']['use_raw']:
-                ax.text(
-                    ig,
-                    scores[ig],
-                    gene_name
-                    if gene_symbols is None
-                    else adata.raw.var[gene_symbols][gene_name],
-                    rotation='vertical',
-                    verticalalignment='bottom',
-                    horizontalalignment='center',
-                    fontsize=fontsize,
-                )
+                gene_names = adata.raw.var[gene_symbols][gene_names]
             else:
-                ax.text(
-                    ig,
-                    scores[ig],
-                    gene_name
-                    if gene_symbols is None
-                    else adata.var[gene_symbols][gene_name],
-                    rotation='vertical',
-                    verticalalignment='bottom',
-                    horizontalalignment='center',
-                    fontsize=fontsize,
-                )
+                gene_names = adata.var[gene_symbols][gene_names]
+
+        # Making labels
+        for ig, gene_name in enumerate(gene_names):
+            ax.text(
+                ig,
+                scores[ig],
+                gene_name,
+                rotation='vertical',
+                verticalalignment='bottom',
+                horizontalalignment='center',
+                fontsize=fontsize,
+            )
+
         ax.set_title('{} vs. {}'.format(group_name, reference))
         if count >= n_panels_x * (n_panels_y - 1):
             ax.set_xlabel('ranking')
@@ -333,17 +336,6 @@ def rank_genes_groups(
         if count % n_panels_x == 0:
             ax.set_ylabel('score')
 
-        ax.set_xlim(-0.9, ig + 1 - 0.1)
-
-        if sharey is True:
-            ymin = min(ymin, np.min(scores))
-            ymax = max(ymax, np.max(scores))
-        else:
-            ymin = np.min(scores)
-            ymax = np.max(scores)
-            ymax += 0.3 * (np.max(scores) - np.min(scores))
-            ax.set_ylim(ymin, ymax)
-
     if sharey is True:
         ymax += 0.3 * (ymax - ymin)
         ax.set_ylim(ymin, ymax)


Test patch:
diff --git a/scanpy/tests/_images/master_ranked_genes.png b/scanpy/tests/_images/master_ranked_genes.png
Binary files a/scanpy/tests/_images/master_ranked_genes.png and b/scanpy/tests/_images/master_ranked_genes.png differ
diff --git a/scanpy/tests/_images/master_ranked_genes_sharey.png b/scanpy/tests/_images/master_ranked_genes_sharey.png
Binary files a/scanpy/tests/_images/master_ranked_genes_sharey.png and b/scanpy/tests/_images/master_ranked_genes_sharey.png differ