scverse / scanpy

Single-cell analysis in Python. Scales to >1M cells.
https://scanpy.readthedocs.io
BSD 3-Clause "New" or "Revised" License
1.86k stars 595 forks source link

AttributeError (sc.pl.stacked_violin) #3140

Closed JelenaKrneta closed 2 months ago

JelenaKrneta commented 2 months ago

Please make sure these conditions are met

What happened?

I was running a basic workflow with 3k PBMC and at the step sc.pl.stacked_violin got Attribute error below

Minimal code sample

sc.pl.stacked_violin(adata, marker_genes, groupby='leiden', rotation=90)

Error output

--------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[51], line 1
----> 1 sc.pl.stacked_violin(adata, marker_genes, groupby='leiden', rotation=90);

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/legacy_api_wrap/__init__.py:80, in legacy_api.<locals>.wrapper.<locals>.fn_compatible(*args_all, **kw)
     77 @wraps(fn)
     78 def fn_compatible(*args_all: P.args, **kw: P.kwargs) -> R:
     79     if len(args_all) <= n_positional:
---> 80         return fn(*args_all, **kw)
     82     args_pos: P.args
     83     args_pos, args_rest = args_all[:n_positional], args_all[n_positional:]

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/scanpy/plotting/_stacked_violin.py:825, in stacked_violin(adata, var_names, groupby, log, use_raw, num_categories, title, colorbar_title, figsize, dendrogram, gene_symbols, var_group_positions, var_group_labels, standard_scale, var_group_rotation, layer, stripplot, jitter, size, scale, yticklabels, order, swap_axes, show, save, return_fig, row_palette, cmap, ax, vmin, vmax, vcenter, norm, **kwds)
    823 if return_fig:
    824     return vp
--> 825 vp.make_figure()
    826 savefig_or_show(StackedViolin.DEFAULT_SAVE_PREFIX, show=show, save=save)
    827 show = settings.autoshow if show is None else show

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/scanpy/plotting/_baseplot_class.py:792, in BasePlot.make_figure(self)
    789     return_ax_dict["gene_group_ax"] = gene_groups_ax
    791 # plot the mainplot
--> 792 normalize = self._mainplot(main_ax)
    794 # code from pandas.plot in add_totals adds
    795 # minor ticks that need to be removed
    796 main_ax.yaxis.set_tick_params(which="minor", left=False, right=False)

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/scanpy/plotting/_stacked_violin.py:415, in StackedViolin._mainplot(self, ax)
    413 x_spacer_size = self.plot_x_padding
    414 y_spacer_size = self.plot_y_padding
--> 415 self._make_rows_of_violinplots(
    416     ax, _matrix, colormap_array, _color_df, x_spacer_size, y_spacer_size
    417 )
    419 # turn on axis for `ax` as this is turned off
    420 # by make_grid_spec when the axis is subdivided earlier.
    421 ax.set_frame_on(True)

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/scanpy/plotting/_stacked_violin.py:537, in StackedViolin._make_rows_of_violinplots(self, ax, _matrix, colormap_array, _color_df, x_spacer_size, y_spacer_size)
    531     # because of the renamed matrix columns here
    532     # we need to use this instead of the 'row_label'
    533     # (in _color_df the values are not renamed as those
    534     # values will be used to label the ticks)
    535     _df = df[df.genes == _matrix.columns[idx]]
--> 537 row_ax = sns.violinplot(
    538     x=x,
    539     y="values",
    540     data=_df,
    541     orient="vertical",
    542     ax=row_ax,
    543     # use a single `color`` if row_colors[idx] is defined
    544     # else use the palette
    545     hue=None if palette_colors is None else x,
    546     palette=palette_colors,
    547     color=row_colors[idx],
    548     **self.kwds,
    549 )
    551 if self.stripplot:
    552     row_ax = sns.stripplot(
    553         x=x,
    554         y="values",
   (...)
    559         ax=row_ax,
    560     )

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/seaborn/categorical.py:1770, in violinplot(data, x, y, hue, order, hue_order, orient, color, palette, saturation, fill, inner, split, width, dodge, gap, linewidth, linecolor, cut, gridsize, bw_method, bw_adjust, density_norm, common_norm, hue_norm, formatter, log_scale, native_scale, legend, scale, scale_hue, bw, inner_kws, ax, **kwargs)
   1767 kde_kws = dict(cut=cut, gridsize=gridsize, bw_method=bw_method, bw_adjust=bw_adjust)
   1768 inner_kws = {} if inner_kws is None else inner_kws.copy()
-> 1770 p.plot_violins(
   1771     width=width,
   1772     dodge=dodge,
   1773     gap=gap,
   1774     split=split,
   1775     color=color,
   1776     fill=fill,
   1777     linecolor=linecolor,
   1778     linewidth=linewidth,
   1779     inner=inner,
   1780     density_norm=density_norm,
   1781     common_norm=common_norm,
   1782     kde_kws=kde_kws,
   1783     inner_kws=inner_kws,
   1784     plot_kws=kwargs,
   1785 )
   1787 p._add_axis_labels(ax)
   1788 p._adjust_cat_axis(ax, axis=p.orient)

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/seaborn/categorical.py:1047, in _CategoricalPlotter.plot_violins(self, width, dodge, gap, split, color, fill, linecolor, linewidth, inner, density_norm, common_norm, kde_kws, inner_kws, plot_kws)
   1045 # Plot the main violin body
   1046 plot_func = {"x": ax.fill_betweenx, "y": ax.fill_between}[self.orient]
-> 1047 plot_func(
   1048     inv_val(data[value_var]),
   1049     inv_pos(data[self.orient] - offsets[0]),
   1050     inv_pos(data[self.orient] + offsets[1]),
   1051     **violin["kwargs"]
   1052 )
   1054 # Adjust the observation data
   1055 obs = violin["observations"]

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/matplotlib/__init__.py:1473, in _preprocess_data.<locals>.inner(ax, data, *args, **kwargs)
   1470 @functools.wraps(func)
   1471 def inner(ax, *args, data=None, **kwargs):
   1472     if data is None:
-> 1473         return func(
   1474             ax,
   1475             *map(sanitize_sequence, args),
   1476             **{k: sanitize_sequence(v) for k, v in kwargs.items()})
   1478     bound = new_sig.bind(ax, *args, **kwargs)
   1479     auto_label = (bound.arguments.get(label_namer)
   1480                   or bound.kwargs.get(label_namer))

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/matplotlib/axes/_axes.py:5662, in Axes.fill_betweenx(self, y, x1, x2, where, step, interpolate, **kwargs)
   5660 def fill_betweenx(self, y, x1, x2=0, where=None,
   5661                   step=None, interpolate=False, **kwargs):
-> 5662     return self._fill_between_x_or_y(
   5663         "y", y, x1, x2,
   5664         where=where, interpolate=interpolate, step=step, **kwargs)

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/matplotlib/axes/_axes.py:5629, in Axes._fill_between_x_or_y(self, ind_dir, ind, dep1, dep2, where, interpolate, step, **kwargs)
   5625         pts = pts[:, ::-1]
   5627     polys.append(pts)
-> 5629 collection = mcoll.PolyCollection(polys, **kwargs)
   5631 # now update the datalim and autoscale
   5632 pts = np.vstack([np.hstack([ind[where, None], dep1[where, None]]),
   5633                  np.hstack([ind[where, None], dep2[where, None]])])

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/matplotlib/collections.py:1198, in PolyCollection.__init__(self, verts, sizes, closed, **kwargs)
   1178 def __init__(self, verts, sizes=None, *, closed=True, **kwargs):
   1179     """
   1180     Parameters
   1181     ----------
   (...)
   1196         Forwarded to `.Collection`.
   1197     """
-> 1198     super().__init__(**kwargs)
   1199     self.set_sizes(sizes)
   1200     self.set_verts(verts, closed)

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/matplotlib/collections.py:206, in Collection.__init__(self, edgecolors, facecolors, linewidths, linestyles, capstyle, joinstyle, antialiaseds, offsets, offset_transform, norm, cmap, pickradius, hatch, urls, zorder, **kwargs)
    203 self._offset_transform = offset_transform
    205 self._path_effects = None
--> 206 self._internal_update(kwargs)
    207 self._paths = None

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/matplotlib/artist.py:1216, in Artist._internal_update(self, kwargs)
   1209 def _internal_update(self, kwargs):
   1210     """
   1211     Update artist properties without prenormalizing them, but generating
   1212     errors as if calling `set`.
   1213 
   1214     The lack of prenormalization is to maintain backcompatibility.
   1215     """
-> 1216     return self._update_props(
   1217         kwargs, "{cls.__name__}.set() got an unexpected keyword argument "
   1218         "{prop_name!r}")

File ~/miniconda3/envs/scarf_env/lib/python3.12/site-packages/matplotlib/artist.py:1190, in Artist._update_props(self, props, errfmt)
   1188             func = getattr(self, f"set_{k}", None)
   1189             if not callable(func):
-> 1190                 raise AttributeError(
   1191                     errfmt.format(cls=type(self), prop_name=k))
   1192             ret.append(func(v))
   1193 if ret:

AttributeError: PolyCollection.set() got an unexpected keyword argument 'rotation'

Versions

``` numpy 1.26.4 pandas 2.2.2 scanpy 1.10.2 session_info 1.0.0 ----- PIL 10.3.0 anndata 0.10.8 anyio NA arrow 1.3.0 asciitree NA asttokens NA attr 23.2.0 attrs 23.2.0 babel 2.15.0 certifi 2024.06.02 cffi 1.16.0 charset_normalizer 3.3.2 cloudpickle 3.0.0 comm 0.2.2 cycler 0.12.1 cython_runtime NA dask 2024.5.2 dateutil 2.9.0.post0 debugpy 1.8.1 decorator 5.1.1 defusedxml 0.7.1 executing 2.0.1 fastjsonschema NA fqdn NA h5py 3.11.0 idna 3.7 igraph 0.11.5 ipykernel 6.29.4 isoduration NA jedi 0.19.1 jinja2 3.1.4 joblib 1.4.2 json5 0.9.25 jsonpointer 2.4 jsonschema 4.22.0 jsonschema_specifications NA jupyter_events 0.10.0 jupyter_server 2.14.1 jupyterlab_server 2.27.2 kiwisolver 1.4.5 legacy_api_wrap NA leidenalg 0.10.2 llvmlite 0.42.0 markupsafe 2.1.5 matplotlib 3.9.0 mpl_toolkits NA natsort 8.4.0 nbformat 5.10.4 numba 0.59.1 numcodecs 0.12.1 overrides NA packaging 24.0 parso 0.8.4 platformdirs 4.2.2 prometheus_client NA prompt_toolkit 3.0.46 psutil 5.9.8 pure_eval 0.2.2 pyarrow 16.1.0 pydev_ipython NA pydevconsole NA pydevd 2.9.5 pydevd_file_utils NA pydevd_plugins NA pydevd_tracing NA pygments 2.18.0 pyparsing 3.1.2 pythonjsonlogger NA pytz 2024.1 referencing NA requests 2.32.3 rfc3339_validator 0.1.4 rfc3986_validator 0.1.1 rpds NA scipy 1.11.0 send2trash NA six 1.16.0 sklearn 1.5.0 sniffio 1.3.1 stack_data 0.6.3 texttable 1.7.0 threadpoolctl 3.5.0 tlz 0.12.1 toolz 0.12.1 tornado 6.4.1 traitlets 5.14.3 uri_template NA urllib3 2.2.1 wcwidth 0.2.13 webcolors 24.6.0 websocket 1.8.0 yaml 6.0.1 zarr 2.18.2 zmq 26.0.3 ----- IPython 8.25.0 jupyter_client 8.6.2 jupyter_core 5.7.2 jupyterlab 4.2.1 ----- Python 3.12.3 | packaged by Anaconda, Inc. | (main, May 6 2024, 19:46:43) [GCC 11.2.0] Linux-5.4.0-84-generic-x86_64-with-glibc2.27 ----- Session information updated at 2024-07-03 15:12 ```
JelenaKrneta commented 2 months ago

I am closing the issue because it was my mistake: I ran the script that I saved several years ago instead of the updated, current one at https://scanpy.readthedocs.io/en/stable/_sources/tutorials/basics/clustering-2017.ipynb (where the argument rotation is omitted)