I would like to make use of the stacked bar plot feature of pandas DataFrames. However, I would like to follow up by modifying the bars which were just plotted. For that, I need access to their graphics handles. But all I get back from df.plot() is an axis handle. How do I get a list of what was specifically created in a particular call? This would be necessary, for instance, if there were preexisting objects in the same axes from an earlier plot, and I wanted to differentiate, ie to treat just the new ones. Here is my code which plots twice to the same axis. I would like to end up having the stacked bars clustered next to each other, so I thought I could just make them a little narrower and shift them right and left. But for that I would need handles of what was made in the second call.
import random
import pandas as pd
import numpy as np
from pylab import *
close('all')
df = pd.DataFrame(np.random.random((7, 5)) * 10,
index=list('abcdefg'), columns=list('ABCDE'))
print df
ax = df.plot(kind='bar', stacked=True, align='center')
c1=ax.containers
hh=findobj(ax,lambda xx:hasattr(xx,'width'))
setp(hh,'width',.3)
print hh
df2= pd.DataFrame(np.random.random((6, 5)) * 10,
index=list('abcdef'), columns=list('FGHIJ'))
ax2 = df2.plot(kind='bar', stacked=True, align='center', ax=ax,colormap='bone')
c2=ax2.containers
print ax==ax2 # Should be true
c1==c2 # Should be False
show()
I have tried to get the list of containers ax.containers after the first call, and then again after the second, and taking the set difference, but this didn't work.
You're looking for the patches attribute of axes. You can get the original x positions with [p.get_x() for p in ax.patches]. This gives the left endpoint for each patch.
You'll want to add or subtract some value to each of the patches. Something like: new_xs = [p.get_x() - .5 for p in ax.patches]. And then set_x to the new values:
>>>for p, x in zip(ax.patches, new_xs):
p.set_x(x)
You'll also probably need to spread the x_ticks out more, or make the width of each patch smaller with p.set_width(). It may just be easier to do it all through matplotlib, rather than trying to adjust what pandas gives back.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With