【问题标题】:seaborn distplot / displot with multiple distributionsseaborn distplot / displot 具有多个分布
【发布时间】:2018-02-13 04:55:33
【问题描述】:

我正在使用 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 ==0target ==1target ==2,总共有 3 个图。

【问题讨论】:

标签: python seaborn histogram density-plot


【解决方案1】:

重要的是按target012 的值对数据帧进行排序。

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)

【讨论】:

  • 这为我创建了单独的图(在 2021 年),也许它已经改变了
【解决方案2】:

解决此类问题的一种更常见的方法是使用 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))

【讨论】:

    【解决方案3】:

    citynormanhttps://github.com/mwaskom/seaborn/issues/861 上使用FacetGrid 找到了一个更简单的解决方案:

    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)
    

    【讨论】:

      【解决方案4】:

      一个更新更简单的选项:

      sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde')
      

      【讨论】:

        【解决方案5】:

        任何尝试使用新的 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 有所帮助。

        【讨论】:

        • 有没有办法将图例的值从 0、1、2 更改为其他值,而无需更改数据框本身的名称
        • 哦,这肯定是可能的,让我在答案中回答。
        • @RaghavArora 查看编辑后的答案,希望对您有所帮助。
        • 太棒了,谢谢
        【解决方案6】:

        如果有人希望获得 sns.distplot 的 facetgrid,则将其替换为图形级选项 sns.displot 和轴级函数 sns.histplot

        这使得使用pandas.DataFrame.melt将数据从宽格式(如OP中所示)转换为长格式变得非常容易

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

        这里的图片很小,但是如果你右键点击图片并在新的标签页或窗口中打开它,你可以更好地看到细节。

        【讨论】:

          猜你喜欢
          • 2020-12-02
          • 2018-02-11
          • 2021-11-26
          • 2015-05-25
          • 2020-09-26
          • 2021-02-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多