Reputation: 97
I have the following df:
test_df = pd.DataFrame({'name': ['a', 'b', 'c'], 'res1': [1,2,3], 'res2': [4,5,6]})
I would like to plot (ideally, in one chart) the data, so I can compare res1 with res2 separately for each row (each name).
I have tried to achieve something similar, but I suppose that there is a simpler and more elegant solution that would also allow me to have it all in one chart with name as a group on x-axis.
plt.subplot(1, 3, i+1)
sns.barplot(x=test_df.iloc[i,1:].index.tolist(), y=test_df.iloc[i,1:].values.tolist())
plt.title(test_df.iloc[i,0])
Upvotes: 1
Views: 3297
Reputation: 62413
seaborn.barplot
, or with just using pandas.DataFrame.plot
, which avoids the additional import..bar_label
, which is available with matplotlib 3.4.2
.matplotlib
.pandas 1.3.0
, matplotlib 3.4.2
, and seaborn 0.11.1
pandas.DataFrame.plot
x='name'
, or res1
and res2
as the index.import pandas as pd
test_df = pd.DataFrame({'name': ['a', 'b', 'c'], 'res1': [1,2,3], 'res2': [4,5,6]})
# display(test_df)
name res1 res2
0 a 1 4
1 b 2 5
2 c 3 6
# plot with 'name' as the x-axis
p1 = test_df.plot(kind='bar', x='name', rot=0)
# annotate each group of bars
for p in p1.containers:
p1.bar_label(p, fmt='%.1f', label_type='edge')
import pandas as pd
test_df = pd.DataFrame({'name': ['a', 'b', 'c'], 'res1': [1,2,3], 'res2': [4,5,6]})
# set name as the index and then Transpose the dataframe
test_df = test_df.set_index('name').T
# display(test_df)
name a b c
res1 1 2 3
res2 4 5 6
# plot and annotate
p1 = test_df.plot(kind='bar', rot=0)
for p in p1.containers:
p1.bar_label(p, fmt='%.1f', label_type='edge')
seaborn.barplot
pandas.DataFrame.melt
, and then use the hue
parameter.import pandas as pd
import seaborn as sns
test_df = pd.DataFrame({'name': ['a', 'b', 'c'], 'res1': [1,2,3], 'res2': [4,5,6]})
# melt the dataframe into a long form
test_df = test_df.melt(id_vars='name')
# display(test_df.head())
name variable value
0 a res1 1
1 b res1 2
2 c res1 3
3 a res2 4
4 b res2 5
# plot the barplot using hue; switch the columns assigned to x and hue if you want a, b, and c on the x-axis.
p1 = sns.barplot(data=test_df, x='variable', y='value', hue='name')
# add annotations
for p in p1.containers:
p1.bar_label(p, fmt='%.1f', label_type='edge')
x='variable', hue='name'
x='name', hue='variable'
Upvotes: 2
Reputation: 35155
The data could be formatted more easily, but it can be represented as a single graph by converting the data format to a vertical format and specifying a bar chart.
import pandas as pd
import seaborn as sns
test_df = pd.DataFrame({'name': ['a', 'b', 'c'], 'res1': [1,2,3], 'res2': [4,5,6]})
df = test_df.set_index('name').unstack().to_frame(name='values')
df.reset_index(inplace=True)
df.rename(columns={'level_0':'categ'}, inplace=True)
sns.barplot(x='name', y='values', hue='categ', data=df)
categ | name | values | |
---|---|---|---|
0 | res1 | a | 1 |
1 | res1 | b | 2 |
2 | res1 | c | 3 |
3 | res2 | a | 4 |
4 | res2 | b | 5 |
5 | res2 | c | 6 |
Upvotes: 2