The following plotting issue occurs in preparation for a model build:

feature = 'Forks'
hue = 'dataset'
target = 'SalePrice'
data[[feature, target, hue]].head()
    data=data[[feature, target, hue]].dropna(), 

train    401125
test      12457
Name: dataset, dtype: int64

    Forks   SalePrice   dataset
205615  NaN     9,500.00    train
92803   None or Unspecified     24,000.00   train
98346   NaN     35,000.00   train
169297  None or Unspecified     19,000.00   train
274835  None or Unspecified     14,000.00   train

ValueError                                Traceback (most recent call last)
Input In [69], in <cell line: 7>()
      4 data[hue].value_counts()
      5 data[[feature, target, hue]].head()
----> 7 sns.violinplot(
      8     data=data[[feature, target, hue]].dropna(), 
      9     x=feature, 
     10     y=target, 
     11     hue=hue,
     12     split=True, 
     13 )

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\seaborn\_decorators.py:46, in _deprecate_positional_args.<locals>.inner_f(*args, **kwargs)
     36     warnings.warn(
     37         "Pass the following variable{} as {}keyword arg{}: {}. "
     38         "From version 0.12, the only valid positional argument "
     43         FutureWarning
     44     )
     45 kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 46 return f(**kwargs)

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\seaborn\categorical.py:2400, in violinplot(x, y, hue, data, order, hue_order, bw, cut, scale, scale_hue, gridsize, width, inner, split, dodge, orient, linewidth, color, palette, saturation, ax, **kwargs)
   2388 @_deprecate_positional_args
   2389 def violinplot(
   2390     *,
   2397     ax=None, **kwargs,
   2398 ):
-> 2400     plotter = _ViolinPlotter(x, y, hue, data, order, hue_order,
   2401                              bw, cut, scale, scale_hue, gridsize,
   2402                              width, inner, split, dodge, orient, linewidth,
   2403                              color, palette, saturation)
   2405     if ax is None:
   2406         ax = plt.gca()

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\seaborn\categorical.py:541, in _ViolinPlotter.__init__(self, x, y, hue, data, order, hue_order, bw, cut, scale, scale_hue, gridsize, width, inner, split, dodge, orient, linewidth, color, palette, saturation)
    539 if split and self.hue_names is not None and len(self.hue_names) != 2:
    540     msg = "There must be exactly two hue levels to use `split`.'"
--> 541     raise ValueError(msg)
    542 self.split = split
    544 if linewidth is None:

ValueError: There must be exactly two hue levels to use `split`.'

And now I'm stuck, because ??sns.categorical._ViolinPlotter does not clarify for me where self.hue_names comes from and why len(self.hue_names) would not just be 2. Does anybody have any insights?


1 Answer 1


A violin plot normally draws symmetric violins for each unique value of hue.

If hue takes on exactly two values, the two violins for can be combined into one asymmetric "split" violin by passing split=True.

If the hue column has fewer or more unique values, it makes no sense to plot a split plot.

In your case it seems that the hue column named dataset has just one unique value 'train' in it and a split violin does not make sense.

Refer to the documentation and look at the two plots below. The first one draws two violins for each value of x, one for alive passengers and the other for dead passengers, while the second one draws one violin with the left and right sides being asymmetric and corresponding to dead and alive passengers.

enter image description here enter image description here

  • $\begingroup$ You're absolutely correct. I overlooked the fact that although 'data' has two distinct values for 'hue', when I perform: data=data[[feature, target, hue]].dropna(), I just ditched all the values with hue 'test', because they none of those have a 'target' value. $\endgroup$
    – Tim
    Commented Jul 26, 2023 at 8:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.