【问题标题】:Frequency diagram with matplotlib使用 matplotlib 的频率图
【发布时间】:2016-12-05 19:37:39
【问题描述】:

我正在尝试在 Python 中使用 matplotlib 自动生成频率图,以计算出现次数,而不必在 Excel 中手动绘制。但是,我无法像在 Excel 中那样制作尽可能相似的图表。 Matplotlib 可以做到这一点吗?

在 Excel 中:

代码:

#!/usr/bin/python

import numpy as np
import matplotlib.pyplot as plt
from numpy import *
import os
import sys
import csv
from random import randint

x = [6,0,0,26,0,0,0,0,5,0,7,0,12,12,0,0,0,3,0,5,5,0,10,4,3,5,1,0,2,0,0,1,0,8,0,3,7,1,0,0,0,1,1,0,0,0,0,0,7,16,0,0,0,5]


plt.hist(x)
plt.title("Frequency diagram")
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.show()

结果(可读性不如Excel,怎么才能和excel图一样):

【问题讨论】:

    标签: python excel matplotlib


    【解决方案1】:
    import numpy as np
    import matplotlib.pyplot as plt
    
    def make_hist(ax, x, bins=None, binlabels=None, width=0.85, extra_x=1, extra_y=4, 
                  text_offset=0.3, title=r"Frequency diagram", 
                  xlabel="Values", ylabel="Frequency"):
        if bins is None:
            xmax = max(x)+extra_x
            bins = range(xmax+1)
        if binlabels is None:
            if np.issubdtype(np.asarray(x).dtype, np.integer):
                binlabels = [str(bins[i]) if bins[i+1]-bins[i] == 1 else 
                             '{}-{}'.format(bins[i], bins[i+1]-1)
                             for i in range(len(bins)-1)]
            else:
                binlabels = [str(bins[i]) if bins[i+1]-bins[i] == 1 else 
                             '{}-{}'.format(*bins[i:i+2])
                             for i in range(len(bins)-1)]
            if bins[-1] == np.inf:
                binlabels[-1] = '{}+'.format(bins[-2])
        n, bins = np.histogram(x, bins=bins)
        patches = ax.bar(range(len(n)), n, align='center', width=width)
        ymax = max(n)+extra_y
    
        ax.set_xticks(range(len(binlabels)))
        ax.set_xticklabels(binlabels)
    
        ax.set_title(title)
        ax.set_xlabel(xlabel)
        ax.set_ylabel(ylabel)
        ax.set_ylim(0, ymax)
        ax.grid(True, axis='y')
        # http://stackoverflow.com/a/28720127/190597 (peeol)
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['bottom'].set_visible(False)
        ax.spines['left'].set_visible(False)
        # http://stackoverflow.com/a/11417222/190597 (gcalmettes)
        ax.xaxis.set_ticks_position('none')
        ax.yaxis.set_ticks_position('none')
        autolabel(patches, text_offset)
    
    def autolabel(rects, shift=0.3):
        """
        http://matplotlib.org/1.2.1/examples/pylab_examples/barchart_demo.html
        """
        # attach some text labels
        for rect in rects:
            height = rect.get_height()
            if height > 0:
                plt.text(rect.get_x()+rect.get_width()/2., height+shift, '%d'%int(height),
                         ha='center', va='bottom')
    
    x = [6,0,0,26,0,0,0,0,5,0,7,0,12,12,0,0,0,3,0,5,5,0,10,4,3,5,1,0,2,0,0,1,0,8,0,
         3,7,1,0,0,0,1,1,0,0,0,0,0,7,16,0,0,0,5,41]
    fig, ax = plt.subplots(figsize=(14,5))
    # make_hist(ax, x)
    # make_hist(ax, [1,1,1,0,0,0], extra_y=1, text_offset=0.1)
    make_hist(ax, x, bins=list(range(10))+list(range(10,41,5))+[np.inf], extra_y=6)
    plt.show()
    

    make_hist 尝试识别x 中的所有值是否都是整数。如果是这样,它使用基于整数的 bin 标签。例如,bin 标签10-14 表示范围[10, 14](含)。

    另一方面,如果x 包含浮点数,那么make_hist 将使用基于半开浮点数的bin 标签。例如,10-15 将表示半开范围 [10, 15)

    【讨论】:

    • 哇!谢谢,很多代码。但是,当我将列表的值更改为例如 x = [1,1,1,0,0,0] 时,图表显示不正确?是动态的吗?因为值会有所不同。
    • 我对@9​​87654334@ 的定义完全不同。也许再试一次。
    • 谢谢。但是,我想知道为什么它没有显示任何高于 35 的值?例如,是否可以将最后一列设为40+,其中 40 以上的值是其中的一部分?由于x 值可能会发生变化并且不是静态的。非常感谢您的帮助。
    • 要获得这些确切的标签,我认为您需要手动定义binsbinlabels。我已经编辑了帖子以显示如何。
    • 谢谢你!我真的很欣赏你的努力。但是,通过在列表中添加 41,它不会出现在图表中。是否可以将 0 推到左侧为其腾出空间?结果(dropbox.com/s/lsnf38svk6laydi/…)
    【解决方案2】:

    Matplotlib 确实支持样式。你可能更喜欢 ggplot 风格:

    plt.style.use('ggplot')
    

    还有许多其他预制样式,或者您可以创建自己的样式: http://matplotlib.org/users/style_sheets.html

    【讨论】:

      猜你喜欢
      • 2020-09-22
      • 2013-10-28
      • 1970-01-01
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-04
      • 2023-03-10
      相关资源
      最近更新 更多