Seaborn Facetgrid with Mosaic Plot

Trying to plot a grid of mosaic plots using Seaborn's FacetGrid and statsmodels' mosaic and not quite making it.

Example dataset:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from statsmodels.graphics.mosaicplot import mosaic

index = [i for j in [[k] * 6 for k in range(4)] for i in j]
gender = ['male', 'male', 'male', 'female', 'female', 'female'] * 4
pet = np.random.choice(['cat', 'dog'], 24).tolist()
data = pd.DataFrame({'index': index, 'gender': gender, 'pet': pet})
data.head(10)
    index   gender  pet
0   0   male    dog
1   0   male    dog
2   0   male    cat
3   0   female  dog
4   0   female  dog
5   0   female  cat
6   1   male    cat
7   1   male    dog
8   1   male    dog
9   1   female  dog

I want to make a 2x2 grid of 4 mosaic plots, each for the subset of column index.

Now, a single mosaic plot of say the first group (index == 0):

data0 = data[data['index'] == 0]

props = {}
for x in ['female', 'male']:
    for y, col in {'dog': 'red', 'cat': 'blue'}.items():
        props[(x, y)] ={'color': col}

mosaic(data0, ['gender', 'pet'],
       labelizer=lambda k: '',
       properties=props)
plt.show()

But trying to put this mosaic in a custom function sns.FacetGrid.map() could use, I fail (this is one version, I tried a few):

def my_mosaic(sliced_data, **kwargs):
    mosaic(sliced_data, ['gender', 'pet'],
       labelizer=lambda k: '',
       properties=props)

g = sns.FacetGrid(data, col='index', col_wrap=2)
g = g.map(my_mosaic)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-323-a81a61aaeaff> in <module>()
      5 
      6 g = sns.FacetGrid(data, col='index', col_wrap=2)
----> 7 g = g.map(my_mosaic)

~\AppData\Local\Programs\Python\Python36-32\lib\site-packages\seaborn\axisgrid.py in map(self, func, *args, **kwargs)
    741 
    742             # Draw the plot
--> 743             self._facet_plot(func, ax, plot_args, kwargs)
    744 
    745         # Finalize the annotations and layout

~\AppData\Local\Programs\Python\Python36-32\lib\site-packages\seaborn\axisgrid.py in _facet_plot(self, func, ax, plot_args, plot_kwargs)
    825 
    826         # Draw the plot
--> 827         func(*plot_args, **plot_kwargs)
    828 
    829         # Sort out the supporting information

TypeError: my_mosaic() missing 1 required positional argument: 'sliced_data'

I read the documentation and examples, but I just couldn't figure out how to make a callable function from any plotting function which isn't built-in in Seaborn or in matplotlib.pyplot (e.g. plt.scatter or sns.regplot).

1 Answer

I found it is easier to use map_dataframe() when you are ultimately dealing with... dataframes.

def my_mosaic(*args,**kwargs):
    mosaic(kwargs['data'], list(args),
           labelizer=lambda k: '',
           properties=props,
           ax=plt.gca())

g = sns.FacetGrid(data, col='index', col_wrap=2)
g = g.map_dataframe(my_mosaic, 'gender', 'pet')
0

Your Answer

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

Sarah Jenkins

Sarah Jenkins

Senior Technology Editor & AI Specialist

Sarah Jenkins is a veteran tech journalist with over 12 years of experience covering artificial intelligence, mobile innovations, and digital ethics. Her insights have appeared in leading technology publications worldwide.

Share this article
Twitter Facebook Pinterest