如何在matplotlib中创build密度图?

在RI可以通过执行以下操作来创build所需的输出

data = c(rep(1.5, 7), rep(2.5, 2), rep(3.5, 8), rep(4.5, 3), rep(5.5, 1), rep(6.5, 8)) plot(density(data, bw=0.5)) 

R中的密度图

在python(与matplotlib)最近我得到了一个简单的直方图:

 import matplotlib.pyplot as plt data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8 plt.hist(data, bins=6) plt.show() 

直方图在matplotlib

我也尝试了Normed = True参数,但除了尝试将高斯拟合到直方图以外无法获得任何其他内容。

我最近的尝试是围绕scipy.statsgaussian_kde ,在networking上的例子,但我迄今没有成功。

Sven展示了如何使用Scipy中的gaussian_kde类,但是你会注意到它看起来不像你用R生成的东西。这是因为gaussian_kde试图自动推断带宽。 您可以通过更改gaussian_kde类的函数covariance_factor来使用带宽。 首先,这里是你没有改变的function:

替代文字

但是,如果我使用下面的代码:

 import matplotlib.pyplot as plt import numpy as np from scipy.stats import gaussian_kde data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8 density = gaussian_kde(data) xs = np.linspace(0,8,200) density.covariance_factor = lambda : .25 density._compute_covariance() plt.plot(xs,density(xs)) plt.show() 

我明白了

替代文字

这与你从R得到的结果非常接近。我做了什么? gaussian_kde使用一个changable函数, covariance_factor来计算它的带宽。 在改变函数之前,covariance_factor为这个数据返回的值大约是.5。 降低这个降低了带宽。 改变这个函数后,我不得不调用_compute_covariance ,以便所有的因素都能正确计算。 这与R的bw参数并不完全一致,但希望它能帮助你朝正确的方向发展。

五年后,当我Google“如何使用python创build一个内核密度图”时,这个线程仍然显示在顶部!

今天,更简单的方法是使用seaborn ,这个包提供了许多方便的绘图function和良好的风格pipe理。

 import numpy as np import seaborn as sns data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8 sns.set_style('whitegrid') sns.kdeplot(np.array(data), bw=0.5) 

在这里输入图像说明

也许尝试像这样:

 import matplotlib.pyplot as plt import numpy from scipy import stats data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8 density = stats.kde.gaussian_kde(data) x = numpy.arange(0., 8, .1) plt.plot(x, density(x)) plt.show() 

你可以很容易地用不同的内核密度估计代替gaussian_kde()

选项1:

使用pandas数据框图(build立在matplotlib之上):

 import pandas as pd data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8 df = pd.DataFrame(data) df.plot(kind='density') 

在这里输入图像说明

选项2:

使用distplot seaborn

 import seaborn as sns data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8 sns.distplot(data, hist=False) 

在这里输入图像说明