Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This gist includes a function called stylable_groupby_boxplot() that receives a pandas dataframe object and the column you want to groupby and returns a dictionary that includes all the boxplot's parts just like the standard matplotlib boxplot function does.
from numpy.random import rand
import matplotlib.pyplot as plt
import pandas as pd
# 2 columns produces an array of 2 matplotlib.axes.AxesSubplot objects
df2 = pd.DataFrame(rand(10,2), columns=['Col1', 'Col2'] )
df2['X'] = pd.Series(['A','B','A','B','A','B','A','B','A','B'])
#1 column produces a single matplotlib.axes.AxesSubplot object
df1 = pd.DataFrame(rand(10), columns=['Col1'] )
df1['X'] = pd.Series(['A','B','A','B','A','B','A','B','A','B'])
def stylable_groupby_boxplot(df, by):
'''
If you plot only one column, boxplot returns a single AxesSubplot object.
If there are several columns, boxplot returns an array of several AxesSubplot objects.
'''
bp = df.boxplot(by=by, grid=False)
bptype = str(type(bp))
if bptype == "<class 'matplotlib.axes.AxesSubplot'>":
cl = bp.get_children()
cl=[item for item in cl if isinstance(item, matplotlib.lines.Line2D)]
bpdict = {}
groups = df.groupby(by).groups.keys()
for i in range(len(groups)):
bpdict[groups[i]] = {'boxes': [], 'caps': [], 'fliers': [], 'medians': [], 'whiskers': []}
bpdict[groups[i]]['boxes'] = [cl[4+8*i]]
bpdict[groups[i]]['caps'] = [cl[2+8*i], cl[3+8*i]]
bpdict[groups[i]]['fliers'] = [cl[6+8*i], cl[7+8*i]]
bpdict[groups[i]]['medians'] = [cl[5+8*i]]
bpdict[groups[i]]['whiskers'] = [cl[0+8*i], cl[1+8*i]]
else:
bpdict = {}
groups = df.groupby(by).groups.keys()
keys = range(len(bp))
for i in keys:
bpdict[keys[i]] = {}
cl = bp[i].get_children()
cl=[item for item in cl if isinstance(item, matplotlib.lines.Line2D)]
for j in range(len(groups)):
bpdict[keys[i]][groups[j]] = {'boxes': [], 'caps': [], 'fliers': [], 'medians': [], 'whiskers': []}
bpdict[keys[i]][groups[j]]['boxes'] = [cl[4+8*j]]
bpdict[keys[i]][groups[j]]['caps'] = [cl[2+8*j], cl[3+8*j]]
bpdict[keys[i]][groups[j]]['fliers'] = [cl[6+8*j], cl[7+8*j]]
bpdict[keys[i]][groups[j]]['medians'] = [cl[5+8*j]]
bpdict[keys[i]][groups[j]]['whiskers'] = [cl[0+8*j], cl[1+8*j]]
return bpdict
bp2 = stylable_groupby_boxplot(df2, by="X")
bp1 = stylable_groupby_boxplot(df1, by="X")
# 2 column styling
plt.suptitle("")
plt.setp(bp2[0]['A']['boxes'], color='blue')
plt.setp(bp2[0]['A']['medians'], color='red')
plt.setp(bp2[0]['A']['whiskers'], color='blue')
plt.setp(bp2[0]['A']['fliers'], color='blue')
plt.setp(bp2[0]['A']['caps'], color='blue')
plt.setp(bp2[0]['B']['boxes'], color='red')
plt.setp(bp2[0]['B']['medians'], color='blue')
plt.setp(bp2[0]['B']['whiskers'], color='red')
plt.setp(bp2[0]['B']['fliers'], color='red')
plt.setp(bp2[0]['B']['caps'], color='red')
plt.setp(bp2[1]['A']['boxes'], color='green')
plt.setp(bp2[1]['A']['medians'], color='purple')
plt.setp(bp2[1]['A']['whiskers'], color='green')
plt.setp(bp2[1]['A']['fliers'], color='green')
plt.setp(bp2[1]['A']['caps'], color='green')
plt.setp(bp2[1]['B']['boxes'], color='purple')
plt.setp(bp2[1]['B']['medians'], color='green')
plt.setp(bp2[1]['B']['whiskers'], color='purple')
plt.setp(bp2[1]['B']['fliers'], color='purple')
plt.setp(bp2[1]['B']['caps'], color='purple')
# 1 column styling
plt.suptitle("")
plt.setp(bp1['A']['boxes'], color='blue')
plt.setp(bp1['A']['medians'], color='red')
plt.setp(bp1['A']['whiskers'], color='blue')
plt.setp(bp1['A']['fliers'], color='blue')
plt.setp(bp1['A']['caps'], color='blue')
plt.setp(bp1['B']['boxes'], color='red')
plt.setp(bp1['B']['medians'], color='blue')
plt.setp(bp1['B']['whiskers'], color='red')
plt.setp(bp1['B']['fliers'], color='red')
plt.setp(bp1['B']['caps'], color='red')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.