Q:

include NAs as factor in seaborn boxplot

Can I show missing data as extra factor in seaborn? Googling for a while now. 
This is the simple code I am using:
ax = sns.boxplot(data=df, x=x, y=y)

There is an option such as dropna for value_counts:
df['bla'].value_counts(dropna = False)

but I could not find it for boxplots. Thanks.

A:

No you can't.
At least, not directly with seaborn.
Issues related to NaN values have been opened in seaborn for lineplot, or pairplot. However a ticket from 2014 seems to indicate that seaborn ignores missing values starting from 0.4. It can be confirmed from seaborn's source code categorical.py
box_data = remove_na(group_data)

The best I could come up with is to create an extra categorical column that expresses the valid/invalid column data status.
Then I would do 2 subplots :
 - a counplot that shows the nb of valid/invalid data for the column you are focusing on
 - some convential seaborn plot based on that column
Additionnaly, it is possible to access the boxplots in order to show the nb of points taken into account for each boxplot.
Similar could be done for barplots.
Another approach is to use the value_count intel and add it to plot as an annotation
Example:
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

def custom(val):
    if val >= 0.0:
        return np.NaN
    return val

df = pd.DataFrame(np.random.randn(500, 3))
df = df.rename(index=int, columns={0: 'col_1', 1: 'col_2', 2: 'col_3'})
df['four'] = 'bar'
df['five'] = df['col_1'] > 0
df['category'] = pd.cut(df['col_2'], bins=3, labels=['titi', 'tata', 'toto'])
df['col_3'] = df['col_1'].apply(custom)
df['is_col_3_na'] = pd.isna(df['col_3'])

fig, (ax1, ax2) = plt.subplots(1, 2)
validdf = df[(df['is_col_3_na'] == False)].copy()

sns.countplot(data=df, x='is_col_3_na', ax=ax1).set_title('col_3 valid/invalid data ratios')
sns.boxplot(data=validdf, x='category', y='col_3',
            #hue="category",
            ax=ax2)

print(df['is_col_3_na'].describe())
print(df['is_col_3_na'].value_counts())

# start: taken from https://python-graph-gallery.com/38-show-number-of-observation-on-boxplot/
# with proper modifications
# Calculate number of obs per group & median to position labels
medians = validdf.groupby(['category'])['col_3'].median().values
nobs = validdf['category'].value_counts().values
nobs = [str(x) for x in nobs.tolist()]
nobs = ["n: " + i for i in nobs]

# Add it to the plot
pos = range(len(nobs))
for tick, label in zip(pos, ax2.get_xticklabels()):
    ax2.text(pos[tick], medians[tick] + 0.03, nobs[tick],
             horizontalalignment='center', size='x-small', color='b', weight='semibold')
# end: taken from https://python-graph-gallery.com/38-show-number-of-observation-on-boxplot/
plt.show()

Output:

Console prints (concerning the column 'col_3'):
count      500
unique       2
top       True
freq       254
Name: is_col_3_na, dtype: object

True     254
False    246
Name: is_col_3_na, dtype: int64

