【问题标题】:producing histogram with y axis as relative frequency?生成以y轴为相对频率的直方图?
【发布时间】:2015-10-13 03:54:55
【问题描述】:

今天我的任务是生成一个直方图,其中 y 轴是相对频率,而不仅仅是绝对计数。我找到了另一个关于此的问题(请参阅:Setting a relative frequency in a matplotlib histogram)但是,当我尝试实现它时,我收到错误消息:

'list' object has no attribute size

尽管答案中给出了完全相同的代码——尽管它们的信息也存储在一个列表中。

另外,我尝试了这里的方法(http://www.bertplot.com/visualization/?p=229),但没有成功,因为输出仍然没有显示 y 标签从 0 到 1。

import numpy as np
import matplotlib.pyplot as plt
import random
from tabulate import tabulate
import matplotlib.mlab as mlab

precision = 100000000000

def MarkovChain(n,s) :
    """

  """
    matrix = []
    for l in range(n) :
        lineLst = []
        sum = 0
        crtPrec = precision
        for i in range(n-1) :
            val = random.randrange(crtPrec)
            sum += val
            lineLst.append(float(val)/precision)
            crtPrec -= val
        lineLst.append(float(precision - sum)/precision)
        matrix2 = matrix.append(lineLst)

    print("The intial probability matrix.")    
    print(tabulate(matrix2))
    baseprob = []
    baseprob2 = []
    baseprob3 = []
    baseprob4 = []

    for i in range(1,s): #changed to do a range 1-s instead of 1000

        #must use the loop variable here, not s (s is always the same)
        matrix_n = np.linalg.matrix_power(matrix2, i)
        baseprob.append(matrix_n.item(0))
        baseprob2.append(matrix_n.item(1))
        baseprob3.append(matrix_n.item(2))

    baseprob = np.array(baseprob)
    baseprob2 = np.array(baseprob2)
    baseprob3 = np.array(baseprob3)
    baseprob4 = np.array(baseprob4)

    # Here I tried to make a histogram using the plt.hist() command, but the normed=True doesn't work like I assumed it would.
    '''    
  plt.hist(baseprob, bins=20, normed=True)
  plt.show()
  '''

    #Here I tried to make a histogram using the method from the second link in my post.
    # The code runs, but then the graph that is outputted isn't doesn't have the relative frequency on the y axis.
    '''
   n, bins, patches = plt.hist(baseprob, bins=30,normed=True,facecolor = "green",)
   y = mlab.normpdf(bins,mu,sigma)
   plt.plot(bins,y,'b-')
   plt.title('Main Plot Title',fontsize=25,horizontalalignment='right')
   plt.ylabel('Count',fontsize=20)
   plt.yticks(fontsize=15)
   plt.xlabel('X Axis Label',fontsize=20)
   plt.xticks(fontsize=15)
   plt.show()
   '''
    # Here I tried to make a histogram using the method seen in the Stackoverflow question I mentioned.
    # The figure that pops out looks correct in terms of the axes, but no actual data is posted. Instead the error below is shown in the console.
    # AttributeError: 'list' object has no attribute 'size'


    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.hist(baseprob, weights=np.zeros_like(baseprob)+1./ baseprob.size)
    n, bins, patches = ax.hist(baseprob, bins=100, normed=1, cumulative=0)
    ax.set_xlabel('Bins', size=20)
    ax.set_ylabel('Frequency', size=20)
    ax.legend
    plt.show()


    print("The final probability matrix.")
    print(tabulate(matrix_n))
    matrixTranspose = zip(*matrix_n)
    evectors = np.linalg.eig(matrixTranspose)[1][:,0]
    print("The steady state vector is:")
    print(evectors)






MarkovChain(5, 1000)

我尝试的方法都被注释掉了,所以要重现我的错误,请确保删除注释标记。

如您所知,我对编程真的很陌生。此外,这用于计算机科学课程的家庭作业,因此仅向我提供代码没有道德问题。

【问题讨论】:

    标签: python matplotlib statistics histogram


    【解决方案1】:

    matplotlib 函数的预期输入通常是 numpy 数组,其中包含方法 nparray.size。列表没有 size 方法,因此当在 hist 函数中调用 list.size 时,这会导致您的错误。您需要使用nparray = np.array(list) 进行转换。您可以在使用 append 构建列表的循环之后执行此操作,例如,

    baseprob = []
    baseprob2 = []
    baseprob3 = []
    baseprob4 = []
    
    for i in range(1,s): #changed to do a range 1-s instead of 1000
    
     #must use the loop variable here, not s (s is always the same)
         matrix_n = numpy.linalg.matrix_power(matrix, i)
         baseprob.append(matrix_n.item(0))
         baseprob2.append(matrix_n.item(1))
         baseprob3.append(matrix_n.item(2))
    
     baseprob = np.array(baseprob)
     baseprob2 = np.array(baseprob2)
     baseprob3 = np.array(baseprob3)
     baseprob4 = np.array(baseprob4)
    

    编辑:最小历史示例

    import numpy as np
    import matplotlib.pyplot as plt
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    baseprob = np.random.randn(1000000)
    ax.hist(baseprob, weights=np.zeros_like(baseprob)+1./ baseprob.size, bins=100)
    n, bins, patches = ax.hist(baseprob, bins=100, normed=1, cumulative=0, alpha = 0.4)
    ax.set_xlabel('Bins', size=20)
    ax.set_ylabel('Frequency', size=20)
    ax.legend
    plt.show()
    

    给出,

    【讨论】:

    • 感谢您的回复!我尝试实现它,但出现错误:ValueError: input must be square array。根据控制台日志,在第41行失败,即:matrix_n = np.linalg.matrix_power(matrix2, i)我做错了什么?编辑:代码和输出的 pastebin 链接pastebin.com/WAHQfuYy
    • 我还注意到一些奇怪的事情:如果我在第 41 行将 matrix2 更改为 matrix,则会出现一个数字,但它根本不是正确的数字;它仍然将轴作为绝对计数而不是相对计数。图片链接:i.imgur.com/9xoTsHb.png
    • 您对matrix2 = matrix.append(lineLst) 的使用不正确。 append 方法将 lineLst 添加到列表 matrix 并且不返回任何内容。因此 matrix2 是空的......“正确”的分布应该是什么样的?高斯?我认为你需要简化你正在做的事情。例如,如果您调用plt.plot(baseprob),您会看到它在前几个值上波动并衰减到一个常数,因此您会得到一个大峰值(即数据的历史记录是正确的)。我添加了一个最小的 hist 示例。
    • normed 已弃用。您可以改用density。它使积分(不是总和)等于 1。
    猜你喜欢
    • 1970-01-01
    • 2015-10-11
    • 2014-05-09
    • 1970-01-01
    • 2013-02-05
    • 1970-01-01
    • 2021-03-03
    • 2015-08-27
    • 2019-12-17
    相关资源
    最近更新 更多