밀도로 채색된 산점도를 만들려면 어떻게 해야 합니까?
저는 각 점이 주변 점의 공간 밀도에 의해 채색되는 산점도를 만들고 싶습니다.
저는 매우 유사한 질문을 발견했는데, R:를 사용한 예를 보여줍니다.
R 산점도: 기호 색상은 겹치는 점의 수를 나타냅니다.
matplotlib을 사용하여 파이썬에서 유사한 것을 달성하는 가장 좋은 방법은 무엇입니까?
에 더하여hist2d또는hexbin@askewchan이 제안한 것처럼, 당신은 당신이 링크한 질문의 수락된 대답이 사용하는 것과 같은 방법을 사용할 수 있습니다.
원하는 경우:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
# Generate fake data
x = np.random.normal(size=1000)
y = x * 3 + np.random.normal(size=1000)
# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
fig, ax = plt.subplots()
ax.scatter(x, y, c=z, s=100)
plt.show()

가장 밀도가 높은 점이 항상 맨 위에 있도록 밀도 순서대로 점을 표시하려면(연결된 예제와 유사) z 값을 기준으로 정렬합니다.조금 더 좋아 보이므로 여기에 더 작은 크기의 마커를 사용할 것입니다.
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
# Generate fake data
x = np.random.normal(size=1000)
y = x * 3 + np.random.normal(size=1000)
# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
# Sort the points by density, so that the densest points are plotted last
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
fig, ax = plt.subplots()
ax.scatter(x, y, c=z, s=50)
plt.show()

10만 개 이상의 데이터 포인트를 표시하시겠습니까?
gaussian_kde()를 사용하여 승인된 답변은 많은 시간이 소요됩니다.제 기계에서 100k 행은 약 11분 정도 걸렸습니다.여기에 두 가지 대안적인 방법(mpl-scatter-density 및 데이터 셰이더)을 추가하고 주어진 답변을 동일한 데이터 세트와 비교하겠습니다.
다음에서는 100k 행의 테스트 데이터 세트를 사용했습니다.
import matplotlib.pyplot as plt
import numpy as np
# Fake data for testing
x = np.random.normal(size=100000)
y = x * 3 + np.random.normal(size=100000)
출력 및 계산 시간 비교
다음은 여러 가지 방법을 비교한 것입니다.
1: mpl-scatter-density
설치
pip install mpl-scatter-density
예제 코드
import mpl_scatter_density # adds projection='scatter_density'
from matplotlib.colors import LinearSegmentedColormap
# "Viridis-like" colormap with white background
white_viridis = LinearSegmentedColormap.from_list('white_viridis', [
(0, '#ffffff'),
(1e-20, '#440053'),
(0.2, '#404388'),
(0.4, '#2a788e'),
(0.6, '#21a784'),
(0.8, '#78d151'),
(1, '#fde624'),
], N=256)
def using_mpl_scatter_density(fig, x, y):
ax = fig.add_subplot(1, 1, 1, projection='scatter_density')
density = ax.scatter_density(x, y, cmap=white_viridis)
fig.colorbar(density, label='Number of points per pixel')
fig = plt.figure()
using_mpl_scatter_density(fig, x, y)
plt.show()
이 그림을 그리는 데 0.05초가 걸렸습니다.
확대 기능도 매우 훌륭합니다.
2: datashader
- 데이터 셰이더는 흥미로운 프로젝트입니다.데이터 셰이더 0.12에 formatplotlib 지원이 추가되었습니다.
설치
pip install datashader
코드(dshow의 소스 및 매개 변수 목록):
import datashader as ds
from datashader.mpl_ext import dsshow
import pandas as pd
def using_datashader(ax, x, y):
df = pd.DataFrame(dict(x=x, y=y))
dsartist = dsshow(
df,
ds.Point("x", "y"),
ds.count(),
vmin=0,
vmax=35,
norm="linear",
aspect="auto",
ax=ax,
)
plt.colorbar(dsartist)
fig, ax = plt.subplots()
using_datashader(ax, x, y)
plt.show()
- 이 그림을 그리는 데 0.83초가 걸렸습니다.
- 세 번째 변수를 기준으로 색상을 지정할 수도 있습니다.다음에 대한 세 번째 매개 변수
dsshow색상을 제어합니다.여기에서 더 많은 예를 참조하고 여기에서 dshow를 위한 소스를 참조하십시오.
3: scatter_with_gaussian_kde
def scatter_with_gaussian_kde(ax, x, y):
# https://stackoverflow.com/a/20107592/3015186
# Answer by Joel Kington
xy = np.vstack([x, y])
z = gaussian_kde(xy)(xy)
ax.scatter(x, y, c=z, s=100, edgecolor='')
- 이 그림을 그리는 데 11분이 걸렸습니다.
4: using_hist2d
import matplotlib.pyplot as plt
def using_hist2d(ax, x, y, bins=(50, 50)):
# https://stackoverflow.com/a/20105673/3015186
# Answer by askewchan
ax.hist2d(x, y, bins, cmap=plt.cm.jet)
- 이 빈을 그리는 데 0.021초가 걸렸습니다=(50,50):
- 이 빈을 그리는 데 0.165초가 걸렸습니다=(1000,1000):
- 단점: 확대된 데이터는 mpl-산란 밀도 또는 데이터 셰이더를 사용할 때만큼 좋아 보이지 않습니다.또한 빈의 수를 직접 결정해야 합니다.
5: density_scatter
- 코드는 기욤의 답변과 같습니다.
- 빈=(50,50)을 사용하여 이 값을 그리는 데 0.073초가 걸렸습니다.
- 빈=(1000,1000)을 사용하여 이 값을 그리는 데 0.368초가 걸렸습니다.
또한 포인트 수에 따라 KDE 계산이 너무 느릴 경우 np.histogram2d에서 색상이 보간될 수 있습니다 [댓글에 대한 응답으로 업데이트:색상 막대를 표시하려면 다음과 같이 ax.scatter() 대신 plt.colorbar()를 사용합니다.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import Normalize
from scipy.interpolate import interpn
def density_scatter( x , y, ax = None, sort = True, bins = 20, **kwargs ) :
"""
Scatter plot colored by 2d histogram
"""
if ax is None :
fig , ax = plt.subplots()
data , x_e, y_e = np.histogram2d( x, y, bins = bins, density = True )
z = interpn( ( 0.5*(x_e[1:] + x_e[:-1]) , 0.5*(y_e[1:]+y_e[:-1]) ) , data , np.vstack([x,y]).T , method = "splinef2d", bounds_error = False)
#To be sure to plot all data
z[np.where(np.isnan(z))] = 0.0
# Sort the points by density, so that the densest points are plotted last
if sort :
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
ax.scatter( x, y, c=z, **kwargs )
norm = Normalize(vmin = np.min(z), vmax = np.max(z))
cbar = fig.colorbar(cm.ScalarMappable(norm = norm), ax=ax)
cbar.ax.set_ylabel('Density')
return ax
if "__main__" == __name__ :
x = np.random.normal(size=100000)
y = x * 3 + np.random.normal(size=100000)
density_scatter( x, y, bins = [30,30] )
히스토그램을 만들 수 있습니다.
import numpy as np
import matplotlib.pyplot as plt
# fake data:
a = np.random.normal(size=1000)
b = a*3 + np.random.normal(size=1000)
plt.hist2d(a, b, (50, 50), cmap=plt.cm.jet)
plt.colorbar()

언급URL : https://stackoverflow.com/questions/20105364/how-can-i-make-a-scatter-plot-colored-by-density
'codememo' 카테고리의 다른 글
| 스프링 부트 테스트의 트랜잭션이 롤백되지 않음 (0) | 2023.07.22 |
|---|---|
| .py 파일과 .pyc 파일의 차이점은 무엇입니까? (0) | 2023.07.22 |
| django-rest-framework serializer를 사용하여 외부 키 값을 검색하는 중 (0) | 2023.07.22 |
| 커서에서 행 수를 찾는 방법 (0) | 2023.07.22 |
| 반복을 사용하지 않고 배열 반전 (0) | 2023.07.22 |


