【问题标题】:How to make multiple plots with seaborn from a wide dataframe如何从宽数据框中使用 seaborn 制作多个图
【发布时间】:2021-08-08 04:19:29
【问题描述】:

我目前正在学习使用 seaborn 进行数据可视化,但遇到了一个我找不到解决方案的问题。

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

所以我有这个数据

index col1 col2 col3 col4 col5 col6 col7 col8
1990 0 4 7 3 7 0 6 6
1991 1 7 5 0 8 1 8 4
1992 0 5 0 1 9 1 7 2
1993 2 7 0 0 6 1 2 7
1994 4 1 5 5 8 1 6 3
1995 7 0 6 4 8 0 5 7
1996 5 1 1 4 6 1 7 4
1997 0 4 7 5 5 1 8 5
1998 1 3 7 0 7 0 7 1
1999 5 7 1 1 6 0 8 5
2000 3 8 5 0 3 0 6 3
2001 6 0 4 1 7 1 2 7

我想用 col1、col2 .. col8 作为一列和 1990 值作为一列来制作条形图/直方图,就像 1990;

col? val
col1 0
col2 4
col3 7
col4 3
col5 7
col6 0
col7 6
col8 6

并绘制从 1990 年到 2001 年的每一年。

g = sns.FacetGrid(df, col=df.index.value_counts())
g.map(sns.histplot, df.columns)

这是我写的代码 我查看了 facetgrid,但可以让它适用于我的情况,感谢任何反馈。

【问题讨论】:

    标签: python pandas matplotlib seaborn bar-chart


    【解决方案1】:

    导入和测试数据帧

    • pandas 1.3.0matplotlib 3.4.2seaborn 0.11.1 测试
    import pandas as pd
    import seaborn as sns
    
    # sample dataframe
    data = {1990: {'col1': 0, 'col2': 4, 'col3': 7, 'col4': 3, 'col5': 7, 'col6': 0, 'col7': 6, 'col8': 6}, 1991: {'col1': 1, 'col2': 7, 'col3': 5, 'col4': 0, 'col5': 8, 'col6': 1, 'col7': 8, 'col8': 4}, 1992: {'col1': 0, 'col2': 5, 'col3': 0, 'col4': 1, 'col5': 9, 'col6': 1, 'col7': 7, 'col8': 2}, 1993: {'col1': 2, 'col2': 7, 'col3': 0, 'col4': 0, 'col5': 6, 'col6': 1, 'col7': 2, 'col8': 7}, 1994: {'col1': 4, 'col2': 1, 'col3': 5, 'col4': 5, 'col5': 8, 'col6': 1, 'col7': 6, 'col8': 3}, 1995: {'col1': 7, 'col2': 0, 'col3': 6, 'col4': 4, 'col5': 8, 'col6': 0, 'col7': 5, 'col8': 7}, 1996: {'col1': 5, 'col2': 1, 'col3': 1, 'col4': 4, 'col5': 6, 'col6': 1, 'col7': 7, 'col8': 4}, 1997: {'col1': 0, 'col2': 4, 'col3': 7, 'col4': 5, 'col5': 5, 'col6': 1, 'col7': 8, 'col8': 5}, 1998: {'col1': 1, 'col2': 3, 'col3': 7, 'col4': 0, 'col5': 7, 'col6': 0, 'col7': 7, 'col8': 1}, 1999: {'col1': 5, 'col2': 7, 'col3': 1, 'col4': 1, 'col5': 6, 'col6': 0, 'col7': 8, 'col8': 5}, 2000: {'col1': 3, 'col2': 8, 'col3': 5, 'col4': 0, 'col5': 3, 'col6': 0, 'col7': 6, 'col8': 3}, 2001: {'col1': 6, 'col2': 0, 'col3': 4, 'col4': 1, 'col5': 7, 'col6': 1, 'col7': 2, 'col8': 7}}
    df = pd.DataFrame.from_dict(data, orient='index')
    
    # display(df.head())
          col1  col2  col3  col4  col5  col6  col7  col8
    1990     0     4     7     3     7     0     6     6
    1991     1     7     5     0     8     1     8     4
    1992     0     5     0     1     9     1     7     2
    1993     2     7     0     0     6     1     2     7
    1994     4     1     5     5     8     1     6     3
    

    使用seaborn.catplot 绘图

    # convert the wide dataframe to a long format with melt
    dfm = df.reset_index().melt(id_vars='index', var_name='variable', value_name='value')
    
    # display(dfm.head())
       index variable  value
    0   1990     col1      0
    1   1991     col1      1
    2   1992     col1      0
    3   1993     col1      2
    4   1994     col1      4
    
    # plot with catplot and kind='bar'
    g = sns.catplot(data=dfm, kind='bar', col='index', col_wrap=4, x='variable', y='value', height=3)
    
    # change the ticklabel rotation if needed
    g.set_xticklabels(rotation=90)
    
    # change ylim if needed
    g.set(ylim=(0, 30))
    

    使用pandas.DataFrame.plot 绘图

    • 虽然您已询问过seaborn,但鉴于 OP 中的数据框包含索引中的所有年份,绘制数据的最简单方法是使用 .T 转置数据框,然后使用 pandas.DataFrame.plot
    # display(df.T.head())
          1990  1991  1992  1993  1994  1995  1996  1997  1998  1999  2000  2001
    col1     0     1     0     2     4     7     5     0     1     5     3     6
    col2     4     7     5     7     1     0     1     4     3     7     8     0
    col3     7     5     0     0     5     6     1     7     7     1     5     4
    col4     3     0     1     0     5     4     4     5     0     1     0     1
    col5     7     8     9     6     8     8     6     5     7     6     3     7
    
    # transpose and plot
    axes = df.T.plot(kind='bar', subplots=True, layout=[3, 4], figsize=(15, 7), legend=False, rot=0)
    
    # to change ylim of the subplots, if needed
    for ax in axes.flatten():
        ax.set_ylim(0, 30)
    

    【讨论】:

    • 对不起,回复晚了,非常感谢,我还处于需要解释一切的阶段,你的帖子比我想象的任何事情都清楚。再次非常感谢您
    【解决方案2】:

    melt你的数据框优先。

    df = pd.DataFrame({'index': {0: 1990, 1: 1991, 2: 1992, 3: 1993, 4: 1994, 5: 1995, 6: 1996, 7: 1997, 8: 1998, 9: 1999, 10: 2000, 11: 2001}, 'col1': {0: 0, 1: 1, 2: 0, 3: 2, 4: 4, 5: 7, 6: 5, 7: 0, 8: 1, 9: 5, 10: 3, 11: 6}, 'col2': {0: 4, 1: 7, 2: 5, 3: 7, 4: 1, 5: 0, 6: 1, 7: 4, 8: 3, 9: 7, 10: 8, 11: 0}, 'col3': {0: 7, 1: 5, 2: 0, 3: 0, 4: 5, 5: 6, 6: 1, 7: 7, 8: 7, 9: 1, 10: 5, 11: 4}, 'col4': {0: 3, 1: 0, 2: 1, 3: 0, 4: 5, 5: 4, 6: 4, 7: 5, 8: 0, 9: 1, 10: 0, 11: 1}, 'col5': {0: 7, 1: 8, 2: 9, 3: 6, 4: 8, 5: 8, 6: 6, 7: 5, 8: 7, 9: 6, 10: 3, 11: 7}, 'col6': {0: 0, 1: 1, 2: 1, 3: 1, 4: 1, 5: 0, 6: 1, 7: 1, 8: 0, 9: 0, 10: 0, 11: 1}, 'col7': {0: 6, 1: 8, 2: 7, 3: 2, 4: 6, 5: 5, 6: 7, 7: 8, 8: 7, 9: 8, 10: 6, 11: 2}, 'col8': {0: 6, 1: 4, 2: 2, 3: 7, 4: 3, 5: 7, 6: 4, 7: 5, 8: 1, 9: 5, 10: 3, 11: 7}})
    df2 = df.melt(id_vars='index')
    
    g = sns.FacetGrid(data=df2, col='index', col_wrap=4)
    g.map(sns.barplot, 'variable', 'value', order=df2['variable'].unique())
    plt.show()
    

    【讨论】:

    • 嘿@Brendan 这非常感谢,但你能告诉我哪个变量在做什么,尤其是'variable''value'。我试过degrees = 90 plt.xticks(rotation=degrees),但它只适用于最后一张图。提前谢谢
    • @nasc 'variable''value' 是来自 melt 的默认名称;您可能应该将它们重命名为更合理的名称。
    • 我确实尝试过类似的方法,但出现了 keyerror,是否有其他方法可以更改名称
    猜你喜欢
    • 2021-01-16
    • 2021-11-09
    • 2021-03-09
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 2017-08-10
    相关资源
    最近更新 更多