squidpy icon indicating copy to clipboard operation
squidpy copied to clipboard

TypeError: alpha must be a float or None

Open FvdBre opened this issue 2 years ago • 11 comments

Hi Michalk8, I am very excited to use Squidpy/Tangram to deconvolute public Visium 10X datasets. I tried to run the tutorial that is explained in the vignette (https://squidpy.readthedocs.io/en/stable/external_tutorials/tutorial_tangram.html).

When I run: sq.pl.spatial_scatter( adata_st, color="cluster", alpha=0.7, frameon=False, ax=axs[0] )

I get the following error:

TypeError                                 Traceback (most recent call last)
Cell In[3], line 2
      1 fig, axs = plt.subplots(1, 2, figsize=(20, 5))
----> 2 sq.pl.spatial_scatter(
      3     adata_st, color="cluster", alpha=0.7, frameon=False, ax=axs[0]
      4 )
      5 sc.pl.umap(
      6     adata_sc, color="cell_subclass", size=10, frameon=False, show=False, ax=axs[1]
      7 )
      8 plt.tight_layout()

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/squidpy/pl/_spatial.py:418, in spatial_scatter(adata, shape, **kwargs)
    377 @d.dedent
    378 @_wrap_signature
    379 def spatial_scatter(
   (...)
    382     **kwargs: Any,
    383 ) -> Optional[Union[Axes, Sequence[Axes]]]:
    384     """
    385     Plot spatial omics data with data overlayed on top.
    386 
   (...)
    416     %(spatial_plot.returns)s
    417     """
--> 418     return _spatial_plot(adata, shape=shape, seg=None, seg_key=None, **kwargs)

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/squidpy/pl/_spatial.py:282, in _spatial_plot(adata, shape, color, groups, library_id, library_key, spatial_key, img, img_res_key, img_alpha, img_cmap, img_channel, seg, seg_key, seg_cell_id, seg_contourpx, seg_outline, use_raw, layer, alt_var, size, size_key, scale_factor, crop_coord, cmap, palette, alpha, norm, na_color, connectivity_key, edges_width, edges_color, library_first, frameon, wspace, hspace, ncols, outline, outline_color, outline_width, legend_loc, legend_fontsize, legend_fontweight, legend_fontoutline, legend_na, colorbar, scalebar_dx, scalebar_units, title, axis_label, fig, ax, return_ax, figsize, dpi, save, scalebar_kwargs, edges_kwargs, **kwargs)
    277 if _seg is None and _cell_id is None:
    278     outline_params, kwargs = _set_outline(
    279         size=_size, outline=outline, outline_width=outline_width, outline_color=outline_color, **kwargs
    280     )
--> 282     ax, cax = _plot_scatter(
    283         coords=coords_sub,
    284         ax=ax,
    285         outline_params=outline_params,
    286         cmap_params=cmap_params,
    287         color_params=color_params,
    288         size=_size,
    289         color_vector=color_vector,
    290         na_color=na_color,
    291         **kwargs,
    292     )
    293 elif _seg is not None and _cell_id is not None:
    294     ax, cax = _plot_segment(
    295         seg=_seg,
    296         cell_id=_cell_id,
   (...)
    306         **kwargs,
    307     )

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/squidpy/pl/_spatial_utils.py:955, in _plot_scatter(coords, ax, outline_params, cmap_params, color_params, size, color_vector, na_color, **kwargs)
    944     _cax = scatter(
    945         coords[:, 0],
    946         coords[:, 1],
   (...)
    952         **kwargs,
    953     )
    954     ax.add_collection(_cax)
--> 955 _cax = scatter(
    956     coords[:, 0],
    957     coords[:, 1],
    958     c=color_vector,
    959     s=size,
    960     rasterized=sc_settings._vector_friendly,
    961     cmap=cmap_params.cmap,
    962     norm=norm,
    963     **kwargs,
    964 )
    965 cax = ax.add_collection(_cax)
    967 return ax, cax

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/squidpy/pl/_spatial_utils.py:531, in _shaped_scatter(x, y, s, c, shape, norm, **kwargs)
    529     alpha = ColorConverter().to_rgba_array(c)[..., -1]
    530     collection.set_facecolor(c)
--> 531     collection.set_alpha(alpha)
    533 return collection

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/matplotlib/collections.py:834, in Collection.set_alpha(self, alpha)
    832 def set_alpha(self, alpha):
    833     # docstring inherited
--> 834     super().set_alpha(alpha)
    835     self._update_dict['array'] = True
    836     self._set_facecolor(self._original_facecolor)

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/matplotlib/artist.py:930, in Artist.set_alpha(self, alpha)
    922 """
    923 Set the alpha value used for blending - not supported on all backends.
    924 
   (...)
    927 alpha : float or None
    928 """
    929 if alpha is not None and not isinstance(alpha, Number):
--> 930     raise TypeError('alpha must be a float or None')
    931 self._alpha = alpha
    932 self.pchanged()

TypeError: alpha must be a float or None

Looking at your code, I think the TypeError is caused by the lines below. Where, besides the alpha that is given as a keyword argument in the _sq.pl.spatial.scatter function, an additional alpha is written if isinstance(c, np.ndarray) and np.issubdtype(c.dtype, np.number) != True. I think this causes the TypeError because the additional alpha is not a float or None? This also seems to be the case because the code runs without errors if I internally manually set the newly written alpha to 0.7.

if isinstance(c, np.ndarray) and np.issubdtype(c.dtype, np.number):
    collection.set_array(np.ma.masked_invalid(c))
    collection.set_norm(norm)
else:
    alpha = ColorConverter().to_rgba_array(c)[..., -1]
    collection.set_facecolor(c)
    collection.set_alpha(alpha)

As I am just learning to read and write python code, I was wondering if you could help me figure out what goes wrong. Thanks in advance!

Package versions that I used:

scanpy==1.8.2 anndata==0.8.0 umap==0.5.3 numpy==1.23.5 scipy==1.5.2 pandas==1.5.2 scikit-learn==1.2.0 statsmodels==0.13.5 python-igraph==0.10.2 pynndescent==0.5.8
squidpy==1.2.2
tangram==1.0.3

...

FvdBre avatar Jan 09 '23 12:01 FvdBre

hi @FvdBre ,

which matplotlib version are you using>?

giovp avatar Jan 24 '23 16:01 giovp

Hi @giovp,

Thanks for your response. I am using 'matplotlib 3.3.1' and 'matplotlib_scalebar 0.8.1'.

FvdBre avatar Jan 24 '23 16:01 FvdBre

hi @FvdBre sorry I can't reproduce, can you maybe post a reproducible example using some squidpy datasets in this issue?

giovp avatar Jan 25 '23 14:01 giovp

Hi @giovp,

I got this error when I used a public 10X Visium dataset. But after running all the exact lines and data from the vignette listed above (https://squidpy.readthedocs.io/en/stable/external_tutorials/tutorial_tangram.html), I get the same error.

import scanpy as sc
import squidpy as sq
import numpy as np
import pandas as pd
from anndata import AnnData
import pathlib
import matplotlib.pyplot as plt
import matplotlib as mpl
import skimage

# import tangram for spatial deconvolution
import tangram as tg

sc.logging.print_header()
print(f"squidpy=={sq.__version__}")
print(f"tangram=={tg.__version__}")

Returns:

/opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
scanpy==1.8.2 anndata==0.8.0 umap==0.5.3 numpy==1.23.5 scipy==1.5.2 pandas==1.5.2 scikit-learn==1.2.0 statsmodels==0.13.5 python-igraph==0.10.2 pynndescent==0.5.8
squidpy==1.2.2
tangram==1.0.3

New line:

adata_st = sq.datasets.visium_fluo_adata_crop()
adata_st = adata_st[
    adata_st.obs.cluster.isin([f"Cortex_{i}" for i in np.arange(1, 5)])
].copy()
img = sq.datasets.visium_fluo_image_crop()

adata_sc = sq.datasets.sc_mouse_cortex()

New line:

sq.im.process(img=img, layer="image", method="smooth")
sq.im.segment(
    img=img,
    layer="image_smooth",
    method="watershed",
    channel=0,
)

New line:

inset_y = 1500
inset_x = 1700
inset_sy = 400
inset_sx = 500

fig, axs = plt.subplots(1, 3, figsize=(30, 10))
sq.pl.spatial_scatter(
    adata_st, color="cluster", alpha=0.7, frameon=False, ax=axs[0], title=""
)
axs[0].set_title("Clusters", fontdict={"fontsize": 20})
sf = adata_st.uns["spatial"]["V1_Adult_Mouse_Brain_Coronal_Section_2"]["scalefactors"][
    "tissue_hires_scalef"
]
rect = mpl.patches.Rectangle(
    (inset_y * sf, inset_x * sf),
    width=inset_sx * sf,
    height=inset_sy * sf,
    ec="yellow",
    lw=4,
    fill=False,
)
axs[0].add_patch(rect)

axs[0].axes.xaxis.label.set_visible(False)
axs[0].axes.yaxis.label.set_visible(False)

axs[1].imshow(
    img["image"][inset_y : inset_y + inset_sy, inset_x : inset_x + inset_sx, 0, 0]
    / 65536,
    interpolation="none",
)
axs[1].grid(False)
axs[1].set_xticks([])
axs[1].set_yticks([])
axs[1].set_title("DAPI", fontdict={"fontsize": 20})

crop = img["segmented_watershed"][
    inset_y : inset_y + inset_sy, inset_x : inset_x + inset_sx
].values.squeeze(-1)
crop = skimage.segmentation.relabel_sequential(crop)[0]
cmap = plt.cm.plasma
cmap.set_under(color="black")
axs[2].imshow(crop, interpolation="none", cmap=cmap, vmin=0.001)
axs[2].grid(False)
axs[2].set_xticks([])
axs[2].set_yticks([])
axs[2].set_title("Nucleous segmentation", fontdict={"fontsize": 20})

Returns:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 7
      4 inset_sx = 500
      6 fig, axs = plt.subplots(1, 3, figsize=(30, 10))
----> 7 sq.pl.spatial_scatter(
      8     adata_st, color="cluster", alpha=0.7, frameon=False, ax=axs[0], title=""
      9 )
     10 axs[0].set_title("Clusters", fontdict={"fontsize": 20})
     11 sf = adata_st.uns["spatial"]["V1_Adult_Mouse_Brain_Coronal_Section_2"]["scalefactors"][
     12     "tissue_hires_scalef"
     13 ]

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/squidpy/pl/_spatial.py:418, in spatial_scatter(adata, shape, **kwargs)
    377 @d.dedent
    378 @_wrap_signature
    379 def spatial_scatter(
   (...)
    382     **kwargs: Any,
    383 ) -> Optional[Union[Axes, Sequence[Axes]]]:
    384     """
    385     Plot spatial omics data with data overlayed on top.
    386 
   (...)
    416     %(spatial_plot.returns)s
    417     """
--> 418     return _spatial_plot(adata, shape=shape, seg=None, seg_key=None, **kwargs)

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/squidpy/pl/_spatial.py:282, in _spatial_plot(adata, shape, color, groups, library_id, library_key, spatial_key, img, img_res_key, img_alpha, img_cmap, img_channel, seg, seg_key, seg_cell_id, seg_contourpx, seg_outline, use_raw, layer, alt_var, size, size_key, scale_factor, crop_coord, cmap, palette, alpha, norm, na_color, connectivity_key, edges_width, edges_color, library_first, frameon, wspace, hspace, ncols, outline, outline_color, outline_width, legend_loc, legend_fontsize, legend_fontweight, legend_fontoutline, legend_na, colorbar, scalebar_dx, scalebar_units, title, axis_label, fig, ax, return_ax, figsize, dpi, save, scalebar_kwargs, edges_kwargs, **kwargs)
    277 if _seg is None and _cell_id is None:
    278     outline_params, kwargs = _set_outline(
    279         size=_size, outline=outline, outline_width=outline_width, outline_color=outline_color, **kwargs
    280     )
--> 282     ax, cax = _plot_scatter(
    283         coords=coords_sub,
    284         ax=ax,
    285         outline_params=outline_params,
    286         cmap_params=cmap_params,
    287         color_params=color_params,
    288         size=_size,
    289         color_vector=color_vector,
    290         na_color=na_color,
    291         **kwargs,
    292     )
    293 elif _seg is not None and _cell_id is not None:
    294     ax, cax = _plot_segment(
    295         seg=_seg,
    296         cell_id=_cell_id,
   (...)
    306         **kwargs,
    307     )

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/squidpy/pl/_spatial_utils.py:955, in _plot_scatter(coords, ax, outline_params, cmap_params, color_params, size, color_vector, na_color, **kwargs)
    944     _cax = scatter(
    945         coords[:, 0],
    946         coords[:, 1],
   (...)
    952         **kwargs,
    953     )
    954     ax.add_collection(_cax)
--> 955 _cax = scatter(
    956     coords[:, 0],
    957     coords[:, 1],
    958     c=color_vector,
    959     s=size,
    960     rasterized=sc_settings._vector_friendly,
    961     cmap=cmap_params.cmap,
    962     norm=norm,
    963     **kwargs,
    964 )
    965 cax = ax.add_collection(_cax)
    967 return ax, cax

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/squidpy/pl/_spatial_utils.py:531, in _shaped_scatter(x, y, s, c, shape, norm, **kwargs)
    529     alpha = ColorConverter().to_rgba_array(c)[..., -1]
    530     collection.set_facecolor(c)
--> 531     collection.set_alpha(alpha)
    533 return collection

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/matplotlib/collections.py:834, in Collection.set_alpha(self, alpha)
    832 def set_alpha(self, alpha):
    833     # docstring inherited
--> 834     super().set_alpha(alpha)
    835     self._update_dict['array'] = True
    836     self._set_facecolor(self._original_facecolor)

File /opt/miniconda3/envs/tangram-env/lib/python3.8/site-packages/matplotlib/artist.py:930, in Artist.set_alpha(self, alpha)
    922 """
    923 Set the alpha value used for blending - not supported on all backends.
    924 
   (...)
    927 alpha : float or None
    928 """
    929 if alpha is not None and not isinstance(alpha, Number):
--> 930     raise TypeError('alpha must be a float or None')
    931 self._alpha = alpha
    932 self.pchanged()

TypeError: alpha must be a float or None

FvdBre avatar Jan 26 '23 12:01 FvdBre

Hey there! Could you also provide your plotting backend? Your code also works for me.

print(matplotlib.get_backend()) #-> module://matplotlib_inline.backend_inline for jupyter

timtreis avatar Jan 26 '23 15:01 timtreis

print(mpl.get_backend()) #-> module://matplotlib_inline.backend_inline for jupyter Returns: module://matplotlib_inline.backend_inline

Is this what you are looking for?

FvdBre avatar Jan 30 '23 10:01 FvdBre

@FvdBre I also tried to reproduce and didn't manage. Can you try with a standard dataset from squidpy and see if it works>?

giovp avatar Jan 30 '23 10:01 giovp

I ran the script as described in the vignette using the squidpy dataset:

adata_st = sq.datasets.visium_fluo_adata_crop()
adata_st
AnnData object with n_obs × n_vars = 324 × 16562
    obs: 'in_tissue', 'array_row', 'array_col', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster'
    var: 'gene_ids', 'feature_types', 'genome', 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
    uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial', 'umap'
    obsm: 'X_pca', 'X_umap', 'spatial'
    varm: 'PCs'
    obsp: 'connectivities', 'distances'

FvdBre avatar Jan 30 '23 13:01 FvdBre

Does the issue persist with a fresh conda env?

timtreis avatar Jan 30 '23 16:01 timtreis

My tangram environment seems fine, but when I run it on google colab I don't get the error. I guess this means I have a conflicting package installed on my base (all base packages listed below).

# packages in environment at /opt/miniconda3:
#
# Name                    Version                   Build  Channel
brotlipy                  0.7.0           py39h9ed2024_1003  
ca-certificates           2021.10.26           hecd8cb5_2  
certifi                   2021.10.8        py39hecd8cb5_2  
cffi                      1.14.6           py39h2125817_0  
charset-normalizer        2.0.4              pyhd3eb1b0_0  
conda                     4.11.0           py39hecd8cb5_0  
conda-package-handling    1.7.3            py39h9ed2024_1  
cryptography              36.0.0           py39hf6deb26_0  
idna                      3.3                pyhd3eb1b0_0  
libcxx                    12.0.0               h2f01273_0  
libffi                    3.3                  hb1e8313_2  
ncurses                   6.3                  hca72f7f_2  
openssl                   1.1.1m               hca72f7f_0  
pycosat                   0.6.3            py39h9ed2024_0  
pycparser                 2.21               pyhd3eb1b0_0  
pyopenssl                 21.0.0             pyhd3eb1b0_1  
pysocks                   1.7.1            py39hecd8cb5_0  
python                    3.9.5                h88f2d9e_3  
python.app                3                py39h9ed2024_0  
readline                  8.1.2                hca72f7f_1  
requests                  2.27.1             pyhd3eb1b0_0  
ruamel_yaml               0.15.100         py39h9ed2024_0  
setuptools                58.0.4           py39hecd8cb5_0  
six                       1.16.0             pyhd3eb1b0_0  
sqlite                    3.37.0               h707629a_0  
tk                        8.6.11               h7bc2e8c_0  
tqdm                      4.62.3             pyhd3eb1b0_1  
tzdata                    2021e                hda174b7_0  
urllib3                   1.26.7             pyhd3eb1b0_0  
xz                        5.2.5                h1de35cc_0  
yaml                      0.2.5                haf1e3a3_0  
zlib                      1.2.11               h4dc903c_4  

Therefore I will reinstall miniconda.

UPDATE:

After reinstalling miniconda and comparing the packages in the base there is one package that is not there by default:

yaml 0.2.5 haf1e3a3_0

FvdBre avatar Jan 31 '23 13:01 FvdBre

If in a fresh conda env this problem doesn't persist then it must be some type of conflicts which is difficult to find

giovp avatar Jan 31 '23 14:01 giovp