如何绘制 2 个 seaborn lmplots side-by-side?

How to plot 2 seaborn lmplots side-by-side?

在子图中绘制 2 个分布图或散点图效果很好:

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd
%matplotlib inline

# create df
x = np.linspace(0, 2 * np.pi, 400)
df = pd.DataFrame({'x': x, 'y': np.sin(x ** 2)})

# Two subplots
f, (ax1, ax2) = plt.subplots(1, 2, sharey=True)
ax1.plot(df.x, df.y)
ax1.set_title('Sharing Y axis')
ax2.scatter(df.x, df.y)

plt.show()

但是当我对 lmplot 而不是其他类型的图表执行相同操作时,我收到错误消息:

AttributeError: 'AxesSubplot' object has no attribute 'lmplot'

有什么方法可以并排绘制这些图表类型吗?

你得到那个错误是因为 matplotlib 及其对象完全不知道 seaborn 函数。

将您的轴对象(即 ax1ax2)传递给 seaborn.regplot or you can skip defining those and use the col kwarg of seaborn.lmplot

使用相同的导入,预定义轴并使用 regplot 如下所示:

# create df
x = np.linspace(0, 2 * np.pi, 400)
df = pd.DataFrame({'x': x, 'y': np.sin(x ** 2)})
df.index.names = ['obs']
df.columns.names = ['vars']

idx = np.array(df.index.tolist(), dtype='float')  # make an array of x-values

# call regplot on each axes
fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True)
sns.regplot(x=idx, y=df['x'], ax=ax1)
sns.regplot(x=idx, y=df['y'], ax=ax2)

使用 lmplot 需要 dataframe to be tidy。从上面的代码继续:

tidy = (
    df.stack() # pull the columns into row variables   
      .to_frame() # convert the resulting Series to a DataFrame
      .reset_index() # pull the resulting MultiIndex into the columns
      .rename(columns={0: 'val'}) # rename the unnamed column
)
sns.lmplot(x='obs', y='val', col='vars', hue='vars', data=tidy)

如果使用 lmplot 的目的是将 hue 用于两组不同的变量,如果不进行一些调整,regplot 可能还不够。 为了在两个 side-by-side 图中使用 seaborn 的 lmplot hue 参数,一种可能的解决方案是:

def hue_regplot(data, x, y, hue, palette=None, **kwargs):
    from matplotlib.cm import get_cmap
    
    regplots = []
    
    levels = data[hue].unique()
    
    if palette is None:
        default_colors = get_cmap('tab10')
        palette = {k: default_colors(i) for i, k in enumerate(levels)}
    
    for key in levels:
        regplots.append(
            sns.regplot(
                x=x,
                y=y,
                data=data[data[hue] == key],
                color=palette[key],
                **kwargs
            )
        )
    
    return regplots

此函数给出的结果类似于 lmplot(带有 hue 选项),但接受 ax 参数,这是创建复合图形所必需的。 用法示例是

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd
%matplotlib inline

rnd = np.random.default_rng(1234567890)

# create df
x = np.linspace(0, 2 * np.pi, 400)
df = pd.DataFrame({'x': x, 'y': np.sin(x ** 2),
                   'color1': rnd.integers(0,2, size=400), 'color2': rnd.integers(0,3, size=400)}) # color for exemplification

# Two subplots
f, (ax1, ax2) = plt.subplots(1, 2, sharey=True)
# ax1.plot(df.x, df.y)
ax1.set_title('Sharing Y axis')
# ax2.scatter(df.x, df.y)

hue_regplot(data=df, x='x', y='y', hue='color1', ax=ax1)
hue_regplot(data=df, x='x', y='y', hue='color2', ax=ax2)

plt.show()