blehblehblecksheep
blehblehblecksheep

Reputation: 285

Matplotlib/Seaborn: Where am I making an elementwise comparison? ValueError: The truth value of an array with more than one element is ambiguous

toyData3 is a Pandas dataframe. sns is Seaborn module. I am able to plot the data but I get the following error when I run the code (minimal workin example) in Jupyter/Ipython console, that I don't understand. Where did I make an elementwise comparison? What is going on, and is it worth my concern?

In [3]: import pandas as pd                                                                                                                                                                                        

In [4]: import seaborn as sns                                                                                                                                                                                      

In [5]: data=[(0.  ,  0.        , 0.        ),(0.01,  0.10283333, 0.29774878), (0.02, -0.0395    , 0.16226045), (0.03,  0.06841667, 0.3111277 ), (0.04, -0.03508333, 0.19214552)]                                  

In [6]: toyData3 = pd.DataFrame.from_records(data, columns=['time', 'mean', 'SD'])                                                                                                                                 

In [7]: print(toyData3)                                                                                                                                                                                            
   time      mean        SD
0  0.00  0.000000  0.000000
1  0.01  0.102833  0.297749
2  0.02 -0.039500  0.162260
3  0.03  0.068417  0.311128
4  0.04 -0.035083  0.192146

In [8]: sns.relplot(data=toyData3, x=toyData3.index, y=toyData3.loc[:, 'mean'],  kind='line')                                                                                                                      
/home/user/anaconda3/envs/ilahi/lib/python3.8/site-packages/pandas/core/indexes/base.py:122: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
  result = op(self.values, np.asarray(other))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-35f5a3329860> in <module>
----> 1 sns.relplot(data=toyData3, x=toyData3.index, y=toyData3.loc[:, 'mean'],  kind='line')

~/anaconda3/envs/ilahi/lib/python3.8/site-packages/seaborn/relational.py in relplot(x, y, hue, size, style, data, row, col, col_wrap, row_order, col_order, palette, hue_order, hue_norm, sizes, size_order, size_norm, markers, dashes, style_order, legend, kind, height, aspect, facet_kws, **kwargs)                                                                                                                              
   1693 
   1694     # Draw the plot
-> 1695     g.map_dataframe(func, x, y,
   1696                     hue=hue, size=size, style=style,
   1697                     **plot_kws)

~/anaconda3/envs/ilahi/lib/python3.8/site-packages/seaborn/axisgrid.py in map_dataframe(self, func, *args, **kwargs)
    829 
    830         # Finalize the annotations and layout
--> 831         self._finalize_grid(args[:2])
    832 
    833         return self

~/anaconda3/envs/ilahi/lib/python3.8/site-packages/seaborn/axisgrid.py in _finalize_grid(self, axlabels)
    852     def _finalize_grid(self, axlabels):
    853         """Finalize the annotations and layout."""
--> 854         self.set_axis_labels(*axlabels)
    855         self.set_titles()
    856         self.fig.tight_layout()

~/anaconda3/envs/ilahi/lib/python3.8/site-packages/seaborn/axisgrid.py in set_axis_labels(self, x_var, y_var)
    878         if x_var is not None:
    879             self._x_var = x_var
--> 880             self.set_xlabels(x_var)
    881         if y_var is not None:
    882             self._y_var = y_var

~/anaconda3/envs/ilahi/lib/python3.8/site-packages/seaborn/axisgrid.py in set_xlabels(self, label, **kwargs)
    889             label = self._x_var
    890         for ax in self._bottom_axes:
--> 891             ax.set_xlabel(label, **kwargs)
    892         return self
    893 

~/anaconda3/envs/ilahi/lib/python3.8/site-packages/matplotlib/axes/_axes.py in set_xlabel(self, xlabel, fontdict, labelpad, loc, **kwargs)
    245         elif loc == 'right':
    246             kwargs.update(x=1, horizontalalignment='right')
--> 247         return self.xaxis.set_label_text(xlabel, fontdict, **kwargs)
    248 
    249     def get_ylabel(self):

~/anaconda3/envs/ilahi/lib/python3.8/site-packages/matplotlib/axis.py in set_label_text(self, label, fontdict, **kwargs)
   1561         """
   1562         self.isDefault_label = False
-> 1563         self.label.set_text(label)
   1564         if fontdict is not None:
   1565             self.label.update(fontdict)

~/anaconda3/envs/ilahi/lib/python3.8/site-packages/matplotlib/text.py in set_text(self, s)
   1163         if s is None:
   1164             s = ''
-> 1165         if s != self._text:
   1166             self._text = str(s)
   1167             self.stale = True

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Upvotes: 1

Views: 437

Answers (1)

Tom
Tom

Reputation: 8800

Version Issue: I was able to replicate with seaborn == 0.10.1, pandas == 1.1.4. But after updating to seaborn == 0.11.1, pandas == 1.2.2, I no longer get the error (I get the second plot below, hitch free). The change is related to seaborn, see the patch notes for 0.11.0 within this section:

relplot() now has the same flexibility as the axes-level functions to accept data in long- or wide-format and to accept data vectors (rather than named variables) in long-form mode.

So updating is a good, simple solution! But if that isn't an option, original answer below.


It seems the issue is you are trying to pass actual data to the x and y arguments, rather than column names in data. As seen in examples, the idiomatic way of plotting with seaborn is to name a DataFrame/array with data and then refer to columns in it with x, y, hue, etc. This is a little different from matplotlib where you typically pass the actual iterable data to the plotting function.

So I think the easiest fix is to move your index to a new column, and then plot:

toyData3 = toyData3.reset_index() # creates a new column "index"
sns.relplot(data=toyData3, x='index', y='mean',  kind='line')

Creating the following without errors:

enter image description here

What highlights the issue a little more is that (in my IDE at least) your code creates the following plot before exiting:

enter image description here

Data looks good, but the axis labels were not drawn. So it looks like seaborn is looking for an axis label, which would usually be provided via x and y, but in doing so runs into the error (more specifically, either the x or y is being compared to another value with a ==, returning an array of boolean values rather than a single True or False).

Upvotes: 3

Related Questions