Reputation: 29
I need to overlay two sns.catplots One is of kind='box' and the other is kind='swarm' as follows:
gbox= sns.catplot( x="Emotion",y="Threshold",hue="Group", col = 'Task',
data=indata,palette ["skyblue","salmon"], kind="box", showmeans='True', meanline = 'True', height=6, aspect=0.8, boxprops={'facecolor':'None'}, edgecolor='gray')
sns.catplot( x="Emotion",y="Threshold",hue="Group", col = 'Task',
data=indata, palette=["skyblue","salmon"], kind="swarm",ax=gbox.axes)
I have tried taking the axes from one and feeding into the other catplot, but I receive an error as below. How can I fix this?
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-74-7a05cc88a396> in <module>
17
18 gbox =sns.catplot( x="Emotion",y="Threshold",hue="Group", col = 'Task',
---> 19 data=indata,palette=["skyblue","salmon"],kind="swarm",ax=gbox.axes)
20
21 #plt.show(gbox)
~/anaconda3/lib/python3.6/site-packages/seaborn/categorical.py in catplot(x, y, hue, data, row, col, col_wrap, estimator, ci, n_boot, units, order, hue_order, row_order, col_order, kind, height, aspect, orient, color, palette, legend, legend_out, sharex, sharey, margin_titles, facet_kws, **kwargs)
3753
3754 # Draw the plot onto the facets
-> 3755 g.map_dataframe(plot_func, x, y, hue, **plot_kws)
3756
3757 # Special case axis labels for a count type plot
~/anaconda3/lib/python3.6/site-packages/seaborn/axisgrid.py in map_dataframe(self, func, *args, **kwargs)
818
819 # Draw the plot
--> 820 self._facet_plot(func, ax, args, kwargs)
821
822 # Finalize the annotations and layout
~/anaconda3/lib/python3.6/site-packages/seaborn/axisgrid.py in _facet_plot(self, func, ax, plot_args, plot_kwargs)
836
837 # Draw the plot
--> 838 func(*plot_args, **plot_kwargs)
839
840 # Sort out the supporting information
~/anaconda3/lib/python3.6/site-packages/seaborn/categorical.py in swarmplot(x, y, hue, data, order, hue_order, dodge, orient, color, palette, size, edgecolor, linewidth, ax, **kwargs)
2989 linewidth=linewidth))
2990
-> 2991 plotter.plot(ax, kwargs)
2992 return ax
2993
~/anaconda3/lib/python3.6/site-packages/seaborn/categorical.py in plot(self, ax, kws)
1444 def plot(self, ax, kws):
1445 """Make the full plot."""
-> 1446 self.draw_swarmplot(ax, kws)
1447 self.add_legend_data(ax)
1448 self.annotate_axes(ax)
~/anaconda3/lib/python3.6/site-packages/seaborn/categorical.py in draw_swarmplot(self, ax, kws)
1374 # Set the categorical axes limits here for the swarm math
1375 if self.orient == "v":
-> 1376 ax.set_xlim(-.5, len(self.plot_data) - .5)
1377 else:
1378 ax.set_ylim(-.5, len(self.plot_data) - .5)
AttributeError: 'numpy.ndarray' object has no attribute 'set_xlim'
Thank you for your help! SJ
Upvotes: 2
Views: 1734
Reputation: 1000
First create the catplot that sets up the facet grid and then loop over the axes and plot the overlay plots on them individually. So roughly like this:
gbox = sns.catplot(
data=indata,
x="Emotion",
y="Threshold",
hue="Group",
col='Task',
palette["skyblue", "salmon"],
kind="box",
showmeans='True',
meanline='True',
height=6,
aspect=0.8,
boxprops={'facecolor': 'None'},
edgecolor='gray',
)
for i, task in enumerate(indata['Task'].unique()):
sns.swarmplot( # Note: just one swarmplot
data=indata[indata['Task'] == task], # select the relevant data subset
ax=gbox.axes[i], # append to the relevant axis
x="Emotion",
y="Threshold",
hue="Group",
palette=["skyblue", "salmon"],
)
Upvotes: 0
Reputation: 756
In theory, using the .map and .map_dataframe methods should work, but
EDIT it sort of works but only when sns.FacetGrid is first initiated independently with
col/row
argument, and thehue
parameter is passed in individual .map_dataframe functions? I did not explore every combination, this is a bit hacky and inconsistently working in anyway.
EDIT this is at least the case for pointplot, see issue #2339
Ideally, the catplot/lmplot/relplot/displot functions should allow a grid argument (equivalent to the ax argument of the other seaborn functions)!
Upvotes: 0
Reputation: 40747
You cannot pass an ax=
parameter to catplot
. You will need to create the FacetGrid
"by hand".
Something like this: (untested because you did not provide data)
g = sns.FacetGrid(data=indata, hue="Group", col ='Task',
palette=["skyblue","salmon"])
g.map(sns.boxplot, x="Emotion", y="Threshold", showmeans='True', meanline = 'True',
height=6, aspect=0.8, boxprops={'facecolor':'None'}, edgecolor='gray')
g.map(sns.swarmplot, x="Emotion", y="Threshold")
Upvotes: -1