python饼图 - 标注标签

时间:2017-06-28 12:51:07

标签: python pandas matplotlib pie-chart

我正在尝试按照此处的要求应用标注标签:Python PieChart (is it possible to do CallOut labels)

然而,我在尝试应用重叠标签时遇到了一些问题..任何想法......我是Python的初学者。

错误如        AttributeError:'list'对象没有属性'theta2'        TypeError:'function'对象不可迭代 AttributeError:'numpy.int64'对象没有属性'theta2'

这是我的代码:

    from collections import Counter
    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    import matplotlib.cm as cm, matplotlib.font_manager as fm
    import pandas as pd
    import csv
    import itertools
    from collections import OrderedDict
    import operator 


# Create database of duplicates - check if the mac and os pairs have duplicates
    reader = csv.reader(open('Workbook1.csv', 'r'), delimiter=',')
    writer = csv.writer(open('remacos.csv', 'w'), delimiter=',')
    entries = set()

    for row in reader:
        key = (row[1], row[2])

    if key not in entries:
        writer.writerow(row)
        entries.add(key)

    del writer #Force the writer to clean up



# Create database of duplicates - check if the mac and browser pairs have duplicates
    reader = csv.reader(open('Workbook1.csv', 'r'), delimiter=',')
    writer = csv.writer(open('remacbrowser.csv', 'w'), delimiter=',')
    entries = set()

    for row in reader:
    key = (row[1], row[3])

    if key not in entries:
        writer.writerow(row)
        entries.add(key)

    del writer #Force the writer to clean up


    df = pd.read_csv('remacos.csv', index_col="mac")         
    counteros = Counter(df['os'])
    os_names = counteros.keys()
    os_counts = counteros.values()

# Read Removed Duplicated entries Database and Count Values for Browsers.
    df = pd.read_csv('remacbrowser.csv', index_col="mac")         
    counterbrowsers = Counter(df['browser'])
    browser_names = counterbrowsers.keys()
    browser_counts = counterbrowsers.values()


#New Bar Chart with Fonts
    countdata = df['browser'].value_counts()
    ax = countdata.plot(kind='bar',                 
                        figsize=[9, 6], 
                        width=0.9, 
                        alpha=0.6, 
                        color='g',
                        edgecolor='w',
                        grid=False,
                        ylim=[0, 400])

    ax.set_xticks(range(len(countdata)))
    ax.set_xticklabels(countdata.index, rotation=45,  rotation_mode='anchor', ha='right', fontproperties=ticks_font)
    ax.yaxis.grid(True)
    for label in ax.get_yticklabels():
    label.set_fontproperties(ticks_font)

    ax.set_title('Most Popular Browsers', fontproperties=title_font)
    ax.set_xlabel('', fontproperties=label_font)
    ax.set_ylabel('Number of counts', fontproperties=label_font)

    plt.show()

# Make Pie Chart for Browsers
    plt.figure(figsize=plt.figaspect(1))
#values = sorted(browser_counts) 
#labels = browser_names

    labels, values = zip(*sorted(counterbrowsers.items(), key=lambda x: x[1])) #Counteros is the Dictionary-like object we are trying to sort. This 'zip' solves the problem of sorting each of them independently. This will sort as pairs, by value.
colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral', '#008DB8','#00AAAA','#001CF0','#00FF80', 'c','m','r','b', '#191970','#0038E2','#0055D4','#0071C6','#00E28E', '#00C69C']
#explode = (0, 0, 0, 0.1, 0.1, 0.2, 0.3, 0.4, 0.6)
explode = list()
    for k in labels:
       explode.append(0.1)
#sizes = counts.values.tolist()
    def make_autopct(values):
        def my_autopct(pct):
            total = sum(values)
            val=int(round(pct*total/100))
            return '{p:.2f}%  ({v:d})'.format(p=pct,v=val)
        return my_autopct

    pie = plt.pie(values, labels=labels, explode=explode, colors=colors,     shadow=True, startangle=90, autopct=make_autopct(values))

    bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
    arrowprops=dict(arrowstyle="-",connectionstyle="angle,angleA=0,angleB=90")
kw = dict(xycoords='data',textcoords='data',arrowprops=arrowprops, 
          bbox=bbox_props, zorder=0, va="center")

    for i, p in enumerate(pie):
        ang = (p.theta2 - p.theta1)/2.+p.theta1
        y = np.sin(ang/180.*np.pi)
        x = 1.35*np.sign(np.cos(ang/180.*np.pi))
        plt.gca().annotate(str(1+i), xy=(0, 0), xytext=( x, y), **kw )

    plt.legend(labels, loc="lower right")
    plt.axis('equal') # Set aspect ratio to be equal so that pie is drawn as a circle, # View the plot drop above
plt.title('Browsers Analytics', bbox={'facecolor':'0.8', 'pad':5})
plt.show()

CSV文件显示在如下表格中: 一个CSV将Mac地址与浏览器进行比较 其他CSV链接Mac和OS以获取计数数据。在饼图中,我只是试图让一个人表明我可以复制结果(希望如此)。

id                 mac              os         browser                                                1        fe:fe:fe:fe:fe:fe    Windows 10     Chrome 
2          fe:fe:fe:fe:fe:fe    Mac OS X       Chrome 
3          fe:fe:fe:fe:fe:fe    iPhone         Handheld Browser
5          37:02:e6:87:FF:77    Windows 8.1    Internet Explorer 

条形图只是显示数据的一种方式,但是在饼图中显示数据,其中标注是目标。我无法实现重叠/标注标签的解决方案。这里使用i,p在枚举(饼)中的值是我似乎得到像AttributeError这样的错误:'list'对象没有属性'theta2'

Traceback (most recent call last):
  File "csv-test.py", line 176, in <module>
    ang = (p.theta2 - p.theta1)/2.+p.theta1
AttributeError: 'list' object has no attribute 'theta2'

如果我将(pie)值更改为(counterbrowser),我会得到:

Traceback (most recent call last):
  File "csv-test.py", line 176, in <module>
    ang = (p.theta2 - p.theta1)/2.+p.theta1
AttributeError: 'str' object has no attribute 'theta2'

Patches = pie给我以下错误(用补丁替换(馅饼))

Traceback (most recent call last):
  File "csv-test.py", line 176, in <module>
    ang = (p.theta2 - p.theta1)/2.+p.theta1
AttributeError: 'list' object has no attribute 'theta2'

1 个答案:

答案 0 :(得分:0)

这只是正确输入解决方案的问题;你忘记了,texts部分 linked question的答案陈述

patches, texts = pie = plt.pie(total, startangle=5)
# ...
for i, p in enumerate(patches):
    # ...

如果激活了autopercentage,则需要3个值才能解压缩

patches, texts, autotexts = plt.pie(..., autopct=..)
# ...
    for i, p in enumerate(patches):
        # ...

另外,你当然可以不解开派对的回报并使用

pie = plt.pie(total, startangle=5)
# ...
for i, p in enumerate(pie[0]):
   # ...