Skip to content

Matplotlib 산점도: plt.scatter() 완전 가이드

Updated on

산점도는 두 수치 변수 간의 관계를 탐색하기 위한 대표적인 시각화 방법입니다. 하지만 효과적인 산점도를 만들려면 -- 패턴, 클러스터, 이상값을 어지럽지 않게 드러내는 산점도를 만들려면 -- 단순한 plt.scatter() 호출 이상의 것이 필요합니다. 카테고리용 색상 매핑, 세 번째 변수를 위한 크기 인코딩, 적절한 축 레이블, 그리고 겹치는 점의 처리가 필요합니다.

Matplotlib의 plt.scatter()는 풍부한 매개변수 세트로 이 모든 것을 처리합니다. 이 가이드는 기본 산점도부터 버블 차트, 회귀선, 다중 패널 산점도 행렬과 같은 고급 기법까지 모든 것을 다룹니다.

📚

기본 산점도

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
x = np.random.randn(100)
y = 2 * x + np.random.randn(100) * 0.5
 
plt.figure(figsize=(8, 6))
plt.scatter(x, y)
plt.xlabel('X 값')
plt.ylabel('Y 값')
plt.title('기본 산점도')
plt.show()

마커 사용자 정의

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
x = np.random.randn(50)
y = np.random.randn(50)
 
plt.figure(figsize=(8, 6))
plt.scatter(x, y,
    s=100,              # 마커 크기
    c='steelblue',      # 색상
    marker='o',         # 마커 모양
    alpha=0.7,          # 투명도
    edgecolors='black', # 테두리 색상
    linewidths=0.5,     # 테두리 너비
)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('사용자 정의 산점도')
plt.show()

일반적인 마커 모양

마커기호설명
'o'기본값
's'사각형
'^'위쪽 삼각형
'D'다이아몬드
'*'
'+'플러스
'x'크로스
'.'작음, 밀집 데이터용

카테고리별 색상

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
n = 50
 
# 세 가지 카테고리
categories = ['A', 'B', 'C']
colors = ['#e74c3c', '#3498db', '#2ecc71']
 
plt.figure(figsize=(8, 6))
for cat, color in zip(categories, colors):
    x = np.random.randn(n) + (categories.index(cat) * 2)
    y = np.random.randn(n) + (categories.index(cat) * 1.5)
    plt.scatter(x, y, c=color, label=cat, alpha=0.7, s=60, edgecolors='white')
 
plt.xlabel('특성 1')
plt.ylabel('특성 2')
plt.title('카테고리별 색상 산점도')
plt.legend()
plt.show()

색상 매핑 (연속 변수)

c 매개변수에 숫자 배열과 컬러맵을 사용하여 세 번째 변수를 색상으로 인코딩합니다:

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
x = np.random.randn(200)
y = np.random.randn(200)
values = x ** 2 + y ** 2  # 원점으로부터의 거리
 
plt.figure(figsize=(8, 6))
scatter = plt.scatter(x, y, c=values, cmap='viridis', s=50, alpha=0.8)
plt.colorbar(scatter, label='원점으로부터의 거리')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('색상 매핑이 있는 산점도')
plt.show()

인기 있는 컬러맵

컬러맵유형최적 용도
'viridis'순차적기본값, 지각적으로 균일
'plasma'순차적높은 대비
'coolwarm'발산양수/음수 값
'RdYlGn'발산좋음/나쁨 범위
'Set1'정성적범주형 데이터

크기 인코딩 (버블 차트)

세 번째 변수를 마커 크기로 인코딩하여 버블 차트를 만듭니다:

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
countries = ['US', 'China', 'India', 'Germany', 'Japan', 'UK', 'Brazil', 'France']
gdp = np.array([21.43, 14.34, 2.87, 3.86, 5.08, 2.83, 1.87, 2.72])
population = np.array([331, 1402, 1380, 83, 126, 67, 213, 67])
growth = np.array([2.3, 5.8, 6.5, 1.1, 0.8, 1.4, 1.2, 1.5])
 
plt.figure(figsize=(10, 7))
scatter = plt.scatter(gdp, growth,
    s=population * 2,   # 인구를 가시적 크기로 스케일링
    c=range(len(countries)),
    cmap='tab10',
    alpha=0.6,
    edgecolors='black',
)
 
for i, country in enumerate(countries):
    plt.annotate(country, (gdp[i], growth[i]),
        textcoords="offset points", xytext=(10, 5), fontsize=9)
 
plt.xlabel('GDP (조 USD)')
plt.ylabel('GDP 성장률 (%)')
plt.title('GDP vs 성장률 (버블 크기 = 인구)')
plt.show()

회귀선 추가

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
x = np.random.randn(100) * 3
y = 1.5 * x + np.random.randn(100) * 2
 
# 선형 회귀 적합
coefficients = np.polyfit(x, y, 1)
poly = np.poly1d(coefficients)
x_line = np.linspace(x.min(), x.max(), 100)
 
plt.figure(figsize=(8, 6))
plt.scatter(x, y, alpha=0.6, s=40, label='데이터')
plt.plot(x_line, poly(x_line), 'r-', linewidth=2,
    label=f'y = {coefficients[0]:.2f}x + {coefficients[1]:.2f}')
 
plt.xlabel('X')
plt.ylabel('Y')
plt.title('회귀선이 있는 산점도')
plt.legend()
plt.show()

겹치는 점 처리

점이 많이 겹치는 경우, 투명도, 작은 마커 또는 밀도 기반 기법을 사용합니다:

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
x = np.random.randn(5000)
y = np.random.randn(5000)
 
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
 
# 방법 1: 투명도
axes[0].scatter(x, y, alpha=0.1, s=10)
axes[0].set_title('알파 투명도')
 
# 방법 2: 작은 마커
axes[1].scatter(x, y, s=1, c='black')
axes[1].set_title('작은 마커')
 
# 방법 3: 2D 히스토그램 (hexbin)
axes[2].hexbin(x, y, gridsize=30, cmap='YlOrRd')
axes[2].set_title('Hexbin 밀도')
 
plt.tight_layout()
plt.show()

여러 서브플롯

import matplotlib.pyplot as plt
import numpy as np
 
np.random.seed(42)
n = 100
 
fig, axes = plt.subplots(2, 2, figsize=(10, 10))
 
# 플롯 1: 선형
x1 = np.random.randn(n)
axes[0, 0].scatter(x1, 2 * x1 + np.random.randn(n) * 0.5, c='steelblue', s=30)
axes[0, 0].set_title('선형 관계')
 
# 플롯 2: 이차
x2 = np.linspace(-3, 3, n)
axes[0, 1].scatter(x2, x2**2 + np.random.randn(n) * 0.5, c='coral', s=30)
axes[0, 1].set_title('이차 관계')
 
# 플롯 3: 클러스터
for i, c in enumerate(['red', 'blue', 'green']):
    cx = np.random.randn(30) + i * 3
    cy = np.random.randn(30) + i * 2
    axes[1, 0].scatter(cx, cy, c=c, s=30, alpha=0.7)
axes[1, 0].set_title('클러스터 데이터')
 
# 플롯 4: 상관관계 없음
axes[1, 1].scatter(np.random.randn(n), np.random.randn(n), c='purple', s=30, alpha=0.5)
axes[1, 1].set_title('상관관계 없음')
 
plt.tight_layout()
plt.show()

PyGWalker를 활용한 인터랙티브 산점도

탐색적 데이터 분석에서 정적 산점도는 시작점에 불과합니다. PyGWalker (opens in a new tab)는 pandas DataFrame을 Jupyter에서 직접 인터랙티브한 Tableau 스타일 인터페이스로 변환합니다. 열을 축으로 드래그하고, 색상 및 크기 인코딩을 추가하며, 데이터를 필터링할 수 있습니다 -- 추가 코드 작성 없이:

import pandas as pd
import pygwalker as pyg
 
df = pd.DataFrame({'x': x, 'y': y, 'category': np.random.choice(['A', 'B', 'C'], len(x))})
walker = pyg.walk(df)

plt.scatter() 매개변수 참조

매개변수유형설명
x, y배열형데이터 위치
s스칼라 또는 배열마커 크기(포인트^2)
c색상 또는 배열마커 색상. 배열이면 컬러맵 적용
markerstr마커 스타일 ('o', 's', '^' 등)
cmapstr 또는 Colormapc가 숫자일 때의 컬러맵
alphafloat (0-1)투명도
edgecolors색상마커 테두리 색상
linewidthsfloat마커 테두리 너비
vmin, vmaxfloat컬러맵 범위 제한
labelstr범례 레이블

FAQ

Matplotlib에서 산점도를 어떻게 만드나요?

plt.scatter(x, y)를 사용합니다. x와 y는 같은 길이의 배열입니다. plt.xlabel(), plt.ylabel(), plt.title()로 레이블을 추가합니다. plt.show()를 호출하여 플롯을 표시합니다.

산점도 점을 카테고리별로 어떻게 색을 지정하나요?

카테고리를 반복하면서 각각에 대해 다른 c 매개변수와 labelplt.scatter()를 호출합니다. 그런 다음 plt.legend()를 호출하여 범례를 표시합니다. 또는 연속적인 색상 지정을 위해 컬러맵과 함께 숫자 배열을 c에 전달할 수 있습니다.

산점도에 추세선을 어떻게 추가하나요?

np.polyfit(x, y, 차수)를 사용하여 다항식을 적합하고, 계수로 np.poly1d()를 생성하여 plt.plot()으로 그립니다. 차수=1의 경우 선형 회귀선이 됩니다.

plt.scatter()와 plt.plot()의 차이는 무엇인가요?

plt.scatter()는 점별로 크기, 색상, 모양을 개별 제어할 수 있는 개별 마커를 생성합니다. plt.plot()은 마커 스타일로 균일한 외관의 연결된 점을 생성합니다. 점에 개별 스타일링이 필요할 때는 scatter()를, 선 그래프나 균일한 마커에는 plot()을 사용하세요.

산점도에서 겹치는 점을 어떻게 처리하나요?

alpha(투명도)를 사용하여 밀도를 드러내고, 마커 크기 s를 줄이고, plt.hexbin()으로 밀도 히트맵을 사용하거나, 작은 랜덤 오프셋으로 점을 약간 흩뜨립니다.

결론

Matplotlib의 plt.scatter()는 Python에서 산점도를 만드는 표준 도구입니다. 기본 탐색에는 간단한 plt.scatter(x, y)로 충분합니다. 출판 품질의 그림을 위해서는 카테고리용 색상 매핑, 세 번째 변수를 위한 크기 인코딩, 추세를 위한 회귀선, 밀집 데이터를 위한 투명도를 활용하세요. 이러한 기법을 마스터하면 모든 이변량 관계를 효과적으로 시각화할 수 있습니다.

📚