Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid overlapping of labels & autopct in a matplotlib pie chart?

My Python code is:

values = [234, 64, 54,10, 0, 1, 0, 9, 2, 1, 7, 7] months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',           'Jul','Aug','Sep','Oct', 'Nov','Dec']  colors = ['yellowgreen', 'red', 'gold', 'lightskyblue',            'white','lightcoral','blue','pink', 'darkgreen',            'yellow','grey','violet','magenta','cyan']  plt.pie(values, labels=labels, autopct='%1.1f%%', shadow=True,          colors=colors, startangle=90, radius=1.2)  plt.show() 

Is it possible to show the labels "Jan", "Feb", "Mar", etc. and the percentages, either:

  • without overlapping, or
  • using an arrow mark?

piechart

like image 257
Adithya Avatar asked May 10 '14 05:05

Adithya


People also ask

How do you stop data labels overlapping?

Stop Labels overlapping chartRight click on the Axis. Choose the Format Axis option. Open the Labels dropdown. For label position change it to 'Low'

How do you avoid overlapping labels in R?

To avoid overlapping by shifting labels downward we use n. dodge parameter of guide_axis() function: R.

How do I make labels not overlap in ArcMap?

Open the Properties dialog for the line layer, and choose the Labels > Placement option, then set a High value for the Feature Weight. This causes ArcMap to move those labels which would have overlapped the lines, or to omit drawing them where necessary.


2 Answers

Alternatively you can put the legends beside the pie graph:

import matplotlib.pyplot as plt import numpy as np  x = np.char.array(['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct', 'Nov','Dec']) y = np.array([234, 64, 54,10, 0, 1, 0, 9, 2, 1, 7, 7]) colors = ['yellowgreen','red','gold','lightskyblue','white','lightcoral','blue','pink', 'darkgreen','yellow','grey','violet','magenta','cyan'] porcent = 100.*y/y.sum()  patches, texts = plt.pie(y, colors=colors, startangle=90, radius=1.2) labels = ['{0} - {1:1.2f} %'.format(i,j) for i,j in zip(x, porcent)]  sort_legend = True if sort_legend:     patches, labels, dummy =  zip(*sorted(zip(patches, labels, y),                                           key=lambda x: x[2],                                           reverse=True))  plt.legend(patches, labels, loc='left center', bbox_to_anchor=(-0.1, 1.),            fontsize=8)  plt.savefig('piechart.png', bbox_inches='tight') 

enter image description here


EDIT: if you want to keep the legend in the original order, as you mentioned in the comments, you can set sort_legend=False in the code above, giving:

enter image description here

like image 158
Saullo G. P. Castro Avatar answered Sep 21 '22 06:09

Saullo G. P. Castro


First of all; avoid pie charts whenever you can!

Secondly, have a think about how objects work in python. I believe this example should be self-explaining, however, you obviously don't need to move labels manually.

from matplotlib import pyplot as plt  fig, ax = plt.subplots() ax.axis('equal')  patches, texts, autotexts = ax.pie([12,6,2,3],                                labels=['A', 'B', 'C', 'no data'],                               autopct='%1.1f%%',                                pctdistance=0.5,                                labeldistance=1.1)    # Move a label texts[1]._x =-0.5 texts[1]._y =+0.5  # E.g. change some formatting texts[-1]._color = 'blue' 

There are some options to modify the labels:

# Check all options print(texts[0].__dict__) 

returns

{'_stale': False,  'stale_callback': <function matplotlib.artist._stale_axes_callback(self, val)>,  '_axes': <AxesSubplot:>,  'figure': <Figure size 432x288 with 1 Axes>,  '_transform': <matplotlib.transforms.CompositeGenericTransform at 0x7fe09bedf210>,  '_transformSet': True,  '_visible': True,  '_animated': False,  '_alpha': None,  'clipbox': <matplotlib.transforms.TransformedBbox at 0x7fe065d3dd50>,  '_clippath': None,  '_clipon': False,  '_label': '',  '_picker': None,  '_contains': None,  '_rasterized': None,  '_agg_filter': None,  '_mouseover': False,  'eventson': False,  '_oid': 0,  '_propobservers': {},  '_remove_method': <function list.remove(value, /)>,  '_url': None,  '_gid': None,  '_snap': None,  '_sketch': None,  '_path_effects': [],  '_sticky_edges': _XYPair(x=[], y=[]),  '_in_layout': True,  '_x': -0.07506663683168735,  '_y': 1.097435647331897,  '_text': 'A',  '_color': 'black',  '_fontproperties': <matplotlib.font_manager.FontProperties at 0x7fe065d3db90>,  '_usetex': False,  '_wrap': False,  '_verticalalignment': 'center',  '_horizontalalignment': 'right',  '_multialignment': None,  '_rotation': 'horizontal',  '_bbox_patch': None,  '_renderer': <matplotlib.backends.backend_agg.RendererAgg at 0x7fe08b01fd90>,  '_linespacing': 1.2,  '_rotation_mode': None} 

enter image description here

like image 44
user2821 Avatar answered Sep 21 '22 06:09

user2821