9

Seaborn's catplot does not seem to be able to work with plt.subplots(). Am not sure whats the issue here but i dont seem to be able to put them side by side.

#Graph 1
plt.subplot(121)
sns.catplot(x="HouseStyle",y="SalePrice",data=df,kind="swarm")

#Graph 2
plt.subplot(122)
sns.catplot(x="LandContour",y="SalePrice",data=df,kind="swarm")

Output: Weird no output Weird no output2 Finally output

Aaron
  • 418
  • 1
  • 4
  • 16
  • The accepted answer no longer works with current versions of seaborn because figure-level functions do not have an axes/ax parameter. Additionally, the other answers are already covered by the duplicate. – Trenton McKinney Jul 19 '23 at 16:28

3 Answers3

6

Catplot is a figure-level function whereas you cannot use axes. Try using stripplot instead.

fig, axs = plt.subplots (1, 2, figsize=(25, 15))
sns.stripplot(x='category_col', y='y_col_1', data=df, ax=axs[0])
sns.stripplot(x='category_col', y='y_col_2', data=df, ax=axs[1])
Dharman
  • 30,962
  • 25
  • 85
  • 135
m_h
  • 485
  • 5
  • 11
3

You need to pass the created axis to seaborn's catplot while plotting. Following is a sample answer demonstrating this. A couple of things

  • I would suggest using add_subplot to create subplots like yours
  • The catplot will still return an axis object which can be closed using plt.close() where the number inside the brackets correspond to the figure count. See this answer for more details on close()

Complete reproducible answer

import seaborn as sns
import matplotlib.pyplot as plt

exercise = sns.load_dataset("exercise")

fig = plt.figure()

ax1 = fig.add_subplot(121)
g = sns.catplot(x="time", y="pulse", hue="kind", data=exercise, ax=ax1) # pass ax1

ax2 = fig.add_subplot(122)
g = sns.catplot(x="time", y="pulse", hue="kind", data=exercise, ax=ax2) # pass ax2

plt.close(2)
plt.close(3)
plt.tight_layout()

enter image description here

Sheldore
  • 37,862
  • 7
  • 57
  • 71
  • 11
    I can't seem to work with placing axes in a catplot because I get this error: `UserWarning: catplot is a figure-level function and does not accept target axes.` – Pherdindy Oct 22 '20 at 09:20
  • 1
    @Pherdindy, this is correct and I have not been able to find a solution. I also cannot simply use `plt.figure()` to make a new figure for `sns.catplot` to use, catplot always makes its own. – Seth Nov 17 '20 at 21:26
  • 3
    Note that since seaborn 0.11, `catplot` (and similar figure-level functions) don't accept the `ax=` parameter anymore. You either need to directly call the underlying axes-level function (e.g. `stripplot(...., ax=...)`) or convert the dataframe to "long form" (via pandas `melt`). – JohanC Feb 11 '22 at 08:01
1

Thank you Sheldore for giving an idea of using close(). I tried this way and it worked.

_, ax = plt.subplots(2, 3, figsize=(20,10))
for n, feat in enumerate(cat_feats):
        sns.catplot(x='feat', kind='count', data=df, ax=ax[n//3][n%3])
        plt.close()