Seaborn: Mapped arguments not being passed properly to plots inside FacetGrid?

Created on 29 Jul 2018  路  6Comments  路  Source: mwaskom/seaborn

My understanding is that, once a FacetGrid is constructed, .map is suppose to simply pass args and kwargs on to the plotting function. But this seems to behave strangely. The following works fine:

iris = sns.load_dataset('iris')
iris_melted = iris.melt('species')
g = sns.FacetGrid(iris_melted, col='variable', sharey=False
g.map(sns.boxplot, 'species', 'value')

But the following raises an exception (ValueError: Could not interpret input 'species'), even though x and y are the first two arguments to boxplot:

g = sns.FacetGrid(iris_melted, col='variable', sharey=False
g.map(sns.boxplot, x='species', y='value')

The docstring for map seems to suggest that the positional args aren't actually passed onto the plotting function, but instead identify columns in the DataFrame to use in the plot. But clearly something is being passed to the x and y args, because doing the following also fails (with TypeError: boxplot() got multiple values for argument 'x'):

g = sns.FacetGrid(iris_melted, col='variable', sharey=False
g.map(sns.boxplot, 'species', 'value', x='species', y='value')

I'm not sure if this is a bug, or if the docs are unclear about the expected behavior, but I would expect the second example above to work. Passing other kwargs (e.g., notch) seems to work fine; it appears to be just x and y that can't be explicitly named.

Most helpful comment

You may wish also to look at FacetGrid.map_dataframe

Ah, nice! This is what I was missing--I assumed that the internal implementation was basically this (i.e., the data passed by map would just be a subset of the original DataFrame.

FWIW, I do think this could probably be made clearer in the .map docstring. Maybe you could add a note to say something like "Note that calling map when the data passed to the FacetGrid is a pandas DataFrame can lead to unexpected behavior in the event that the plotting function's positional arguments optionally expect something other than numpy arrays. For a method suitable for plotting with functions that accept a long-form DataFrame, see map_dataframe".

Thanks!

All 6 comments

What version of things are you using? I can't reproduce the error you're seeing when I run your first chunk of code.

(By the way, generally speaking, it's a much better idea to use catplot (factorplot in < 0.9) than to pass functions to FacetGrid directly).

Sorry I just re-read the issue and see that it's the second chunk you are having trouble with.

Your understanding is wrong. As it says here:

args : strings
Column names in self.data that identify variables with data to plot. The data for each variable is passed to func in the order the variables are specified in the call.

It's only the kwargs that are passed through directly, so what's happening in your second chunk is that literally the string "species" is getting passed to the x parameter of boxplot. And, as it says, it's not sure what to do with that.

You may wish also to look at FacetGrid.map_dataframe, which as the docs say,

... is suitable for plotting with functions that accept a long-form DataFrame as a data keyword argument and access the data in that DataFrame using string variable names.

You may wish also to look at FacetGrid.map_dataframe

Ah, nice! This is what I was missing--I assumed that the internal implementation was basically this (i.e., the data passed by map would just be a subset of the original DataFrame.

FWIW, I do think this could probably be made clearer in the .map docstring. Maybe you could add a note to say something like "Note that calling map when the data passed to the FacetGrid is a pandas DataFrame can lead to unexpected behavior in the event that the plotting function's positional arguments optionally expect something other than numpy arrays. For a method suitable for plotting with functions that accept a long-form DataFrame, see map_dataframe".

Thanks!

Just wanted to chime in and say I had this issue too and didn't know about .map_dataframe until seeing this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

btyukodi picture btyukodi  路  3Comments

rrbarbosa picture rrbarbosa  路  3Comments

TDaltonC picture TDaltonC  路  3Comments

JanHomann picture JanHomann  路  3Comments

phantom0301 picture phantom0301  路  3Comments