1

I am having difficulty getting plot.bar to group the bars together the way I have them grouped in the dataframe. The dataframe returns the grouped data correctly, however, the bar graph is providing a separate bar for every line int he dataframe. Ideally, everything in my code below should group 3-6 bars together for each department (Dept X should have bars grouped together for each type, then count of true/false as the Y axis).

Dataframe:

dname             Type  purchased
Dept X       0     False        141
                   True         270
             1     False       2020
                   True        2604
             2     False       2023
                   True        1047

Code:

import psycopg2
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

 ##connection and query data removed

df = pd.merge(df_departments[["id", "dname"]], df_widgets[["department", "widgetid", "purchased","Type"]], how='inner', left_on='id', right_on='department')
df.set_index(['dname'], inplace=True)
dx=df.groupby(['dname', 'Type','purchased'])['widgetid'].size()
dx.plot.bar(x='dname', y='widgetid', rot=90)

output from dataframe

ByRequest
  • 277
  • 2
  • 13

1 Answers1

1

I can't be sure without a more reproducible example, but try unstacking the innermost level of the MultiIndex of dx before plotting:

dx.unstack().plot.bar(x='dname', y='widgetid', rot=90)

I expect this to work because when plotting a DataFrame, each column becomes a legend entry and each row becomes a category on the horizontal axis.

Peter Leimbigler
  • 10,775
  • 1
  • 23
  • 37
  • Thanks for the suggestion. Unfortunately this errors out "KeyError: 'dname'". I'll look into the unstack functionality further. – ByRequest Mar 12 '19 at 13:20
  • @ByRequest, if you're still looking for a solution, I'd be curious to see the exact output (including whitespace) of `dx.head(10)`. – Peter Leimbigler Mar 12 '19 at 13:42
  • 1
    dname Type purchased Department1 0 False 141 True 270 1 False 2020 True 2604 2 False 2023 True 1047 Name: widgetid, dtype: int64 --I'll add this to an image at the top as well since I do not believe my formatting will be retained. Thanks! – ByRequest Mar 12 '19 at 14:07
  • Update - I played around a little bit more with Unstack() - it got me halfway there. I now have three groups within one department. So Departmentx, 0 gives me two bars for counts; Departmentx, 1 gives me two bars for counts - I just need the last piece to get all the bars together grouped by this particular department. Perhaps this is a syntax issue? As of right now what I am using is df.groupby(['sname','Type','purchased'])['widgetid'].size().unstack().plot(kind='bar',stacked=False) – ByRequest Mar 12 '19 at 14:19
  • 1
    I think the issue arises from having to plot a MultiIndex with three levels, whereas my `df.unstack().plot()` approach only works for two levels. This is where I hit my limit of knowledge about pandas/matplotlib plotting... Maybe this question and its linked question could be of help: https://stackoverflow.com/questions/34248741/plotting-pandas-multiindex-bar-chart – Peter Leimbigler Mar 12 '19 at 14:44