2

I'm trying to place statistics data about each parameter in diagonal of the plot by the following code:

import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset('iris')

def summary(x, **kwargs):
    x = pd.Series(x)
    
    label = x.describe()[['mean', 'std', 'min', '50%', 'max']]
       
    label = label.round()
    ax = plt.gca()
    ax.set_axis_off()
    
    ax.annotate(pd.DataFrame(label),
               xy = (0.1, 0.2), size = 20, xycoords = ax.transAxes)

grd = sns.PairGrid(data=iris, size = 4)
grd = grd.map_upper(plt.scatter, color = 'k')

grd = grd.map_lower(sns.kdeplot, cmap = 'PRGn_r')
grd = grd.map_upper(sns.kdeplot, cmap = 'PRGn_r')
grd = grd.map_lower(plt.scatter, color = 'k')

grd = grd.map_diag(summary);

but for some reason I have the ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). while trying to perform summary function, to be more precise - to put as the dataset pd.DataFrame(label) in ax.annotate.

Traceback

-------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-26-88744ab705f0> in <module>
      6 grd = grd.map_lower(plt.scatter, color = 'k')
      7 
----> 8 grd = grd.map_diag(summary)
      9 plt.show()

e:\Anaconda3\lib\site-packages\seaborn\axisgrid.py in map_diag(self, func, **kwargs)
   1448 
   1449         if "hue" not in signature(func).parameters:
-> 1450             return self._map_diag_iter_hue(func, **kwargs)
   1451 
   1452         # Loop over diagonal variables and axes, making one plot in each

e:\Anaconda3\lib\site-packages\seaborn\axisgrid.py in _map_diag_iter_hue(self, func, **kwargs)
   1515                     func(x=data_k, label=label_k, color=color, **plot_kwargs)
   1516                 else:
-> 1517                     func(data_k, label=label_k, color=color, **plot_kwargs)
   1518 
   1519         self._add_axis_labels()

<ipython-input-25-d3b35ec81d97> in summary(x, **kwargs)
      8     ax.set_axis_off()
      9 
---> 10     ax.annotate(pd.DataFrame(label),
     11                xy = (0.1, 0.2), size = 20, xycoords = ax.transAxes)

e:\Anaconda3\lib\site-packages\matplotlib\_api\deprecation.py in wrapper(*args, **kwargs)
    333                 f"for the old name will be dropped %(removal)s.")
    334             kwargs[new] = kwargs.pop(old)
--> 335         return func(*args, **kwargs)
    336 
    337     # wrapper() must keep the same documented signature as func(): if we

e:\Anaconda3\lib\site-packages\matplotlib\axes\_axes.py in annotate(self, text, xy, *args, **kwargs)
    650     @docstring.dedent_interpd
    651     def annotate(self, text, xy, *args, **kwargs):
--> 652         a = mtext.Annotation(text, xy, *args, **kwargs)
    653         a.set_transform(mtransforms.IdentityTransform())
    654         if 'clip_on' in kwargs:

e:\Anaconda3\lib\site-packages\matplotlib\text.py in __init__(self, text, xy, xytext, xycoords, textcoords, arrowprops, annotation_clip, **kwargs)
   1804 
   1805         # Must come last, as some kwargs may be propagated to arrow_patch.
-> 1806         Text.__init__(self, x, y, text, **kwargs)
   1807 
   1808     def contains(self, event):

e:\Anaconda3\lib\site-packages\matplotlib\text.py in __init__(self, x, y, text, color, verticalalignment, horizontalalignment, multialignment, fontproperties, rotation, linespacing, rotation_mode, usetex, wrap, transform_rotates_text, **kwargs)
    152         self._x, self._y = x, y
    153         self._text = ''
--> 154         self.set_text(text)
    155         self.set_color(
    156             color if color is not None else mpl.rcParams["text.color"])

e:\Anaconda3\lib\site-packages\matplotlib\text.py in set_text(self, s)
   1213         if s is None:
   1214             s = ''
-> 1215         if s != self._text:
   1216             self._text = str(s)
   1217             self.stale = True

e:\Anaconda3\lib\site-packages\pandas\core\generic.py in __nonzero__(self)
   1532     @final
   1533     def __nonzero__(self):
-> 1534         raise ValueError(
   1535             f"The truth value of a {type(self).__name__} is ambiguous. "
   1536             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."

ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Curious
  • 198
  • 7

1 Answers1

4
  • .annotate expects a string not a DataFrame or Series. Convert the Series, label, to a string with .to_string()
  • x is already a pandas.Series, so x = pd.Series(x) is not needed.
  • Reproducible and tested with seaborn 0.11.2, matplotlib 3.4.2, and pandas 1.3.1
import seaborn as sns
import matplotlib.pyplot as plt

# change your function; ax.annotate expects a string
def summary(x, **kwargs):
    
    label = x.describe()[['mean', 'std', 'min', '50%', 'max']].round()
       
    ax = plt.gca()
    ax.set_axis_off()
    
    # use .to_string()   
    ax.annotate(label.to_string(), xy=(0.1, 0.2), size=20, xycoords=ax.transAxes)

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158