如何从宽数据框中使用 seaborn 绘制多个图

How to make multiple plots with seaborn from a wide dataframe

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

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

所以我有这个数据

指数 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

我想 barplots/histplots 将 col1、col2 .. col8 作为一列,将 1990 值作为一列,这样 1990;

col?
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,但可以让它适用于我的情况,欢迎任何反馈。

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

导入和测试 DataFrame

  • 使用 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

绘图
  • 使用seaborn 0.11.1正确的方式创建barplotFacetGrid (per the documentation), is with sns.catplotkind='bar'.
  • 需要将数据帧从宽格式转换为长格式,这很容易通过重置索引,然后使用 pandas.DataFrame.melt()
  • A catplot 是一个图形级界面,用于将分类图绘制到 FacetGrid 上。
    • g.set_xticklabels(rotation=90) 可用于旋转 xticklabels。
    • or
# 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, and then use pandas.DataFrame.plot[=56 转置数据框=]
# 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)