-1

I have made a histogram using 3 different pandas series. I wanted to label the groups of bars 1,2,and 3. I was unsuccessful in using xlabels to do this; technically it worked but the numbers 1,2,3 were not aligned properly with the bars.

I have decided to skip that and try annotating. Unfortunately, I figure out how to do it properly.

I tried using xlabels, unsuccessfully. Now I am trying annotation but I can't get more than one text to show on the graph.

Here is an example of what the data looks like Wr_Spr_Conv = [1,1,1,2,2,2,3,3,3,2,2,1,2,3...]

new2['Wr_Spr_Conv'].replace(0, pd.np.nan).dropna(inplace = True)
new2['Re_Spr_Conv'].replace(0, pd.np.nan).dropna(inplace = True)
new2['Ma_Spr_Conv'].replace(0, pd.np.nan).dropna(inplace = True)


plt.style.use('seaborn')
x_labels = [1,2,3]
fig, ax1 = plt.subplots(figsize=(10,10))

#ax1.spines['left'].set_position(('outward', 10))
#ax1.spines['bottom'].set_position(('outward', 10))
# Hide the right and top spines

ax1.spines['right'].set_visible(False)
ax1.spines['top'].set_visible(False)
ax1.spines['bottom'].set_visible(False)
ax1.spines['right'].set_visible(False)
nbins = 9
ax1.tick_params(bottom="off", top="off", left="off", right="off")
    ax1.hist([new2['Wr_Spr_Conv'],new2['Re_Spr_Conv'],new2['Ma_Spr_Conv']],nbins)
#ax1.set_xticks(3)
#ax1.set_xticks(3)
#ax1.set_xlim(right =3)
#ax1.set_xlim(left=0)
# Only show ticks on the left and bottom spines
#ax1.yaxis.set_ticks_position('left')
#ax1.xaxis.set_ticks_position('bottom')    
ax1.set_xticks(x_labels)
ax1.set_xlim(right=3)  # adjust the right leaving left unchanged
ax1.set_xlim(left=1)  # adjust the left leaving right unchanged
ax1.xaxis.set_major_locator(MaxNLocator(integer=True))
#ax1.annotate('Level 1',xy=(1,15))
Heath
  • 128
  • 1
  • 9
Moo10000
  • 115
  • 11
  • @Heath the difference is that here the OP wants a pre-defined number of bins, which is not simply done with `Wr_Spr_Conv.plot(kind='bar', align='center')`. – j-i-l Aug 28 '19 at 21:30
  • @jojo I think this answer should still work: https://stackoverflow.com/a/28931750/5982697 – Heath Aug 28 '19 at 21:33
  • @Heath if you can explain to me where in https://stackoverflow.com/questions/28931224/adding-value-labels-on-a-matplotlib-bar-chart/28931750#28931750 the number of bins is set (independent on the number of data points - so for example use 3 bins) then I'll also vote for a duplicate. – j-i-l Aug 28 '19 at 21:39
  • Ah I see, I think it is a bit different (they're putting the labels in different spots, on the axis vs above the bars). However independent of the bin count being set explicitly, the same method can be used to set the labels, which I understood as the main question the OP was looking to solve. Something like this: https://gist.github.com/heathhenley/2237984e43d5e751ce8d9b45d892a812 – Heath Aug 28 '19 at 22:12
  • It is true that I asked a similar question, however I deleted that post because I had written my question poorly. I am going to try the posted answer later – Moo10000 Aug 28 '19 at 22:51

1 Answers1

1

Assuming your Wr_Spr_Conv is a pandas.Series you can use value_counts and pyplot's bar method with the attribute align='center' to create a histogram with a pre-defined number of bins and centered labels.

Here is a minimal example:

import pandas as pd
from matplotlib import pyplot as plt

nbr_bins = 9
Wr_Spr_Conv = pd.Series( [1,1,1,2,2,5,9,2,7,7,2,3,3,3,2,2,1,2,3]) 
vc = Wr_Spr_Conv.value_counts(bins=nbr_bins)
plt.bar(vc.index.mid, vc.values, width=0.9*vc.index.length[0], align='center')
plt.gca().set_xticks(vc.index.mid)
plt.show()

And the result: enter image description here

This should get you started!

j-i-l
  • 10,281
  • 3
  • 53
  • 70
  • Will try with the dataset in the morning, much thanks ! – Moo10000 Aug 29 '19 at 02:24
  • @Moo10000 did this work for you? – j-i-l Aug 29 '19 at 15:25
  • It is close, now the bars are stacked, as opposed to next to each other. ` '`vc1 = new2['Wr_Spr_Conv'].value_counts() vc2= new2['Re_Spr_Conv'].value_counts() vc3 = new2['Ma_Spr_Conv'].value_counts() k=[vc1,vc2,vc3] # plt.bar(vc1.index,vc1.values, align='center') plt.bar(vc2.index, vc2.values, align = 'center') plt.bar(vc3.index, vc3.values, align = 'center') plt.gca().set_xticks(vc1.index) plt.show()`' I dont think I need 9 bins because the series only have 1,2,and 3 values. I am working – Moo10000 Aug 29 '19 at 16:29
  • I tried something else I found online in a post for grouped bar charts `vc1 = new2['Wr_Spr_Conv'].value_counts() vc2= new2['Re_Spr_Conv'].value_counts() vc3 = new2['Ma_Spr_Conv'].value_counts() r1 = np.arange(len(vc1)) r2 = [x + .25 for x in r1] r3 = [x + .25 for x in r2] k=[vc1,vc2,vc3] # plt.bar(r1,vc1.values, align='center') plt.bar(r2, vc2.values, align = 'center') plt.bar(r3, vc3.values, align = 'center') plt.gca().set_xticks(vc1.index) plt.show()` The first comment, everything was lined up, here the bars are all overlapping @jojo – Moo10000 Aug 29 '19 at 16:42
  • thanks for your help, learned a bit more about this plotting business – Moo10000 Aug 30 '19 at 20:34