如何在Python中用matplotlib绘制cdf?

man*_*ing 17 python matplotlib

我有一个名为的无序列表d,如下所示:

[0.0000, 123.9877,0.0000,9870.9876, ...]
Run Code Online (Sandbox Code Playgroud)

我只是想通过在Python中使用Matplotlib来绘制基于此列表的cdf图.但是不知道我是否可以使用任何功能

d = []
d_sorted = []
for line in fd.readlines():
    (addr, videoid, userag, usertp, timeinterval) = line.split()
    d.append(float(timeinterval))

d_sorted = sorted(d)

class discrete_cdf:
    def __init__(data):
        self._data = data # must be sorted
        self._data_len = float(len(data))

    def __call__(point):
        return (len(self._data[:bisect_left(self._data, point)]) / 
               self._data_len)

cdf = discrete_cdf(d_sorted)
xvalues = range(0, max(d_sorted))
yvalues = [cdf(point) for point in xvalues]
plt.plot(xvalues, yvalues)
Run Code Online (Sandbox Code Playgroud)

现在我正在使用此代码,但错误消息是:

Traceback (most recent call last):
File "hitratioparea_0117.py", line 43, in <module>
cdf = discrete_cdf(d_sorted)
TypeError: __init__() takes exactly 1 argument (2 given)
Run Code Online (Sandbox Code Playgroud)

Hoo*_*ked 28

如上所述,cumsum从中numpy运作良好.确保您的数据是正确的PDF(即总和为1),否则CDF将不会以应有的方式结束.这是一个最小的工作示例:

import numpy as np
from pylab import *

# Create some test data
dx = 0.01
X  = np.arange(-2, 2, dx)
Y  = exp(-X ** 2)

# Normalize the data to a proper PDF
Y /= (dx * Y).sum()

# Compute the CDF
CY = np.cumsum(Y * dx)

# Plot both
plot(X, Y)
plot(X, CY, 'r--')

show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 我只有“Y”作为测量数组。我如何确定我的“X”?我仍然设置`dx=0.01`吗? (3认同)

MPa*_*ath 22

我知道我迟到了.但是,如果你只想要你的情节的cdf而不是将来的计算,有一种更简单的方法:

plt.hist(put_data_here, normed=True, cumulative=True, label='CDF',
         histtype='step', alpha=0.8, color='k')
Run Code Online (Sandbox Code Playgroud)

例如,生成其中一个图形的相关代码是:

plt.hist(dataset, bins=bins, normed=True, cumulative=True, label='CDF DATA', 
         histtype='step', alpha=0.55, color='purple')
# bins and (lognormal / normal) datasets are pre-defined
Run Code Online (Sandbox Code Playgroud)

编辑:来自matplotlib文档的这个例子可能更有帮助.

  • 只是 2018 年的更新:不推荐使用 `normed` 以支持 `density`。 (6认同)
  • 我不太喜欢最后的曲线下降。根据我的理解,CDF应该以1结尾。有什么简单的方法可以摆脱这种情况?因为我在一个图中有多个CDF,每个图都有不同的下降,所以切除图的右边缘将无济于事。 (4认同)

MRo*_*lin 8

计算累积和的numpy函数在cumsum这里很有用

In [1]: from numpy import cumsum
In [2]: cumsum([.2, .2, .2, .2, .2])
Out[2]: array([ 0.2,  0.4,  0.6,  0.8,  1. ])
Run Code Online (Sandbox Code Playgroud)


小智 8

现在,您只需使用seabornskdeplot函数和cumulativeas True 即可生成 CDF。

import numpy as np
from matplotlib import pyplot as plt
import seaborn as sns

X1 = np.arange(100)
X2 = (X1 ** 2) / 100
sns.kdeplot(data = X1, cumulative = True, label = "X1")
sns.kdeplot(data = X2, cumulative = True, label = "X2")
plt.legend()
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 请注意,这绘制了 CDF 的平滑*估计*,而不是实际数据值的步骤。您可以看到,事实上,即使最小数据值为 0,绘制的 x 值也会延伸到 0 以下。但这向我指出了 Seaborn 提供了一种直接执行此操作的方法:sns.ecdfplot(),它绘制了实际的步进价值观。https://seaborn.pydata.org/ generated/seaborn.ecdfplot.html (7认同)

Alo*_*lon 6

对于任意值集合,x:

def cdf(x, plot=True, *args, **kwargs):
    x, y = sorted(x), np.arange(len(x)) / len(x)
    return plt.plot(x, y, *args, **kwargs) if plot else (x, y)
Run Code Online (Sandbox Code Playgroud)

((如果您是 python 新手,*args 和 **kwargs 允许您传递参数和命名参数,而无需显式声明和管理它们))