matplotlib에서 밀도 플롯을 만드는 방법은 무엇입니까?


122

RI에서 다음을 수행하여 원하는 출력을 생성 할 수 있습니다.

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의 밀도 플롯

파이썬에서 (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였지만 지금까지 성공하지 못했습니다.


한 번 봐 가지고 seaborn stackoverflow.com/a/32803224/1922302
johk95

답변:


124

Sven은 gaussian_kdeScipy 에서 클래스를 사용하는 방법을 보여 주었지만 R로 생성 한 것과 완전히 닮지 않았 음을 알 수 있습니다. 이는 gaussian_kde대역폭을 자동으로 추론하려고하기 때문 입니다. 클래스 의 기능 covariance_factor을 변경하여 대역폭으로 플레이 할 수 있습니다 gaussian_kde. 첫째, 해당 기능을 변경하지 않고 얻을 수있는 것은 다음과 같습니다.

대체 텍스트

그러나 다음 코드를 사용하면 :

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함수를 사용합니다 covariance_factor. 함수를 변경하기 전에이 데이터에 대해 covariance_factor가 반환 한 값은 약 .5였습니다. 이것을 낮추면 대역폭이 낮아졌습니다. _compute_covariance모든 요소가 올바르게 계산되도록 함수를 변경 한 후 호출 해야했습니다. R의 bw 매개 변수와 정확히 일치하지는 않지만 올바른 방향으로가는 데 도움이되기를 바랍니다.


6
@Justin 좋은 대답 (+1)과 Python v R 화염 전쟁 또는 기타를 시작하고 싶지 않지만 R이 Python 및 다른 언어보다 훨씬 간결하게 데이터를 사용하는 방식을 좋아합니다. 나는 파이썬이 R에 비해 많은 좋은 점을 가지고 있다고 확신하며 (나는 파이썬 사용자가 아니기 때문에 아마도 주석을 달기 위해 완전히 통일되어있다) 데이터를 분석하는 것보다 더 많은 작업에 사용할 수 있지만, 오랜 시간의 R 사용자 나는 이와 같은 예제가 나타날 때까지 그러한 작업에 대한 언어가 얼마나 간결한 지 잊어 버립니다.
Gavin Simpson

4
(여전히 주석 편집과 싸우고 있음) 다음은 대역폭을 인수로 설정할 수있는 gaussian_kde의 하위 클래스와 더 많은 예입니다. mail.scipy.org/pipermail/scipy-user/2010-January/023877.html 및 개선 사항이 있습니다. projects.scipy.org/scipy/ticket/1092 에서 티켓 . gaussian_kde는 n 차원 데이터 용으로 설계되었습니다.
Josef

11
@Gavin Simpson, 예, R은 범위가 좁기 때문에 더 간결합니다. 통계 계산 및 그래픽을 위해 만들어졌습니다. Python은 원하는 모든 작업을 수행 할 수있는 일반적인 프로그래밍 언어입니다. 그 때문에 구문이 간결하지 않을 수 있습니다. 일부는 Numpy / Scipy의 다른 디자인이지만 일부는 Python의 모듈 식 설정입니다. R은 계산과 그래픽 만 수행해야하는 경우 훌륭하지만 일부 브레이 더 애플리케이션에서 이러한 계산을 사용해야하는 경우 Python과 같은 것을 원할 수 있습니다. 그러나 Python에서 R을 사용할 수도 있습니다 ...
Justin Peel

10
set_bandwidth방법 및 bw_method생성자 인수는 당 scipy 0.11.0에 gaussian_kde에 추가 된 문제 1619
eddygeek

1
오래된 대답. 현재 Python에서 더 표준 인 Seaborn 솔루션에 대해서는 아래를 참조하십시오.
LudvigH

148

5 년 후, "python을 사용하여 커널 밀도 플롯을 만드는 방법"을 Google에서 검색했을 때이 스레드가 여전히 맨 위에 표시됩니다!

오늘날이 작업을 수행하는 훨씬 더 쉬운 방법 은 많은 편리한 플로팅 기능과 좋은 스타일 관리를 제공하는 패키지 인 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)

여기에 이미지 설명 입력


정말 고마워요 .. 수일 동안 이런 걸 찾고 있었어요 .. 왜 bw=0.5주어지는 지 설명해 주 시겠어요?
Sitz Blogz

4
@SitzBlogz bw매개 변수는 대역폭을 나타냅니다. 나는 OP의 설정과 일치하려고 노력하고 있었다 (그의 원래 첫 번째 코드 예제 참조). bw컨트롤에 대한 자세한 설명 은 en.wikipedia.org/wiki/…를 참조하십시오 . 기본적으로 밀도 플롯을 얼마나 매끄럽게할지 제어합니다. bw가 클수록 더 부드러워집니다.
Xin

내 데이터가 본질적으로 이산 적이라는 것을 묻는 또 다른 쿼리가 있으며 scipy doc를 읽은 후 PMF = PDF를 플롯하는 방법에 대한 제안이 있음을 이해했습니다.
Sitz Blogz

1
내가 이것을 시도하면 나는 얻는다TypeError: slice indices must be integers or None or have an __index__ method
endolith

48

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

여기에 이미지 설명 입력

옵션 2 :

사용 distplotseaborn:

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)

여기에 이미지 설명 입력


4
대역폭 매개 변수를 추가하려면 : df.plot.density (bw_method = 0.5)
Anake

3
@Aziz Do n't need pandas.DataFrame, pandas.Series(data).plot(kind='density')@Anake 를 사용할 수 있습니다. df.plot.density를 별도의 단계로 설정할 필요가 없습니다. 당신의에 전달할 수 bw_method에 kwargpd.Series(data).plot(kind='density', bw_method=0.5)
레드 완두콩

45

다음과 같이 시도해보십시오.

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()다른 커널 밀도 추정값으로 쉽게 대체 할 수 있습니다 .


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

이 코드는 다음 밀도 플롯을 반환합니다.

여기에 이미지 설명 입력

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.