Grouped Bar graph Pandas
Asked Answered
M

2

32

I have a table in a pandas DataFrame named df:

+--- -----+------------+-------------+----------+------------+-----------+
|avg_views| avg_orders | max_views   |max_orders| min_views  |min_orders |
+---------+------------+-------------+----------+------------+-----------+
| 23       | 123       |   135       | 500      |    3       |    1      |
+---------+------------+-------------+----------+------------+-----------+ 

What I am looking for now is to plot a grouped bar graph which shows me (avg, max, min) of views and orders in one single bar chart.

i.e on x axis there would be Views and orders separated by a distance and 3 bars of (avg, max, min) for views and similarly for orders.

I have attached a sample bar graph image, just to know how the bar graph should look.

just sample: green color should be for avg, yellow for max and pin Green color should be for avg, yellow for max and pink for avg.

I took the following code from setting spacing between grouped bar plots in matplotlib but it is not working for me:

plt.figure(figsize=(13, 7), dpi=300)

groups = [[23, 135, 3], [123, 500, 1]]
group_labels = ['views', 'orders']
num_items = len(group_labels)
ind = np.arange(num_items)
margin = 0.05
width = (1. - 2. * margin) / num_items

s = plt.subplot(1, 1, 1)
for num, vals in enumerate(groups):
    print 'plotting: ', vals
    # The position of the xdata must be calculated for each of the two data 
    # series.
    xdata = ind + margin + (num * width)
    # Removing the "align=center" feature will left align graphs, which is 
    # what this method of calculating positions assumes.
    gene_rects = plt.bar(xdata, vals, width)
s.set_xticks(ind + 0.5)
s.set_xticklabels(group_labels)

plotting: [23, 135, 3] ... ValueError: shape mismatch: objects cannot be broadcast to a single shape

Maggee answered 4/11, 2016 at 10:22 Comment(2)
Can you provide a minimal reproducible example?Desquamate
@Desquamate check, i have appended the codeMaggee
D
38

Using pandas:

import pandas as pd

groups = [[23,135,3], [123,500,1]]
group_labels = ['views', 'orders']

# Convert data to pandas DataFrame.
df = pd.DataFrame(groups, index=group_labels).T

# Plot.
pd.concat(
    [
        df.mean().rename('average'), 
        df.min().rename('min'), 
        df.max().rename('max')
    ],
    axis=1,
).plot.bar()

Result plot

Desquamate answered 4/11, 2016 at 11:32 Comment(3)
worked like a charm! only one question, this just gave me bar graph is there any way to actually put my value on the top of each bar. say lil above bar for max order can i give its value?Maggee
I'm afraid I don't know how to do that. Try this answer maybe...Desquamate
Or directly from the documentation (see autolabel).Desquamate
P
37

You should not have to modify your dataframe just to plot it in a certain way right ?

Use seaborn !

import seaborn as sns

sns.catplot(
    x="x",       # x variable name
    y="y",       # y variable name
    hue="type",  # group variable name
    data=df,     # dataframe to plot
    kind="bar",
)

source

Pandora answered 3/4, 2020 at 7:7 Comment(1)
And if you wonder how to change the figsize of a sns.catplot, use the height keyword to control the size and the aspect keyword to control the shape. SourceDidactic

© 2022 - 2024 — McMap. All rights reserved.