Plot a side by side bar charts with sharing only Y-axis

Viewed 389

How to plot a side by side bar charts from multiple dataframe with the same Y-axis?

from matplotlib import pyplot as plt
import pandas as pd

fruits = {"Apple": 10, "Banana": 9, "Mango": 5, "Orange": 1}
beverages = {"Coca-cola": 15, "Pepsi": 12, "Seven-up": 9, "Root-bear": 3}
foods = {'hamburger': 10, 'pizza': 7, 'pasta': 5, 'sushi': 2}

fruits_df = pd.DataFrame(fruits.items(), columns = ['stuffs', 'freq'])
beverages_df = pd.DataFrame(beverages.items(), columns = ['stuffs', 'freq'])
foods_df = pd.DataFrame(foods.items(), columns = ['stuffs', 'freq'])

# initialize a figure
fig=plt.figure(figsize=(18, 6))
plt.subplots_adjust(hspace = 2)

ax1 = fig.add_subplot(221)
fruits_df.head(8).plot(x='stuffs', y='freq', kind='bar', ax=ax1, legend=False).set_title('fruits')
plt.xticks(rotation=45, ha='right')

ax2 = fig.add_subplot(222)
beverages_df.head(8).plot(x='stuffs', y='freq', kind='bar', ax=ax2, legend=False, color="orange").set_title('beverage')
plt.xticks(rotation=45, ha='right')

ax2 = fig.add_subplot(223)
foods_df.head(8).plot(x='stuffs', y='freq', kind='bar', ax=ax2, legend=False, color="blue").set_title('foods')
plt.xticks(rotation=45, ha='right')

enter image description here

My desired output is following. I'm planning to add three or more dataframes on it like snacks, costumes and etc... please help

enter image description here

2 Answers

Using plt.subplots(..., sharey=True) might do the trick.

from matplotlib import pyplot as plt
import pandas as pd

fruits = {"Apple": 10, "Banana": 9, "Mango": 5, "Orange": 1}
beverages = {"Coca-cola": 15, "Pepsi": 12, "Seven-up": 9, "Root-bear": 3}
foods = {'hamburger': 10, 'pizza': 7, 'pasta': 5, 'sushi': 2}

fruits_df = pd.DataFrame(fruits.items(), columns = ['stuffs', 'freq'])
beverages_df = pd.DataFrame(beverages.items(), columns = ['stuffs', 'freq'])
foods_df = pd.DataFrame(foods.items(), columns = ['stuffs', 'freq'])

# initialize a figure
fig, axes = plt.subplots(1, 3, figsize=(18, 6), sharey=True)
ax1, ax2, ax3 = axes
fruits_df.plot(x='stuffs', y='freq', kind='bar', ax=ax1, legend=False).set_title('fruits')
beverages_df.plot(x='stuffs', y='freq', kind='bar', ax=ax2, legend=False, color="orange").set_title('beverage')
foods_df.plot(x='stuffs', y='freq', kind='bar', ax=ax3, legend=False, color="blue").set_title('foods')

for ax in axes:
    ax.set_xticklabels(ax.get_xticklabels(), rotation = 45)
    for side in ('right', 'top', 'left'):
        if (ax == ax1) and (side == 'left'):
            continue
        else:
            sp = ax.spines[side]
            sp.set_visible(False)

enter image description here

You can concatenate all dataframe together through:

fruits_df['type'] = 'fruit'
beverages_df['type'] = 'beverages'
foods_df['type'] = 'foods'

df = pd.concat([fruits_df, beverages_df, foods_df], ignore_index = True)

and then you can use seaborn.barplot and pass the parameter hue = 'type':

fig, ax = plt.subplots(figsize = (18, 6))

sns.barplot(ax = ax, data = df, x = 'stuffs', y = 'freq', hue = 'type', dodge = False)

plt.show()

Complete Code

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


fruits = {"Apple": 10, "Banana": 9, "Mango": 5, "Orange": 1}
beverages = {"Coca-cola": 15, "Pepsi": 12, "Seven-up": 9, "Root-bear": 3}
foods = {'hamburger': 10, 'pizza': 7, 'pasta': 5, 'sushi': 2}

fruits_df = pd.DataFrame(fruits.items(), columns = ['stuffs', 'freq'])
beverages_df = pd.DataFrame(beverages.items(), columns = ['stuffs', 'freq'])
foods_df = pd.DataFrame(foods.items(), columns = ['stuffs', 'freq'])

fruits_df['type'] = 'fruit'
beverages_df['type'] = 'beverages'
foods_df['type'] = 'foods'

df = pd.concat([fruits_df, beverages_df, foods_df], ignore_index = True)


fig, ax = plt.subplots(figsize = (18, 6))

sns.barplot(ax = ax, data = df, x = 'stuffs', y = 'freq', hue = 'type', dodge = False)

plt.show()

enter image description here

Related