Skip to content

[Bug]: scatter plot fails for list of lists with categorical data #26743

Open

Description

@sofyakrainova

Bug summary

scatter plot can handle categorical data and list of lists separately, but cannot handle then both that seems inconsistent. Looks at the examples

Code for reproduction

import matplotlib.pyplot as plt

# runs
plt.scatter([1,2,3], ["a", "b", "a"])
plt.show()

# runs
plt.scatter([[1, 0],[ 0, 1]], 
           [[1, 2], [2, 3]])
plt.show()

# fails
plt.scatter([[1, 0],[ 0, 1]], 
           [["a", "b"], ["b", "a"]])
plt.show()

Actual outcome

image
image

ValueError Traceback (most recent call last)
Cell In[51], line 11
8 plt.show()
10 # fails
---> 11 plt.scatter([[1, 0],[ 0, 1]],
12 [["a", "b"], ["b", "a"]])
13 plt.show()

File ~\anaconda3\lib\site-packages\matplotlib\pyplot.py:2862, in scatter(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, data, **kwargs)
2857 @_copy_docstring_and_deprecators(Axes.scatter)
2858 def scatter(
2859 x, y, s=None, c=None, marker=None, cmap=None, norm=None,
2860 vmin=None, vmax=None, alpha=None, linewidths=None, *,
2861 edgecolors=None, plotnonfinite=False, data=None, **kwargs):
-> 2862 __ret = gca().scatter(
2863 x, y, s=s, c=c, marker=marker, cmap=cmap, norm=norm,
2864 vmin=vmin, vmax=vmax, alpha=alpha, linewidths=linewidths,
2865 edgecolors=edgecolors, plotnonfinite=plotnonfinite,
2866 **({"data": data} if data is not None else {}), **kwargs)
2867 sci(__ret)
2868 return __ret

File ~\anaconda3\lib\site-packages\matplotlib_init_.py:1459, in _preprocess_data..inner(ax, data, *args, **kwargs)
1456 @functools.wraps(func)
1457 def inner(ax, *args, data=None, **kwargs):
1458 if data is None:
-> 1459 return func(ax, *map(sanitize_sequence, args), **kwargs)
1461 bound = new_sig.bind(ax, *args, **kwargs)
1462 auto_label = (bound.arguments.get(label_namer)
1463 or bound.kwargs.get(label_namer))

File ~\anaconda3\lib\site-packages\matplotlib\axes_axes.py:4673, in Axes.scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, **kwargs)
4667 linewidths = [
4668 lw if lw is not None else mpl.rcParams['lines.linewidth']
4669 for lw in linewidths]
4671 offsets = np.ma.column_stack([x, y])
-> 4673 collection = mcoll.PathCollection(
4674 (path,), scales,
4675 facecolors=colors,
4676 edgecolors=edgecolors,
4677 linewidths=linewidths,
4678 offsets=offsets,
4679 offset_transform=kwargs.pop('transform', self.transData),
4680 alpha=alpha,
4681 )
4682 collection.set_transform(mtransforms.IdentityTransform())
4683 if colors is None:

File ~\anaconda3\lib\site-packages\matplotlib\collections.py:994, in PathCollection.init(self, paths, sizes, **kwargs)
980 def init(self, paths, sizes=None, **kwargs):
981 """
982 Parameters
983 ----------
(...)
991 Forwarded to .Collection.
992 """
--> 994 super().init(**kwargs)
995 self.set_paths(paths)
996 self.set_sizes(sizes)

File ~\anaconda3\lib\site-packages\matplotlib_api\deprecation.py:454, in make_keyword_only..wrapper(*args, **kwargs)
448 if len(args) > name_idx:
449 warn_deprecated(
450 since, message="Passing the %(name)s %(obj_type)s "
451 "positionally is deprecated since Matplotlib %(since)s; the "
452 "parameter will become keyword-only %(removal)s.",
453 name=name, obj_type=f"parameter of {func.name}()")
--> 454 return func(*args, **kwargs)

File ~\anaconda3\lib\site-packages\matplotlib\collections.py:192, in Collection.init(self, edgecolors, facecolors, linewidths, linestyles, capstyle, joinstyle, antialiaseds, offsets, offset_transform, norm, cmap, pickradius, hatch, urls, zorder, **kwargs)
189 self._joinstyle = None
191 if offsets is not None:
--> 192 offsets = np.asanyarray(offsets, float)
193 # Broadcast (2,) -> (1, 2) but nothing else.
194 if offsets.shape == (2,):

ValueError: could not convert string to float: 'a'

Expected outcome

it should provide plot with categorical data on y-axis

Additional information

No response

Operating system

Windows

Matplotlib Version

3.7.1

Matplotlib Backend

module://matplotlib_inline.backend_inline

Python version

3.10.12

Jupyter version

6.5.3

Installation

conda

Activity

  1. anntzer commented on Sep 12, 2023

    @anntzer
    Contributor

    FWIW I think we should deprecate the auto-flattening (handling of list-of-lists) in scatter; it is inconsistent e.g. with plot.

  2. anirudh-hegde commented on Sep 29, 2023

    @anirudh-hegde

    Bug summary

    scatter plot can handle categorical data and list of lists separately, but cannot handle then both that seems inconsistent. Looks at the examples

    Code for reproduction

    import matplotlib.pyplot as plt
    
    # runs
    plt.scatter([1,2,3], ["a", "b", "a"])
    plt.show()
    
    # runs
    plt.scatter([[1, 0],[ 0, 1]], 
               [[1, 2], [2, 3]])
    plt.show()
    
    # fails
    plt.scatter([[1, 0],[ 0, 1]], 
               [["a", "b"], ["b", "a"]])
    plt.show()

    Actual outcome

    image

    image
    ValueError Traceback (most recent call last) Cell In[51], line 11 8 plt.show() 10 # fails ---> 11 plt.scatter([[1, 0],[ 0, 1]], 12 [["a", "b"], ["b", "a"]]) 13 plt.show()

    File ~\anaconda3\lib\site-packages\matplotlib\pyplot.py:2862, in scatter(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, data, **kwargs) 2857 @_copy_docstring_and_deprecators(Axes.scatter) 2858 def scatter( 2859 x, y, s=None, c=None, marker=None, cmap=None, norm=None, 2860 vmin=None, vmax=None, alpha=None, linewidths=None, *, 2861 edgecolors=None, plotnonfinite=False, data=None, **kwargs): -> 2862 __ret = gca().scatter( 2863 x, y, s=s, c=c, marker=marker, cmap=cmap, norm=norm, 2864 vmin=vmin, vmax=vmax, alpha=alpha, linewidths=linewidths, 2865 edgecolors=edgecolors, plotnonfinite=plotnonfinite, 2866 **({"data": data} if data is not None else {}), **kwargs) 2867 sci(__ret) 2868 return __ret

    File ~\anaconda3\lib\site-packages\matplotlib__init__.py:1459, in _preprocess_data..inner(ax, data, *args, **kwargs) 1456 @functools.wraps(func) 1457 def inner(ax, *args, data=None, **kwargs): 1458 if data is None: -> 1459 return func(ax, *map(sanitize_sequence, args), **kwargs) 1461 bound = new_sig.bind(ax, *args, **kwargs) 1462 auto_label = (bound.arguments.get(label_namer) 1463 or bound.kwargs.get(label_namer))

    File ~\anaconda3\lib\site-packages\matplotlib\axes_axes.py:4673, in Axes.scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, **kwargs) 4667 linewidths = [ 4668 lw if lw is not None else mpl.rcParams['lines.linewidth'] 4669 for lw in linewidths] 4671 offsets = np.ma.column_stack([x, y]) -> 4673 collection = mcoll.PathCollection( 4674 (path,), scales, 4675 facecolors=colors, 4676 edgecolors=edgecolors, 4677 linewidths=linewidths, 4678 offsets=offsets, 4679 offset_transform=kwargs.pop('transform', self.transData), 4680 alpha=alpha, 4681 ) 4682 collection.set_transform(mtransforms.IdentityTransform()) 4683 if colors is None:

    File ~\anaconda3\lib\site-packages\matplotlib\collections.py:994, in PathCollection.init(self, paths, sizes, **kwargs) 980 def init(self, paths, sizes=None, **kwargs): 981 """ 982 Parameters 983 ---------- (...) 991 Forwarded to .Collection. 992 """ --> 994 super().init(**kwargs) 995 self.set_paths(paths) 996 self.set_sizes(sizes)

    File ~\anaconda3\lib\site-packages\matplotlib_api\deprecation.py:454, in make_keyword_only..wrapper(*args, **kwargs) 448 if len(args) > name_idx: 449 warn_deprecated( 450 since, message="Passing the %(name)s %(obj_type)s " 451 "positionally is deprecated since Matplotlib %(since)s; the " 452 "parameter will become keyword-only %(removal)s.", 453 name=name, obj_type=f"parameter of {func.name}()") --> 454 return func(*args, **kwargs)

    File ~\anaconda3\lib\site-packages\matplotlib\collections.py:192, in Collection.init(self, edgecolors, facecolors, linewidths, linestyles, capstyle, joinstyle, antialiaseds, offsets, offset_transform, norm, cmap, pickradius, hatch, urls, zorder, **kwargs) 189 self._joinstyle = None 191 if offsets is not None: --> 192 offsets = np.asanyarray(offsets, float) 193 # Broadcast (2,) -> (1, 2) but nothing else. 194 if offsets.shape == (2,):

    ValueError: could not convert string to float: 'a'

    Expected outcome

    it should provide plot with categorical data on y-axis

    Additional information

    No response

    Operating system

    Windows

    Matplotlib Version

    3.7.1

    Matplotlib Backend

    module://matplotlib_inline.backend_inline

    Python version

    3.10.12

    Jupyter version

    6.5.3

    Installation

    conda

    I am interested to solve your issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions