Home > Back-end >  Plotting two counter objects on one with matplotlib
Plotting two counter objects on one with matplotlib

Time:02-24

I have two counter objects and I want to plot them onto one histogram. I have this code:

func1_list = ['intronic', 'exonic', 'intronic', 'intronic','exonic', 'intronic', 'intronic']
func2_list = ['intronic', 'intronic','exonic', 'intronic','intronic', 'intronic','exonic', 'intronic']

count1 = Counter(func1_list)
count2 = Counter(func2_list)


key1 = count1.keys()
key2 = count2.keys()

df = pd.DataFrame(count1,index=key1)
df2 = pd.DataFrame(count2,index=key2)

df.plot(kind='bar')
df2.plot(kind='bar')

plt.show()

The output looks like this:

enter image description here

Ideally the output should be an x-axis with four bars. Two should be grouped 'intronic', where each bar in intronic would be the number from func1_list and func2_list (which the legend should say), and then another group of two bars called exonic, where each bar in that group would be the number in func1_list and func2_list.

There's no error, but you can see that doesn't happen either, I think it's plotted the exact same list, twice. Could someone explain what I'm doing wrong?

CodePudding user response:

I ran your code. I turns out that df looks like

          intronic  exonic
intronic         5       2
exonic           5       2

and df2 is similar, just with 6 in the first column instead of 5. I'm not sure why each DataFrame would have two identical rows. I don't understand that behavior. However, it is then exactly the behavior of df.plot that there must be two ticks on the x-axis of your plot, labeled intronic and extronic (because these are the indices), and that there are two bars for each tick on the x-axis, labeled intronic and extronic (because these are the column names in the DataFrame). And since each call to df.plot returns a new set of axes, each bar plot is placed in a separate figure.

The solution therefore must be to put the two Counter-objects into the same DataFrame. This can be done by passing a list of the counters and giving them appropriate indices

df = pd.DataFrame([count1, count2], index=['func1_list', 'func2_list'])

This gives a DataFrame looking like

            intronic  exonic
func1_list         5       2
func2_list         6       2

The indices give the tick labels on the x-axis, and we want those to be intronic and extronic. That can be achieved by transposing the DataFrame

df = df.transpose()

Finally,

df.plot(kind='bar')
plt.tight_layout() # to make sure that x-axis labels are always shown fully
plt.show()

enter image description here

produces the desired outcome.

  • Related