Imports and Test DataFrame
- Tested with
pandas 1.3.0, matplotlib 3.4.2, and seaborn 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
Plotting with seaborn.catplot
- Using
seaborn 0.11.1, the correct way to create a barplot FacetGrid (per the documentation), is with sns.catplot and kind='bar'.
- It is required to convert the dataframe from a wide to long form, which is easily done by resetting the index, and then using
pandas.DataFrame.melt()
- A
catplot is a figure-level interface for drawing categorical plots onto a FacetGrid.
# 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))
![enter image description here]()
Plotting with pandas.DataFrame.plot
- While you have asked about
seaborn, given the dataframe in the OP with all the years in the index, the easiest way to plot the data is transpose the dataframe with .T, and then use 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)
![enter image description here]()