2

The seaborn documentation makes a distinction between figure-level and axes-level functions: https://seaborn.pydata.org/introduction.html#figure-level-and-axes-level-functions

I understand that functions like sns.boxplot can take an axis as argument, and can therefore be used within subplots.

But how about sns.relplot() ? Is there no way to put that into subplots?

More generally, is there any way to get seaborn to generate line plots within subplots?

For example, this doesn't work:

fig,ax=plt.subplots(2)
sns.relplot(x,y, ax=ax[0])

because relplot doesn't take axes as an argument.

Pythonista anonymous
  • 6,902
  • 18
  • 55
  • 97

1 Answers1

1

Well that's not true. You can indeed pass axis objects to relplot. Below is a minimal answer. The key point here is to close the empty axis objects returned by relplot. You can then also use ax[0] or ax[1] to add additional curves to your individual subfigures just like you would do with matplotlib.

import seaborn as sns
import matplotlib.pyplot as plt

fig, ax = plt.subplots(2)

xdata = np.arange(50)

sns.set(style="ticks")
tips = sns.load_dataset("tips")
g1 = sns.relplot(x="total_bill", y="tip", hue="day", data=tips, ax=ax[0])
g2 = sns.relplot(x="total_bill", y="tip", hue="day", data=tips, ax=ax[1])

# Now you can add any curves to individual axis objects 
ax[0].plot(xdata, xdata/5) 

# You will have to close the additional empty figures returned by replot
plt.close(g1.fig)
plt.close(g2.fig) 
plt.tight_layout()

enter image description here

You can also make line plot solely using seaborn as

import seaborn as sns
import numpy as np

x = np.linspace(0, 5, 100)
y = x**2

ax = sns.lineplot(x, y)
ax.set_xlabel('x-label')
ax.set_ylabel('y-label') 

enter image description here

Sheldore
  • 35,129
  • 6
  • 43
  • 58
  • Thank you, but I don't understand :( Passing the axis tells seaborn where it should be plotting, so why is it creating two more charts we then have to get rid of? Also, is this documented anywhere? Like so often in the Python world, I am left banging my head against the wall because something doesn't work and I can't find anything in the docs, till some kind soul comes along and explain an undocumented or hard-to-find feature... – Pythonista anonymous Mar 22 '19 at 23:59
  • Also, your data is organised has a 'third dimension', a categorical level. Can seaborn plot data which doesn't? Eg this does't work: `fig, ax = plt.subplots(2) `x=np.arange(1,20) `y=x**2 `g1 = sns.relplot(x=x, y=y, ax=ax[0])} – Pythonista anonymous Mar 23 '19 at 00:03
  • @Pythonistaanonymous: Answer to your first comment: Because `relplot` returns a FacetGrid as specified on the [official](https://seaborn.pydata.org/generated/seaborn.relplot.html) webpage. Sometimes, you have to play around a bit to find the solution. – Sheldore Mar 23 '19 at 00:49
  • @Pythonistaanonymous: Answer to your second comment: This is not the datatype for `relplot`. Why do you need to use this approach when you can simply write `ax[0].plot(x, y)` – Sheldore Mar 23 '19 at 00:52
  • @Pythonistaanonymous: I gave a similar answer [here](https://stackoverflow.com/a/52055241/4932316) – Sheldore Mar 23 '19 at 00:53
  • So replot cannot be used to plot an 'ordinary' line? Does seaborn have a function for that or not? Curious because seaborn charts tend to look nicer. PS If you edit your answer to include these points I can upvote and accept it - the site doesn't let me vote it otherwise – Pythonista anonymous Mar 23 '19 at 16:55
  • @Pythonistaanonymous: I have included a line plot. – Sheldore Mar 23 '19 at 16:58
  • 2
    I didn't downvote either, but I can imagine the argument for doing so being the following: A `relplot` is a figure level seaborn function. It is meant to create a FacetGrid of several line- or scatterplots. Now if you only have a single axes in that grid, there is no need for `relplot` anyways and you can (should) directly use either `lineplot` or `scatterplot`. And if you had more than one axes in the grid, the solution would not work anyways, because `ax` is not an argument to `relplot` itself, it's an argument to the underlying line- or scatterplot function. – ImportanceOfBeingErnest Mar 24 '19 at 00:33
  • `UserWarning: relplot is a figure-level function and does not accept target axes. You may wish to try scatterplot warnings.warn(msg, UserWarning)` – rocksNwaves May 03 '20 at 04:47