无法绘制字典中的所有数据

时间:2018-02-24 11:29:12

标签: python python-3.x matplotlib

我试图学习如何使用matplotlib来绘制数据,因为我对此感兴趣,但我们在大学时没有正确地研究这个问题。我写了这个简单的程序来练习,但它的工作中途。该程序应该计算txt文件中每个字母的出现次数并将其绘制在图形中,但是当我尝试分析时,例如,“爱丽丝梦游仙境”这本书。 (我将它转换为txt)它停在字母J.我无法理解为什么,因为如果我尝试打印存储数据的字典,它就不会是空的。后续字母具有关联的数据,但matplotlib没有绘制它。我没有经验,如果我犯了一些粗略的错误,请原谅我。 这是代码:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
import string
import random
import ntpath

def select():
    #open the file dialog to select the file
    from tkinter.filedialog import askopenfilename
    filename = askopenfilename()

    return filename


def random_color():
    #generate a random color, not too light
    r = lambda: random.randint(0,200)
    color=('#%02X%02X%02X' % (r(),r(),r()))
    return color

def count(file):
    #generate the dictionary with all the occurrence of each letter
    count={}
    for line in file:
        for word in line.split():
            for character in word:
                if character.isalpha():
                    if character in count:
                        count[character]+=1
                    else:
                        count[character]=1

    return count  


def main():
    filename=select()
    file=open(filename,'r')
    dictionary=count(file)

    plt.bar(dictionary.keys(), dictionary.values(), 1, color=random_color())
    plt.xlabel('Letters')
    plt.ylabel('Occurrences')
    plt.title(ntpath.basename(filename))
    plt.axis([0, len(dictionary.keys()) , 0, max(dictionary.values())])
    plt.grid(True)
    plt.show()

    print(dictionary.keys())
    print(dictionary.values())

main()

这是我的输出: enter image description here

1 个答案:

答案 0 :(得分:0)

您可能有更新版本的matplotlib。我的1.5.1不支持直接使用分类变量2.1.0 does 所以这里有一种方法可以用艰难的方式绘制字典:

import matplotlib.pyplot as plt
from collections import OrderedDict
#the next two imports are only used to generate a sample dictionary
import random
import string

def main():
    #your file operations, generating the dictionary, we use instead random values
    dictionary = {x: random.randint(0, 1000) for x in string.ascii_letters}
    #print(dictionary)
    #sorting the dictionary
    ord_dict = OrderedDict(sorted(dictionary.items()))
    #print(ord_dict)
    #find out length of the x axis
    n = len(ord_dict.keys())
    fig = plt.figure()
    #create bar chart
    plt.bar(range(n), ord_dict.values(), align = "center")
    #make sure, all bars are visible
    plt.xlim(-1, n)
    #label bars with dictionary keys
    plt.xticks(range(n), ord_dict.keys(), size = "small")
    plt.xlabel('Letters')
    plt.ylabel('Occurrences')
    plt.title("random dictionary")
    plt.grid(True)
    plt.show()

main()

matplotlib 2.1中,您应该可以直接创建条形图,如:

plt.bar(ord_dict.keys(), ord_dict.values(), align = "center")

然后您应该能够省略标记x轴的步骤。但是我无法在不更新matplotlib库的情况下对此进行测试 并查看您的角色数量 - 您可能希望研究collections.Counter的功能。

P.S。:It's a bug,似乎将在2.2版中修复。在此期间,您可以通过在字典键中添加空格来解决您的问题,例如

import matplotlib.pyplot as plt
#the next two imports are only used to generate a sample dictionary
import random
import string

def main():
    #your file operations, generating the dictionary, we use instead random values
    dictionary = {x: random.randint(0, 1000) for x in string.ascii_letters}
    #add a whitespace to each letter to have at least two characters per category
    dictionary = {k + " ":v for k, v in dictionary.items()}
    plt.figure()
    #create bar chart
    plt.bar(dictionary.keys(), dictionary.values())
    plt.xlabel('Letters')
    plt.ylabel('Occurrences')
    plt.title("random dictionary")
    plt.grid(True)
    plt.show()

main()

请注意,您现在不需要有序词典,matplotlib 2.1。自动排序字典键。

matplotlib 2.2.0

更新: 即使类别标签只包含一个字母,该错误也不再存在,所有分类数据都会被绘制出来。但他们也删除了分类数据的自动字母排序(这是一件好事)。所以现在你必须使用有序字典或其他排序策略,否则你的字典数据将以半随机顺序显示。

import matplotlib.pyplot as plt
from collections import OrderedDict
#the next two imports are only used to generate a sample dictionary
import random
import string

def main():
    #your file operations, generating the dictionary; we use instead random values
    dictionary = {x: random.randint(0, 1000) for x in string.ascii_letters}
    #sorting the dictionary
    ord_dict = OrderedDict(sorted(dictionary.items()))
    #create two subplots for comparison
    fig, (ax1, ax2) = plt.subplots(1, 2, sharey = True)
    #original dictionary, not sorted
    ax1.bar(dictionary.keys(), dictionary.values(), align = "center")
    #ordered dictionary
    ax2.bar(ord_dict.keys(), ord_dict.values(), align = "center")

    ax1.set_title("unsorted dictionary")
    ax2.set_title("ordered dictionary")
    plt.show()

main()

输出 enter image description here