【问题标题】:python: plotting a histogram with a function line on toppython:绘制顶部带有函数线的直方图
【发布时间】:2012-07-04 03:56:17
【问题描述】:

我正在尝试在 Python 中使用 SciPy 进行统计数据和 matplotlib 进行绘图的一些分布绘图和拟合。我在创建直方图之类的事情上运气不错:

seed(2)
alpha=5
loc=100
beta=22
data=ss.gamma.rvs(alpha,loc=loc,scale=beta,size=5000)
myHist = hist(data, 100, normed=True)

太棒了!

我什至可以采用相同的 gamma 参数并绘制概率分布函数的线函数(经过一些谷歌搜索):

rv = ss.gamma(5,100,22)
x = np.linspace(0,600)
h = plt.plot(x, rv.pdf(x))

我将如何绘制直方图 myHist,并将 PDF 行 h 叠加在直方图顶部?我希望这是微不足道的,但我一直无法弄清楚。

【问题讨论】:

标签: python matplotlib scipy


【解决方案1】:

扩展 Malik 的答案,并尝试坚持使用 vanilla NumPy、SciPy 和 Matplotlib。我加入了 Seaborn,但它仅用于提供更好的默认设置和小的视觉调整:

import numpy as np
import scipy.stats as sps
import matplotlib.pyplot as plt

import seaborn as sns
sns.set(style='ticks')

# parameterise our distributions
d1 = sps.norm(0, 10)
d2 = sps.norm(60, 15)

# sample values from above distributions
y1 = d1.rvs(300)
y2 = d2.rvs(200)
# combine mixture
ys = np.concatenate([y1, y2])

# create new figure with size given explicitly
plt.figure(figsize=(10, 6))

# add histogram showing individual components
plt.hist([y1, y2], 31, histtype='barstacked', density=True, alpha=0.4, edgecolor='none')

# get X limits and fix them
mn, mx = plt.xlim()
plt.xlim(mn, mx)

# add our distributions to figure
x = np.linspace(mn, mx, 301)
plt.plot(x, d1.pdf(x) * (len(y1) / len(ys)), color='C0', ls='--', label='d1')
plt.plot(x, d2.pdf(x) * (len(y2) / len(ys)), color='C1', ls='--', label='d2')

# estimate Kernel Density and plot
kde = sps.gaussian_kde(ys)
plt.plot(x, kde.pdf(x), label='KDE')

# finish up
plt.legend()
plt.ylabel('Probability density')
sns.despine()

为我们提供了以下情节:

我尝试坚持使用最少的功能集,同时产生相对较好的输出,特别是使用 SciPy 估计 KDE 非常容易。

【讨论】:

    【解决方案2】:

    人们可能对绘制任何直方图的分布函数感兴趣。 这可以使用seaborn kde 函数来完成

    import numpy as np # for random data
    import pandas as pd  # for convinience
    import matplotlib.pyplot as plt  # for graphics
    import seaborn as sns  # for nicer graphics
    
    v1 = pd.Series(np.random.normal(0,10,1000), name='v1')
    v2 = pd.Series(2*v1 + np.random.normal(60,15,1000), name='v2')
    
    # plot a kernel density estimation over a stacked barchart
    plt.figure()
    plt.hist([v1, v2], histtype='barstacked', normed=True);
    v3 = np.concatenate((v1,v2))
    sns.kdeplot(v3);
    plt.show()
    

    来自使用 python 进行数据可视化的 coursera 课程

    【讨论】:

      【解决方案3】:

      把这两部分放在一起。

      import scipy.stats as ss
      import numpy as np
      import matplotlib.pyplot as plt
      alpha, loc, beta=5, 100, 22
      data=ss.gamma.rvs(alpha,loc=loc,scale=beta,size=5000)
      myHist = plt.hist(data, 100, normed=True)
      rv = ss.gamma(alpha,loc,beta)
      x = np.linspace(0,600) 
      h = plt.plot(x, rv.pdf(x), lw=2)
      plt.show()
      

      为了确保您在任何特定的情节实例中得到您想要的,请先尝试创建一个figure 对象

      import scipy.stats as ss
      import numpy as np
      import matplotlib.pyplot as plt
      # setting up the axes
      fig = plt.figure(figsize=(8,8))
      ax  = fig.add_subplot(111)
      # now plot
      alpha, loc, beta=5, 100, 22
      data=ss.gamma.rvs(alpha,loc=loc,scale=beta,size=5000)
      myHist = ax.hist(data, 100, normed=True)
      rv = ss.gamma(alpha,loc,beta)
      x = np.linspace(0,600)
      h = ax.plot(x, rv.pdf(x), lw=2)
      # show
      plt.show()
      

      【讨论】:

      • 我遇到的问题是我正在使用 ipython notebook,所以我会运行一个绘图,它会以交互方式绘图,然后我会做一些事情并绘制另一个,它最终会出现在新情节。感谢您帮助我解决这个问题!
      猜你喜欢
      • 2020-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-23
      • 1970-01-01
      • 2021-05-04
      • 1970-01-01
      相关资源
      最近更新 更多