Repository: scverse/scanpy

Issue:
Plotting layout behavior at repl
As mentioned in #299, I'm getting some strange layout behavior when plotting at the repl.

Using the setup:

```python
import scanpy.api as sc
import numpy as np

N = 1000
M = 2000

adata = sc.AnnData(X=np.random.random_sample((N, M)))

sc.pp.pca(adata)
```

I get outputs that look like the following 

```python
sc.pl.pca(adata, color=list("123"))
```

<img width="1552" alt="screen shot 2018-10-18 at 4 46 46 pm" src="https://user-images.githubusercontent.com/8238804/47133668-72d23780-d2f5-11e8-9630-f6e676a146ca.png">

```python
sc.pl.pca(adata, color=list("1234"))
```

<img width="1552" alt="screen shot 2018-10-18 at 4 47 37 pm" src="https://user-images.githubusercontent.com/8238804/47133696-909f9c80-d2f5-11e8-8482-eab30e84fe46.png">

```python
sc.pl.pca(adata, color=list("12"), ncols=1)
```

<img width="839" alt="screen shot 2018-10-18 at 4 50 11 pm" src="https://user-images.githubusercontent.com/8238804/47133806-17547980-d2f6-11e8-97ad-6d9528ea280b.png">

I get similar results with the MacOSX and GR backends (haven't checked others).

I think the issue is due to the implicit `bbox_inches="tight"` occurring with the matplotlib inline backend, and its explicit usage for `scanpy.plotting.utils.savefig`.  In the cases here, the bounding box is not being trimmed.


Discussion:
thanks for the report! if you type plt.tight_layout() do you get better
images?


On Thu, Oct 18, 2018 at 8:50 AM Isaac Virshup <notifications@github.com>
wrote:

> As mentioned in #299 <https://github.com/theislab/scanpy/issues/299>, I'm
> getting some strange layout behavior when plotting at the repl.
>
> Using the setup:
>
> import scanpy.api as scimport numpy as np
>
> N = 1000
> M = 2000
>
> adata = sc.AnnData(X=np.random.random_sample((N, M)))
>
> sc.pp.pca(adata)
>
> I get outputs that look like the following
>
> sc.pl.pca(adata, color=list("123"))
>
> [image: screen shot 2018-10-18 at 4 46 46 pm]
> <https://user-images.githubusercontent.com/8238804/47133668-72d23780-d2f5-11e8-9630-f6e676a146ca.png>
>
> sc.pl.pca(adata, color=list("1234"))
>
> [image: screen shot 2018-10-18 at 4 47 37 pm]
> <https://user-images.githubusercontent.com/8238804/47133696-909f9c80-d2f5-11e8-8482-eab30e84fe46.png>
>
> sc.pl.pca(adata, color=list("12"), ncols=1)
>
> [image: screen shot 2018-10-18 at 4 50 11 pm]
> <https://user-images.githubusercontent.com/8238804/47133806-17547980-d2f6-11e8-97ad-6d9528ea280b.png>
>
> I get similar results with the MacOSX and GR backends (haven't checked
> others).
>
> I think the issue is due to the implicit bbox_inches="tight" occurring
> with the matplotlib inline backend, and its explicit usage for
> scanpy.plotting.utils.savefig. In the cases here, the bounding box is not
> being trimmed.
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/theislab/scanpy/issues/309>, or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AEu_1RC33MewvC1wM45k3iek6QjaeHcyks5umCSYgaJpZM4Xsxiv>
> .
>

I get this warning:

```python
/usr/local/lib/python3.6/site-packages/matplotlib/figure.py:2362: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  warnings.warn("This figure includes Axes that are not compatible "
```

and the same layout.
Does this problem also happens with the previous code? this is just to guide me on a solution.
On a6165678, there are still larger margins on the right, but much less extreme:

![figure_1](https://user-images.githubusercontent.com/8238804/47275093-1d996d00-d5f8-11e8-9373-fd8e3a16ea18.png)

Found the problem. PR coming.

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
@@ -236,7 +236,7 @@ def plot_scatter(adata,
         from matplotlib import gridspec
         # set up the figure
         num_panels = len(color) * len(components_list)
-        n_panels_x = ncols
+        n_panels_x = min(ncols, num_panels)
         n_panels_y = np.ceil(num_panels / n_panels_x).astype(int)
         # each panel will have the size of rcParams['figure.figsize']
         fig = pl.figure(figsize=(n_panels_x * rcParams['figure.figsize'][0] * (1 + wspace),


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