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)

enter image description here

example 2 (manually corrected)

enter image description here

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:

pie rotated annotations


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -