How to set the xlim and ylim of a FacetGrid
Asked Answered
I

3

138

I'm using sns.lmplot to plot a linear regression, dividing my dataset into two groups with a categorical variable.

For both x and y, I'd like to manually set the lower bound on both plots, but leave the upper bound at the Seaborn default. Here's a simple example:

import pandas as pd
import seaborn as sns
import numpy as np

n = 200
np.random.seed(2014)
base_x = np.random.rand(n)
base_y = base_x * 2
errors = np.random.uniform(size=n)
y = base_y + errors

df = pd.DataFrame({'X': base_x, 'Y': y, 'Z': ['A','B']*(100)})

mask_for_b = df.Z == 'B'
df.loc[mask_for_b,['X','Y']] = df.loc[mask_for_b,] *2

sns.lmplot('X','Y',df,col='Z',sharex=False,sharey=False)

This outputs the following: enter image description here

But in this example, I'd like the xlim and the ylim to be (0,*) . I tried using sns.plt.ylim and sns.plt.xlim but those only affect the right-hand plot. Example:

sns.plt.ylim(0,)
sns.plt.xlim(0,)

enter image description here

How can I access the xlim and ylim for each plot in the FacetGrid?

Iorgo answered 8/8, 2014 at 22:12 Comment(0)
A
218

The lmplot function returns a FacetGrid instance. This object has a method called set, to which you can pass key=value pairs and they will be set on each Axes object in the grid.

Secondly, you can set only one side of an Axes limit in matplotlib by passing None for the value you want to remain as the default.

Putting these together, we have:

g = sns.lmplot('X', 'Y', df, col='Z', sharex=False, sharey=False)
g.set(ylim=(0, None))

enter image description here

Update

  • Positional arguments, sharex and sharey are deprecate beginning in seaborn 0.11
g = sns.lmplot(x='X', y='Y', data=df, col='Z', facet_kws={'sharey': False, 'sharex': False})
g.set(ylim=(0, None))
Aseity answered 8/8, 2014 at 23:19 Comment(0)
G
97

You need to get hold of the axes themselves. Probably the cleanest way is to change your last row:

lm = sns.lmplot('X','Y',df,col='Z',sharex=False,sharey=False)

Then you can get hold of the axes objects (an array of axes):

axes = lm.axes

After that you can tweak the axes properties

axes[0,0].set_ylim(0,)
axes[0,1].set_ylim(0,)

creates:

enter image description here

Gabrielson answered 8/8, 2014 at 23:0 Comment(0)
B
1

You could also specify xlim and ylim parameters of FacetGrid via facet_kws:

sns.lmplot(df, x='X', y='Y', col='Z', facet_kws={'xlim': (0, 2), 'ylim': (0, 9)})

However, the same limits will be used for all subplots, as they are just handed over to Matplotlib's Figure.subplots method. This also means, you can't use (0, None), since it fixes the upper limit to 1. So, this is not really a solution for the OP, but for other cases (e. g. normalized variables like percentages) this can be useful.

Booher answered 29/9, 2023 at 10:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.