如何避免标签重叠在matplotlib饼图中的autopct?

时间:2014-05-10 05:37:22

标签: python numpy matplotlib plot pie-chart

我的Python代码是:

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()

是否可以显示标签" Jan"," 2月"," 3月"等等以及百分比:

  • 没有重叠,或
  • 使用arrow mark

piechart

3 个答案:

答案 0 :(得分:30)

或者,您可以将图例放在饼图旁边:

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


编辑:如果您想按原始顺序保留图例,正如您在评论中提到的那样,您可以在上面的代码中设置sort_legend=False,并提供:

enter image description here

答案 1 :(得分:0)

尝试紧缩布局。

plt.tight_layout()
在代码末尾的

。可能会稍微防止重叠。

答案 2 :(得分:0)

首先; avoid pie charts whenever you can!

其次,想一想对象在 Python 中是如何工作的。我相信这个例子应该是不言自明的,但是,您显然不需要手动移动标签。

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 = texts[1]._x-0.5
texts[1]._y = texts[1]._y+0.5

# E.g. change some formatting
texts[-1]._color = 'blue'



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

# prints: {'_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