[英]How to add additional plots to a seaborn FacetGrid and specify colors
Is there a way to create a Seaborn line plot with all the lines gray and the mean as a red line?有没有办法创建一条 Seaborn 线 plot ,所有线均为灰色,平均值为红线? I'm trying to do this with relplot
but I don't know how to separate the mean from the data (and it appears the mean isn't being plotted?).我正在尝试使用relplot
来做到这一点,但我不知道如何将平均值与数据分开(而且似乎平均值没有被绘制?)。
Make reproducible data frame制作可重现的数据框
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']
)
Plotting attempt绘图尝试
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
)
I think you want units
in the call to relplot
and then add a layer of lineplot
using map
:我认为您希望调用relplot
中的units
,然后使用lineplot
添加一层线map
:
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.relplot
documentation has an example for the fmri
dataset that only shows the mean
and the ci
, so the result depends on how you set the hue
and event
parameters. seaborn.relplot
文档有一个fmri
数据集的示例,该示例仅显示mean
和ci
,因此结果取决于您如何设置hue
和event
参数。units
instead of hue
or style
(as pointed out by mwaskom ), and then set color='grey'
.要为所有线条指定单一颜色,请使用units
而不是hue
或style
(如mwaskom所指出的那样),然后设置color='grey'
。data
used to create the relplot
, this solution may be more appropriate, as it allows for accessing each axes
of the figure, and adding something from a different data source.但是,在需要从不是用于创建relplot
的data
的源中添加数据的情况下,此解决方案可能更合适,因为它允许访问图形的每个axes
,并添加来自不同数据源的内容。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')
I came here from 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?我是从Seaborn 的 relplot 来到这里的:有没有办法在使用 hue 参数时为所有线条分配一种特定的颜色,并为另一条线分配另一种颜色? and can't post there.并且不能在那里发帖。
But I find the simplest solution is to simply pass a hue_order
as well as a palette
argument to the relplot
call.但我发现最简单的解决方案是简单地将一个hue_order
和一个palette
参数传递给relplot
调用。 See below:见下文:
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()
This is a bit different then the accepted answer.这与接受的答案有点不同。 But again, I came here from another question that is closed.但是,我再次从另一个已关闭的问题来到这里。 This also doesn't use any for loops and should be more straight forward.这也不使用任何 for 循环,应该更直接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.