seaborn distplot / 具有多个分布的 displot
seaborn distplot / displot with multiple distributions
我正在使用 seaborn 绘制分布图。我想在同一个图上用不同颜色绘制多个分布:
下面是我如何开始绘制分布图:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],columns= iris['feature_names'] + ['target'])
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0.0
1 4.9 3.0 1.4 0.2 0.0
2 4.7 3.2 1.3 0.2 0.0
3 4.6 3.1 1.5 0.2 0.0
4 5.0 3.6 1.4 0.2 0.0
sns.distplot(iris[['sepal length (cm)']], hist=False, rug=True);
'target'
列包含 3 个值:0、1、2。
我想看一个萼片长度分布图,其中 target ==0
、target ==1
和 target ==2
,总共 3 个图。
重要的是按 target
为 0
、1
或 2
.
的值对数据框进行排序
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns
iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
# Sort the dataframe by target
target_0 = iris.loc[iris['target'] == 0]
target_1 = iris.loc[iris['target'] == 1]
target_2 = iris.loc[iris['target'] == 2]
sns.distplot(target_0[['sepal length (cm)']], hist=False, rug=True)
sns.distplot(target_1[['sepal length (cm)']], hist=False, rug=True)
sns.distplot(target_2[['sepal length (cm)']], hist=False, rug=True)
plt.show()
输出如下:
如果您不知道 target
可能有多少个值,请在 target
列中找到唯一值,然后对数据帧进行切片并适当地添加到图中。
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns
iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
unique_vals = iris['target'].unique() # [0, 1, 2]
# Sort the dataframe by target
# Use a list comprehension to create list of sliced dataframes
targets = [iris.loc[iris['target'] == val] for val in unique_vals]
# Iterate through list and plot the sliced dataframe
for target in targets:
sns.distplot(target[['sepal length (cm)']], hist=False, rug=True)
解决此类问题的更常见方法是使用 melt 将数据重铸为长格式,然后让 map 完成其余工作。
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns
iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
# recast into long format
df = iris.melt(['target'], var_name='cols', value_name='vals')
df.head()
target cols vals
0 0.0 sepal length (cm) 5.1
1 0.0 sepal length (cm) 4.9
2 0.0 sepal length (cm) 4.7
3 0.0 sepal length (cm) 4.6
4 0.0 sepal length (cm) 5.0
您现在可以通过创建 FacetGrid 并使用地图简单地绘制:
g = sns.FacetGrid(df, col='cols', hue="target", palette="Set1")
g = (g.map(sns.distplot, "vals", hist=False, rug=True))
我通过 citynorman 找到了一个使用 FacetGrid on https://github.com/mwaskom/seaborn/issues/861 的更简单的解决方案:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],columns= iris['feature_names'] + ['target'])
g = sns.FacetGrid(iris, hue="target")
g = g.map(sns.distplot, "sepal length (cm)", hist=False, rug=True)
更新更简单的选项:
sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde')
任何试图使用新的 0.11.0 版本构建相同绘图的人,Seaborn 已经或正在弃用 distplot 并将其替换为 displot。
所以新版本的代码应该是:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns
iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde', fill=True, palette=sns.color_palette('bright')[:3], height=5, aspect=1.5)
编辑
正如 Raghav 在评论部分所问,我们可以在不更改数据框本身的情况下更改图表中的标签吗?是的,我们绝对可以。所以我们首先将绘图分配给一个名为 chart
的变量,然后执行以下操作:
chart = sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde', fill=True, palette=sns.color_palette('bright')[:3], height=5, aspect=1.5)
## Changing title
new_title = 'This is a NEW title'
chart._legend.set_title(new_title)
# Replacing labels
new_labels = ['label 1', 'label 2', 'label 3']
for t, l in zip(chart._legend.texts, new_labels):
t.set_text(l)
最终图表如下所示:
希望这对 Raghav 有所帮助。
如果有人想要获得 sns.distplot
的 facetgrid,它已被替换为图形级选项 sns.displot
, and an axes-level function, sns.histplot
这使得将数据从宽格式(如 OP 中所示)转换为长格式变得非常容易,方法是使用 pandas.DataFrame.melt
import pandas as pd
import seaborn as sns
iris = sns.load_dataset('iris')
# convert the dataframe from wide to long form
iris_melt = iris.melt(id_vars='species')
iris_melt.head()
species variable value
0 setosa sepal_length 5.1
1 setosa sepal_length 4.9
2 setosa sepal_length 4.7
3 setosa sepal_length 4.6
4 setosa sepal_length 5.0
sns.displot(
data=iris_melt,
x='value',
hue='species',
kind='kde',
fill=True,
col='variable'
)
这里的图片很小,但是如果你右击图片并在新标签页中打开或者window,你可以更好地看到细节。
我正在使用 seaborn 绘制分布图。我想在同一个图上用不同颜色绘制多个分布:
下面是我如何开始绘制分布图:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],columns= iris['feature_names'] + ['target'])
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0.0
1 4.9 3.0 1.4 0.2 0.0
2 4.7 3.2 1.3 0.2 0.0
3 4.6 3.1 1.5 0.2 0.0
4 5.0 3.6 1.4 0.2 0.0
sns.distplot(iris[['sepal length (cm)']], hist=False, rug=True);
'target'
列包含 3 个值:0、1、2。
我想看一个萼片长度分布图,其中 target ==0
、target ==1
和 target ==2
,总共 3 个图。
重要的是按 target
为 0
、1
或 2
.
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns
iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
# Sort the dataframe by target
target_0 = iris.loc[iris['target'] == 0]
target_1 = iris.loc[iris['target'] == 1]
target_2 = iris.loc[iris['target'] == 2]
sns.distplot(target_0[['sepal length (cm)']], hist=False, rug=True)
sns.distplot(target_1[['sepal length (cm)']], hist=False, rug=True)
sns.distplot(target_2[['sepal length (cm)']], hist=False, rug=True)
plt.show()
输出如下:
如果您不知道 target
可能有多少个值,请在 target
列中找到唯一值,然后对数据帧进行切片并适当地添加到图中。
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns
iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
unique_vals = iris['target'].unique() # [0, 1, 2]
# Sort the dataframe by target
# Use a list comprehension to create list of sliced dataframes
targets = [iris.loc[iris['target'] == val] for val in unique_vals]
# Iterate through list and plot the sliced dataframe
for target in targets:
sns.distplot(target[['sepal length (cm)']], hist=False, rug=True)
解决此类问题的更常见方法是使用 melt 将数据重铸为长格式,然后让 map 完成其余工作。
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns
iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
# recast into long format
df = iris.melt(['target'], var_name='cols', value_name='vals')
df.head()
target cols vals
0 0.0 sepal length (cm) 5.1
1 0.0 sepal length (cm) 4.9
2 0.0 sepal length (cm) 4.7
3 0.0 sepal length (cm) 4.6
4 0.0 sepal length (cm) 5.0
您现在可以通过创建 FacetGrid 并使用地图简单地绘制:
g = sns.FacetGrid(df, col='cols', hue="target", palette="Set1")
g = (g.map(sns.distplot, "vals", hist=False, rug=True))
我通过 citynorman 找到了一个使用 FacetGrid on https://github.com/mwaskom/seaborn/issues/861 的更简单的解决方案:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],columns= iris['feature_names'] + ['target'])
g = sns.FacetGrid(iris, hue="target")
g = g.map(sns.distplot, "sepal length (cm)", hist=False, rug=True)
更新更简单的选项:
sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde')
任何试图使用新的 0.11.0 版本构建相同绘图的人,Seaborn 已经或正在弃用 distplot 并将其替换为 displot。
所以新版本的代码应该是:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns
iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
columns=iris['feature_names'] + ['target'])
sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde', fill=True, palette=sns.color_palette('bright')[:3], height=5, aspect=1.5)
编辑
正如 Raghav 在评论部分所问,我们可以在不更改数据框本身的情况下更改图表中的标签吗?是的,我们绝对可以。所以我们首先将绘图分配给一个名为 chart
的变量,然后执行以下操作:
chart = sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde', fill=True, palette=sns.color_palette('bright')[:3], height=5, aspect=1.5)
## Changing title
new_title = 'This is a NEW title'
chart._legend.set_title(new_title)
# Replacing labels
new_labels = ['label 1', 'label 2', 'label 3']
for t, l in zip(chart._legend.texts, new_labels):
t.set_text(l)
最终图表如下所示:
希望这对 Raghav 有所帮助。
如果有人想要获得 sns.distplot
的 facetgrid,它已被替换为图形级选项 sns.displot
, and an axes-level function, sns.histplot
这使得将数据从宽格式(如 OP 中所示)转换为长格式变得非常容易,方法是使用 pandas.DataFrame.melt
import pandas as pd
import seaborn as sns
iris = sns.load_dataset('iris')
# convert the dataframe from wide to long form
iris_melt = iris.melt(id_vars='species')
iris_melt.head()
species variable value
0 setosa sepal_length 5.1
1 setosa sepal_length 4.9
2 setosa sepal_length 4.7
3 setosa sepal_length 4.6
4 setosa sepal_length 5.0
sns.displot(
data=iris_melt,
x='value',
hue='species',
kind='kde',
fill=True,
col='variable'
)
这里的图片很小,但是如果你右击图片并在新标签页中打开或者window,你可以更好地看到细节。