简体   繁体   English

如何并排绘制 2 个 seaborn lmplots?

[英]How to plot 2 seaborn lmplots side-by-side?

Plotting 2 distplots or scatterplots in a subplot works great:在子图中绘制 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()

子图示例

But when I do the same with an lmplot instead of either of the other types of charts I get an error:但是,当我对lmplot而不是其他类型的图表执行相同操作时,会出现错误:

AttributeError: 'AxesSubplot' object has no attribute 'lmplot' AttributeError:“AxesSubplot”对象没有属性“lmplot”

Is there any way to plot these chart types side by side?有没有办法并排绘制这些图表类型?

You get that error because matplotlib and its objects are completely unaware of seaborn functions.您会收到该错误,因为 matplotlib 及其对象完全不知道 seaborn 函数。

Pass your axes objects (ie, ax1 and ax2 ) to seaborn.regplot or you can skip defining those and use the col kwarg of seaborn.lmplot将您的轴对象(即ax1ax2 )传递给seaborn.regplot或者您可以跳过定义这些对象并使用 seaborn.lmplot 的col seaborn.lmplot

With your same imports, pre-defining your axes and using regplot looks like this:使用相同的导入,预定义轴并使用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)

在此处输入图像描述

Using lmplot requires your dataframe to be tidy .使用 lmplot 需要您的数据框整洁 Continuing from the code above:继续上面的代码:

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)

在此处输入图像描述

If the intention of using lmplot is to use hue for two different sets of variables, regplot may not be sufficient without some tweaks.如果使用lmplot的目的是为两组不同的变量使用hueregplot可能不足够,没有一些调整。 In order to use of seaborn's lmplot hue argument in two side-by-side plots, one possible solution is:为了在两个并排的图中使用 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

This function give result similar to lmplot (with hue option), but accepts the ax argument, necessary for creating a composite figure.此函数给出类似于lmplot的结果(带有hue选项),但接受ax参数,这是创建复合图形所必需的。 An example of usage is一个使用示例是

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()

使用色调变量的 regplots 示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM