如何在matplotlib中创建密度图?

时间:2010-11-10 23:39:59

标签: python r numpy matplotlib scipy

在R中,我可以通过执行以下操作来创建所需的输出:

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

Density plot in 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()

Histogram in matplotlib

我也尝试了the normed=True parameter但除了尝试将高斯拟合到直方图之外,其他任何事情都没有。

我最近的尝试是在scipy.statsgaussian_kde,网上的示例,但到目前为止我都没有成功。

6 个答案:

答案 0 :(得分:119)

五年后,当我谷歌"如何使用python"创建内核密度图时,这个线程仍然显示在顶部!

今天,更简单的方法是使用seaborn,这个包提供了许多方便的绘图功能和良好的样式管理。

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)

enter image description here

答案 1 :(得分:111)

Sven已经展示了如何使用Scipy中的类gaussian_kde,但你会注意到它看起来与你用R生成的内容完全不同。这是因为gaussian_kde试图推断带宽自动。您可以通过更改covariance_factor类的函数gaussian_kde以某种方式使用带宽。首先,这是你在不改变这个功能的情况下获得的:

alt text

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

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

我得到了

alt text

这与你从R得到的非常接近。我做了什么? gaussian_kde使用可更改的函数covariance_factor来计算其带宽。在更改函数之前,covariance_factor为此数据返回的值约为.5。降低这个降低了带宽。我必须在更改该函数后调用_compute_covariance,以便正确计算所有因子。它与R的bw参数不完全一致,但希望它能帮助你找到正确的方向。

答案 2 :(得分:42)

也许尝试类似的事情:

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

答案 3 :(得分:36)

选项1:

使用pandas数据框图(构建于matplotlib之上):

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

enter image description here

选项2:

使用distplot的{​​{1}}:

seaborn

enter image description here

答案 4 :(得分:0)

也可以使用matplotlib创建密度图: 函数plt.hist(data)返回密度图所需的y和x值(请参见文档https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.hist.html)。 结果,以下代码通过使用matplotlib库创建了密度图:

import matplotlib.pyplot as plt
dat=[-1,2,1,4,-5,3,6,1,2,1,2,5,6,5,6,2,2,2]
a=plt.hist(dat,density=True)
plt.close()
plt.figure()
plt.plot(a[1][1:],a[0])      

此代码返回链接中的密度图:https://imgur.com/LiNIhLB

答案 5 :(得分:0)

您可以执行以下操作:

s = np.random.normal(2, 3, 1000)
import matplotlib.pyplot as plt
count, bins, ignored = plt.hist(s, 30, density=True)
plt.plot(bins, 1/(3 * np.sqrt(2 * np.pi)) * np.exp( - (bins - 2)**2 / (2 * 3**2) ), 
linewidth=2, color='r')
plt.show()