Why do the bar chart ticks merge into one when plotting dataframe but work when plotting row?

Viewed 119

I need to make a graph that would look like this:

The goal

Here's some sample data:

data = {"Small-Mid":367, "Large":0, "XXL":0, "FF":328, "AA":0, "Total":695} 
df = pd.DataFrame([data], columns=data.keys()) 

It's a dataframe that has only one row, if I try to plot the whole dataframe I get this ugly thing:

fig, ax = plt.subplots(figsize=(11.96, 4.42))
df.plot(kind="bar")
plt.show()

The ugly thing, two graphs, one empty the other one just wrong:

If I plot by selecting the row then it looks fine:

fig, ax = plt.subplots(figsize=(11.96, 4.42))
row = df.iloc[0]
row.plot(kind='bar')
plt.show()

A much nicer graph:

The issue is that I need the Total bar to be a different colour than the other bars and I can't do that when plotting the row, because it only accepts a single value rather than a dictionary for colours.

What I don't understand is why does it return two plots when plotting the whole dataframe and why are all the bars put as one tick mark, as well as how do I make it work?

1 Answers

You should re-shape your dataframe with pandas.melt:

df = pd.melt(frame = df,
             var_name = 'variable',
             value_name = 'value')

Then you can plot your bar chart with seaborn.barplot:

sns.barplot(ax = ax, data = df, x = 'variable', y = 'value')

Complete Code

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

data = {"Small-Mid":367, "Large":0, "XXL":0, "FF":328, "AA":0, "Total":695}
df = pd.DataFrame([data], columns=data.keys())

df = pd.melt(frame = df,
             var_name = 'variable',
             value_name = 'value')

fig, ax = plt.subplots(figsize=(11.96, 4.42))
sns.barplot(ax = ax, data = df, x = 'variable', y = 'value')
plt.show()

enter image description here

If you want only 'Total' column to be a different color from others, you can define a color-correspondence dictionary:

colors = {"Small-Mid":'blue', "Large":'blue', "XXL":'blue', "FF":'blue', "AA":'blue', "Total":'red'}

and pass it to seaborn as palette parameter:

sns.barplot(ax = ax, data = df, x = 'variable', y = 'value', palette = colors.values())

enter image description here

Related