1

I have two dataframes df1 and df2. df2 is subset of df1. I want to draw horizontal bar plot of df1 having identified df2 rows (different bar color or something). Thank you.

%matplotlib inline 
import pandas as pd
import matplotlib as plt

d1 = {
    'index' : [1, 2, 3, 4, 5], 
    'col1'  : [5, 8, 6, 4, 2]
}

d2 = {
    'index' : [3, 5], 
    'col1'  : [6, 2]
}

df1 = pd.DataFrame(d1).set_index(["index"])
df2 = pd.DataFrame(d2).set_index(["index"])

df1.plot(kind="barh", grid=False)
Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75
BoB
  • 129
  • 2
  • 9

2 Answers2

2

Unfortunately, pandas' barh function doesn't let us choose different colors for each bar. But since that seems to be the case, I would elect to not use pandas plotting function, but instead directly use matplotlib's function.

In this context, there are plenty of ways to achieve the desired result. Here is one option:

fig, ax = plt.subplots()
c = ['C2' if i in df2.index else 'C1' for i in df1.index]
ax.barh(y=df1.index,width=df1.col1,color=c)
ax.grid(False)

enter image description here

@GlobalTraveler 's answer made me think of another solution

df3 = df1.loc[df1.index.difference(df2.index)].append(df2, sort=False).sort_index()
df3.plot(kind='barh', stacked=True, grid=False)

The first line creates a new dataframe that has the following content:

    col1    col2
index       
1   5.0     NaN
2   8.0     NaN
3   NaN     6.0
4   4.0     NaN
5   NaN     2.0

plotting this dataframe produces the desired ouput. enter image description here

Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75
0

I think the way to go is to concatenate the dataframes and append nans for missing values

import pandas as pd
import matplotlib.pyplot as plt

d1 = {
    'index' : [1, 2, 3, 4, 5], 
    'col1'  : [5, 8, 6, 4, 2]
}

d2 = {
    'index' : [3, 5], 
    'col1'  : [6, 2]
}

df1 = pd.DataFrame(d1).set_index(["index"])
df2 = pd.DataFrame(d2).set_index(["index"])

plotThis = pd.concat([df1, df2], axis = 1, ignore_index = True)

plotThis.plot(kind = 'barh')
cvanelteren
  • 1,633
  • 9
  • 16