使用 seaborn 绘图时,如何为色调参数指定多个变量?
Posted
技术标签:
【中文标题】使用 seaborn 绘图时,如何为色调参数指定多个变量?【英文标题】:How can I specify multiple variables for the hue parameters when plotting with seaborn? 【发布时间】:2020-06-07 12:29:01 【问题描述】:当使用 seaborn 时,有没有办法可以为 hue 参数包含多个变量(列)?问这个问题的另一种方法是如何在将数据绘制在单个 x,y 轴图上之前按多个变量对数据进行分组?
我想做类似下面的事情。但是目前我无法为 hue 参数指定两个变量。:
sns.relplot(x='#', y='Attack', hue=['Legendary', 'Stage'], data=df)
例如,假设我有一个如下所示的 pandas DataFrame,其中包含通过 this 教程获得的 Pokemon database。
我想在 x 轴上绘制 pokedex #,在 y 轴上绘制 Attack。但是,我希望数据按 Stage 和 Legendary 进行分组。使用 matplotlib,我编写了一个自定义函数,将数据框按 ['Legendary','Stage'] 分组,然后遍历每个组以进行绘图(请参见下面的结果)。尽管我的自定义功能按预期工作,但我希望这可以通过 seaborn 简单地实现。我猜肯定有其他人试图使用 seaborn 在单个图中可视化超过 3 个变量?
fig, ax = plt.subplots()
grouping_variables = ['Stage','Legendary']
group_1 = df.groupby(grouping_variables)
for group_1_label, group_1_df in group_1:
ax.scatter(group_1_df['#'], group_1_df['Attack'], label=group_1_label)
ax_legend = ax.legend(title=grouping_variables)
编辑1:
注意:在我提供的示例中,我仅按两个变量(例如:传奇和舞台)对数据进行了分组。但是,其他情况可能需要任意数量的变量(例如:5 个变量)。
【问题讨论】:
【参考方案1】:您可以利用 hue
接受列名或与您的数据长度相同的序列这一事实,列出要分配每个数据点的颜色类别。所以……
sns.relplot(x='#', y='Attack', hue='Stage', data=df)
... 与:
基本相同sns.relplot(x='#', y='Attack', hue=df['Stage'], data=df)
你通常不会使用后者,它只是为了达到同样的目的而需要更多的输入——除非你想动态地构建一个自定义序列:
sns.relplot(x='#', y='Attack', data=df,
hue=df[['Legendary', 'Stage']].apply(tuple, axis=1))
您构建通过hue
传递的序列的方式完全取决于您,唯一的要求是它必须与您的数据具有相同的长度,如果是类似数组,它必须是一维的,所以你不能只传递hue=df[['Legendary', 'Stage']]
,你必须以某种方式将这些列连接成一个。我选择tuple
作为最简单、最通用的方式,但如果你想对格式有更多的控制,请构建一个Series
的字符串。为了更好的可读性,我将它保存到一个单独的变量中,这样我就可以为它指定一个名称(将用作图例标题),但您不必:
hue = df[['Legendary', 'Stage']].apply(
lambda row: f"row.Legendary, row.Stage", axis=1)
hue.name = 'Legendary, Stage'
sns.relplot(x='#', y='Attack', hue=hue, data=df)
【讨论】:
【参考方案2】:要使用seaborn.relplot
的 hue,请考虑将所需的组连接到单个列中,然后在新变量上运行绘图:
def run_plot(df, flds):
# CREATE NEW COLUMN OF CONCATENATED VALUES
df['_'.join(flds)] = pd.Series(df.reindex(flds, axis='columns')
.astype('str')
.values.tolist()
).str.join('_')
# PLOT WITH hue
sns.relplot(x='#', y='Attack', hue='_'.join(flds), data=random_df, aspect=1.5)
plt.show()
plt.clf()
plt.close()
用随机数据演示
数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
### DATA
np.random.seed(22320)
random_df = pd.DataFrame('#': np.arange(1,501),
'Name': np.random.choice(['Bulbasaur', 'Ivysaur', 'Venusaur',
'Charmander', 'Charmeleon'], 500),
'HP': np.random.randint(1, 100, 500),
'Attack': np.random.randint(1, 100, 500),
'Defense': np.random.randint(1, 100, 500),
'Sp. Atk': np.random.randint(1, 100, 500),
'Sp. Def': np.random.randint(1, 100, 500),
'Speed': np.random.randint(1, 100, 500),
'Stage': np.random.randint(1, 3, 500),
'Legend': np.random.choice([True, False], 500)
)
图
run_plot(random_df, ['Legend', 'Stage'])
run_plot(random_df, ['Legend', 'Stage', 'Name'])
【讨论】:
【参考方案3】:在 seaborn 的 scatterplot()
中,您可以结合 hue=
和 style=
参数来为每种组合生成不同的标记和不同的颜色
示例(逐字取自the documentation):
tips = sns.load_dataset("tips")
ax = sns.scatterplot(x="total_bill", y="tip", data=tips)
ax = sns.scatterplot(x="total_bill", y="tip",
hue="day", style="time", data=tips)
【讨论】:
很好,但不是问题的主题。以上是关于使用 seaborn 绘图时,如何为色调参数指定多个变量?的主要内容,如果未能解决你的问题,请参考以下文章