How to plot cdf in matplotlib in Python?

I have a disordered list named d that looks like:

[0.0000, 123.9877,0.0000,9870.9876, ...] 

I just simply want to plot a cdf graph based on this list by using Matplotlib in Python. But don't know if there's any function I can use

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) 

Now I am using this code, but the error message is :

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) 
4

7 Answers

As mentioned, cumsum from numpy works well. Make sure that your data is a proper PDF (ie. sums to one), otherwise the CDF won't end at unity as it should. Here is a minimal working example:

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() 

enter image description here

3

I know I'm late to the party. But, there is a simpler way if you just want the cdf for your plot and not for future calculations:

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

As an example,

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 

EDIT: This example from the matplotlib docs may be more helpful.

6

The numpy function to compute cumulative sums cumsum can be useful here

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. ]) 

For an arbitrary collection of values, 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) 

((If you're new to python, the *args, and **kwargs allow you to pass arguments and named arguments without declaring and managing them explicitly))

1

Nowadays, you can just use seaborn's kdeplot function with cumulative as True to generate a 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() 

enter image description here

What works best for me is quantile function of pandas.

Say I have 71 participants. Each participant have a certain number of interruptions. I want to compute the CDF plot of #interruptions for participants. Goal is to be able to tell how many percent of participants have at least 30 interventions.

step=0.05 indices = np.arange(0,1+step,step) num_interruptions_per_participant = [32,70,52,52,39,20,37,31,60,57,31,71,24,23,38,4,77,37,79,43,63,43,75,13 ,45,31,57,28,61,29,30,52,65,11,76,37,65,28,33,73,65,43,50,33,45,40,50,44 ,33,49,24,69,55,47,22,45,54,11,30,13,32,52,31,50,10,46,10,25,47,51,83] CDF = pd.DataFrame({'dummy':num_interruptions_per_participant})['dummy'].quantile(indices) plt.plot(CDF,indices,linewidth=9, label='#interventions', color='blue') 

enter image description here

According to Graph Almost 25% of the participants have less than 30 interventions.

You can use this statistic for your further analysis. For instance, In my case I need at least 30 intervention for each participant in order to meet minimum sample requirement needed for leave-one-subject out evaluation. CDF tells me that I have problem with 25% of the participants.

import matplotlib.pyplot as plt X=sorted(data) Y=[] l=len(X) Y.append(float(1)/l) for i in range(2,l+1): Y.append(float(1)/l+Y[i-2]) plt.plot(X,Y,color=c,marker='o',label='xyz') 

I guess this would do,for the procedure refer

1

You Might Also Like