如何向 seaborn FacetGrid 添加额外的绘图并指定颜色
How to add additional plots to a seaborn FacetGrid and specify colors
有没有办法创建一个 Seaborn 线图,所有的线都是灰色的,平均值是红色的?我正在尝试使用 relplot
来执行此操作,但我不知道如何将平均值与数据分开(而且似乎未绘制平均值?)。
制作可重现的数据框
np.random.seed(1)
n1 = 100
n2 = 10
idx = np.arange(0,n1*2)
x, y, cat, id2 = [], [], [], []
x1 = list(np.random.uniform(-10,10,n2))
for i in idx:
x.extend(x1)
y.extend(list(np.random.normal(loc=0, scale=0.5, size=n2)))
cat.extend(['A', 'B'][i > n1])
id2.append(idx[i])
id2 = id2 * n2
id2.sort()
df1 = pd.DataFrame(list(zip(id2, x, y, cat)),
columns =['id2', 'x', 'y', 'cat']
)
密谋尝试
g = sns.relplot(
data=df1, x='x', y='y', hue='id2',
col='cat', kind='line',
palette='Greys',
facet_kws=dict(sharey=False,
sharex=False
),
legend=False
)
- 这取决于想要的结果。
seaborn.relplot
文档有一个 fmri
数据集的示例,它仅显示 mean
和 ci
,因此结果取决于您如何设置 hue
和event
个参数。
- 要为所有线条指定单一颜色,请使用
units
而不是 hue
或 style
(如 mwaskom 所指出的),然后设置 color='grey'
.
- 对于本OP的要求,接受的答案是最好的选择。但是,在需要从不是用于创建
relplot
的 data
的来源添加数据的情况下,此解决方案可能更合适,因为它允许访问每个 axes
图,并从 不同 数据源添加 something。
import seaborn as sns
import pandas as pd
# load and select data only where event is stim
fm = sns.load_dataset('fmri').query("event == 'stim'")
# groupby to get the mean for each region by timepoint
fmg = fm.groupby(['region', 'timepoint'], as_index=False).signal.mean()
# plot the fm dataframe
g = sns.relplot(data=fm, col='region', x='timepoint', y='signal',
units='subject', kind='line', ci=None, color='grey', estimator=None)
# extract and flatten the axes from the figure
axes = g.axes.flatten()
# iterate through each axes
for ax in axes:
# extract the region
reg = ax.get_title().split(' = ')[1]
# select the data for the region
data = fmg[fmg.region.eq(reg)]
# plot the mean line
sns.lineplot(data=data, x='timepoint', y='signal', ax=ax, color='red', label='mean', lw=3)
# fix the legends
axes[0].legend().remove()
axes[1].legend(title='Subjects', bbox_to_anchor=(1, 1), loc='upper left')
资源
- 另请参阅以下答案,了解将信息添加到 seaborn FacetGrid 的其他方法
我想你想在 relplot
的调用中使用 units
,然后使用 map
:
添加一层 lineplot
import seaborn as sns
import pandas as pd
fm = sns.load_dataset('fmri').query("event == 'stim'")
g = sns.relplot(
data=fm, kind='line',
col='region', x='timepoint', y='signal', units='subject',
estimator=None, color='.7'
)
g.data = fm # Hack needed to work around bug on v0.11, fixed in v0.12.dev
g.map(sns.lineplot, 'timepoint', 'signal', color='r', ci=None, lw=3)
我从 Seaborn's relplot: Is there a way to assign a specific color to all lines and another color to another single line when using the hue argument? 来到这里,post 不能到那里。
但我发现最简单的解决方案是简单地将 hue_order
和 palette
参数传递给 relplot
调用。见下文:
import seaborn as sbn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
sim = ['a'] * 100 + ['b'] * 100 + ['c'] * 100
var = (['u'] * 50 + ['v'] * 50)*3
x = np.linspace(0, 50, 50)
x = np.hstack([x]*6)
y = np.random.rand(300)
df = pd.DataFrame({'x':x, 'y':y, 'sim':sim, 'var':var})
hueOrder = ["a", "b", "c"] # Specifies the order for the palette
hueColor = ["r", "r", "b"] # Specifies the colors for the hueOrder (just make two the same color, and one different)
sbn.relplot(data=df, x='x', y='y', kind='line', col='var', hue='sim', hue_order=hueOrder, palette=hueColor)
plt.show()
这与接受的答案有点不同。但同样,我是从另一个已关闭的问题来到这里的。这也不使用任何 for 循环,应该更直接。
输出:
有没有办法创建一个 Seaborn 线图,所有的线都是灰色的,平均值是红色的?我正在尝试使用 relplot
来执行此操作,但我不知道如何将平均值与数据分开(而且似乎未绘制平均值?)。
制作可重现的数据框
np.random.seed(1)
n1 = 100
n2 = 10
idx = np.arange(0,n1*2)
x, y, cat, id2 = [], [], [], []
x1 = list(np.random.uniform(-10,10,n2))
for i in idx:
x.extend(x1)
y.extend(list(np.random.normal(loc=0, scale=0.5, size=n2)))
cat.extend(['A', 'B'][i > n1])
id2.append(idx[i])
id2 = id2 * n2
id2.sort()
df1 = pd.DataFrame(list(zip(id2, x, y, cat)),
columns =['id2', 'x', 'y', 'cat']
)
密谋尝试
g = sns.relplot(
data=df1, x='x', y='y', hue='id2',
col='cat', kind='line',
palette='Greys',
facet_kws=dict(sharey=False,
sharex=False
),
legend=False
)
- 这取决于想要的结果。
seaborn.relplot
文档有一个fmri
数据集的示例,它仅显示mean
和ci
,因此结果取决于您如何设置hue
和event
个参数。 - 要为所有线条指定单一颜色,请使用
units
而不是hue
或style
(如 mwaskom 所指出的),然后设置color='grey'
. - 对于本OP的要求,接受的答案是最好的选择。但是,在需要从不是用于创建
relplot
的data
的来源添加数据的情况下,此解决方案可能更合适,因为它允许访问每个axes
图,并从 不同 数据源添加 something。
import seaborn as sns
import pandas as pd
# load and select data only where event is stim
fm = sns.load_dataset('fmri').query("event == 'stim'")
# groupby to get the mean for each region by timepoint
fmg = fm.groupby(['region', 'timepoint'], as_index=False).signal.mean()
# plot the fm dataframe
g = sns.relplot(data=fm, col='region', x='timepoint', y='signal',
units='subject', kind='line', ci=None, color='grey', estimator=None)
# extract and flatten the axes from the figure
axes = g.axes.flatten()
# iterate through each axes
for ax in axes:
# extract the region
reg = ax.get_title().split(' = ')[1]
# select the data for the region
data = fmg[fmg.region.eq(reg)]
# plot the mean line
sns.lineplot(data=data, x='timepoint', y='signal', ax=ax, color='red', label='mean', lw=3)
# fix the legends
axes[0].legend().remove()
axes[1].legend(title='Subjects', bbox_to_anchor=(1, 1), loc='upper left')
资源
- 另请参阅以下答案,了解将信息添加到 seaborn FacetGrid 的其他方法
我想你想在 relplot
的调用中使用 units
,然后使用 map
:
lineplot
import seaborn as sns
import pandas as pd
fm = sns.load_dataset('fmri').query("event == 'stim'")
g = sns.relplot(
data=fm, kind='line',
col='region', x='timepoint', y='signal', units='subject',
estimator=None, color='.7'
)
g.data = fm # Hack needed to work around bug on v0.11, fixed in v0.12.dev
g.map(sns.lineplot, 'timepoint', 'signal', color='r', ci=None, lw=3)
我从 Seaborn's relplot: Is there a way to assign a specific color to all lines and another color to another single line when using the hue argument? 来到这里,post 不能到那里。
但我发现最简单的解决方案是简单地将 hue_order
和 palette
参数传递给 relplot
调用。见下文:
import seaborn as sbn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
sim = ['a'] * 100 + ['b'] * 100 + ['c'] * 100
var = (['u'] * 50 + ['v'] * 50)*3
x = np.linspace(0, 50, 50)
x = np.hstack([x]*6)
y = np.random.rand(300)
df = pd.DataFrame({'x':x, 'y':y, 'sim':sim, 'var':var})
hueOrder = ["a", "b", "c"] # Specifies the order for the palette
hueColor = ["r", "r", "b"] # Specifies the colors for the hueOrder (just make two the same color, and one different)
sbn.relplot(data=df, x='x', y='y', kind='line', col='var', hue='sim', hue_order=hueOrder, palette=hueColor)
plt.show()
这与接受的答案有点不同。但同样,我是从另一个已关闭的问题来到这里的。这也不使用任何 for 循环,应该更直接。
输出: