python - How to avoid pie chart labels overlapping in MatPlotLib ver.2.0.2? -
there lot of questions posted regarding labels overlap pie chart plotting. however, couldn't find automated solution except converting them legend. solution doesn't work me have lot of values (around 60), , conversion legend make plot messy , unclear. question, if want label pie wedges around pie, automated solution matplotlib version 2.0.2 enables labels have spacing (no overlapping) ? solution found manually annotation(). please see below script dummy values. possible connect wedge of pie related label arrow?
i use python 2.7 , matplotlib 2.0.2
thanks,
example 1 (overlapping labels)
example 2 (manually corrected)
import pylab import matplotlib.pyplot plt fig, ax = plt.subplots() l = ax.pie([1,0.2, 0.3,0.1,0.4,7,50,35,5,2],#[0, 0.1, 0, 0.1,0,0.1,0,0.1,0,0.1], #labels=("one","two","three made sentences","four ther","five becomes sentence","six is","seven long", "eight long sent", "nine, bla bel mo","ten short"), labels=("","","","","","six is","seven long", "eight long sent", "nine, bla bel mo","ten short"), colors=("b","g","r","y", "b","g","r","y","g","black"), startangle =20, radius=1, frame=true, # plot axes frame chart if true. labeldistance = 1.1 ) #returns list of matplotlib.patches.wedge objects l2 = ax.pie([1,0.2, 0.3,0.1,0.4,7,50,35,5,2],#[0, 0.1, 0, 0.1,0,0.1,0,0.1,0,0.1], colors=("r","g","b","w", "g","b","y","r","w","black"), startangle =20, radius=1-0.7, frame=true) # plot axes frame chart if true. coor = [t.get_position() t in l[1]] ax.axis('equal') plt.annotate( 'one short ext', xy= (coor[0][0], coor[0][1]) ) # https://kite.com/docs/python/matplotlib.pyplot.annotate plt.annotate( 'two long sentense', xy= (coor[1][0], coor[1][1]) ) plt.annotate('three things say' , xy= (coor[2][0], coor[2][1]+0.02) ) plt.annotate( 'four main tasks do', xy= (coor[3][0], coor[3][1]+0.04) ) plt.annotate( 'five reasons avoid', xy= (coor[4][0], coor[4][1]+0.06 )) plt.savefig('test_draft.pdf') plt.show()
you experiment rotating text. following determines angle each wedge , rotates annotation text accordingly. tweaks needed depending on angle determine text alignment , ensure text not appear upside down. might need further refine this.
import pylab import matplotlib.pyplot plt import math fig, ax = plt.subplots() labels= [ "one", "two", "three made sentences", "four there", "five becomes sentence", "six is", "seven long", "eight long sent", "nine, bla bel mo", "ten short"] l = ax.pie([1,0.2, 0.3,0.1,0.4,7,50,35,5,2], labels=[''] * len(labels), colors=("b","g","r","y", "b","g","r","y","g","black"), startangle=20, radius=1, frame=true, # plot axes frame chart if true. labeldistance=1.1) #returns list of matplotlib.patches.wedge objects l2 = ax.pie([1,0.2, 0.3,0.1,0.4,7,50,35,5,2],#[0, 0.1, 0, 0.1,0,0.1,0,0.1,0,0.1], colors=("r","g","b","w", "g","b","y","r","w","black"), startangle=20, radius=1-0.7, frame=true) # plot axes frame chart if true. label, t in zip(labels, l[1]): x, y = t.get_position() angle = int(math.degrees(math.atan2(y, x))) ha = "left" va = "bottom" if angle > 90: angle -= 180 if angle < 0: va = "top" if -45 <= angle <= 0: ha = "right" va = "bottom" plt.annotate(label, xy=(x,y), rotation=angle, ha=ha, va=va, size=8) ax.axis('equal') plt.show()
which display as:
Comments
Post a Comment