In [101]:
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
from matplotlib.ticker import NullLocator, NullFormatter, MaxNLocator, FuncFormatter
import warnings
warnings.filterwarnings(action='ignore')
Subplot¶
: 하나의 그림(캔버스)안에 여러 개의 plot을 넣는 것
[plt.subplot]¶
- 개별 subplot을 생성
- (행, 열, 위치)로 subplot 위치를 지정
- 사용하기 간단하지만, plot간의 세부 설정이 제한적이다.
In [3]:
# subplot(행, 열, 위치)
for i in range(1, 7): # 총 6개의 서브플롯 생성
plt.subplot(2, 3, i) # 2행 3열 중 i번째 위치에 생성
plt.text(0.5, 0.5, f"({2}, {3}, {i})", fontsize=18, ha='center') # 텍스트 추가
plt.tight_layout()
plt.show()
[plt.subplots]¶
- subplot의 행렬을 생성
- sharex와 sharey를 통해 x축 및 y축을 공유 가능
- 반환된 Axes 객체 배열을 사용해 세부 조작이 가능
In [14]:
# subplots(행, 열)로 Axes 배열 생성
fig, ax = plt.subplots(2, 3, figsize=(8, 6), sharex='col', sharey='row') # x축/행, y축/열 공유
for i in range(2): # 2행
for j in range(3): # 3열
ax[i, j].text(0.5, 0.5, f"({i}, {j})", fontsize=18, ha='center') # 각 서브플롯에 텍스트 추가
plt.tight_layout()
plt.show()
GridSpec + subplot¶
: 다양한 크기의 서브플롯이 GridSpec으로 구성된 하나의 캔버스에 표시된다.
In [23]:
# GridSpec 생성: 2행 3열 격자
grid = GridSpec(2, 3, wspace=0.4, hspace=0.3) # wspace와 hspace는 각각 격자 간의 가로 및 세로 간격을 설정
# 첫 번째 셀 (0, 0)에 서브플롯 추가
plt.subplot(grid[0, 0])
plt.title("grid[0, 0]")
# 첫 번째 행의 두 번째와 세 번째 셀에 걸쳐 서브플롯 추가
plt.subplot(grid[0, 1:])
plt.title("grid[0, 1:]")
# 두 번째 행의 첫 번째와 두 번째 셀에 걸쳐 서브플롯 추가
plt.subplot(grid[1, :2])
plt.title("grid[1, :2]")
# 두 번째 행의 세 번째 셀에 서브플롯 추가
plt.subplot(grid[1, 2])
plt.title("grid[1, 2]")
# 레이아웃 조정
plt.tight_layout()
plt.show()
In [ ]:
아래와 같이 GridSpec을 이용해서 x축과 y축의 분포를 볼 수 있다.¶
In [35]:
# 데이터 생성
mean = [0, 0]
cov = [[1, 1], [1, 2]] # 공분산 행렬
x, y = np.random.multivariate_normal(mean, cov, 3000).T
# GridSpec 생성 및 플롯 설정
fig = plt.figure(figsize=(6, 6))
grid = plt.GridSpec(4, 4, hspace=0.2, wspace=0.2) # 4x4 행렬을 만들기
# 메인 산점도 플롯
main_ax = fig.add_subplot(grid[:-1, 1:])
main_ax.plot(x, y, 'ok', markersize=3, alpha=0.2) # 산점도
# X축 히스토그램
x_hist = fig.add_subplot(grid[-1, 1:], sharex=main_ax)
x_hist.hist(x, bins=40, histtype='stepfilled', color='gray', orientation='vertical')
x_hist.invert_yaxis()
# Y축 히스토그램
y_hist = fig.add_subplot(grid[:-1, 0], sharey=main_ax)
y_hist.hist(y, bins=40, histtype='stepfilled', color='gray', orientation='horizontal')
y_hist.invert_xaxis()
plt.show()
In [ ]:
In [ ]:
In [ ]:
화살표 + 텍스트를 통한 지점 강조(Axes.annotate())¶
In [47]:
# 데이터 생성
x = np.linspace(0, 20, 1000)
y = np.cos(x)
# 플롯 생성
fig, ax = plt.subplots()
ax.plot(x, y, label="cos(x)", color='blue')
# 축 설정
ax.axis('equal') # X, Y 축 비율 동일하게 설정
# 최대값(local maximum) 강조 - 단순 직선 화살표 사용
ax.annotate('local maximum',
xy=(6.28, 1), # 화살표 머리 위치 (좌표)
xytext=(10, 2), # 텍스트 위치(화살표 꼬리 위치)
arrowprops=dict(facecolor='black', shrink=0.05)) # 화살표 스타일
# 최소값(local minimum) 강조 - connectionstyle 사용
ax.annotate('local minimum',
xy=(5 * np.pi, -1), # 화살표 머리 위치 (좌표)
xytext=(2, -6), # 텍스트 위치(화살표 꼬리 위치)
arrowprops=dict(arrowstyle='->',
connectionstyle="angle3,angleA=0,angleB=-90"))
# 범례 추가
ax.legend()
plt.show()
In [ ]:
In [ ]:
In [ ]:
눈금(Tick)¶
[Locator (위치 설정자)]¶
역할: 축에서 눈금(tick)이 표시될 위치를 결정합니다. 즉, 파이가 작성될 위치를 결정¶
설명¶
- 축의 눈금 위치를 결정합니다.
- 예를 들어, x축에 0, π/2, π, 3π/2, 2π 위치에 눈금을 표시하려면 Locator가 이를 설정합니다.
주요 Locator¶
- MultipleLocator(base): 특정 간격으로 눈금을 표시합니다. (예: π/2 간격)
- FixedLocator(locs): 사용자가 지정한 위치에만 눈금을 표시합니다.
- AutoLocator(): Matplotlib이 자동으로 적절한 눈금 간격을 선택합니다.
- NullLocator(): 눈금을 완전히 제거합니다.
[Formatter (레이블 포맷터)]¶
역할: 각 눈금 위치에 표시될 레이블 값을 결정합니다. 즉, 몇분의 몇 파이를 작성할지 결정¶
설명¶
- 축의 눈금 위치에 어떤 값을 텍스트로 표시할지를 제어합니다.
- 예를 들어, x축의 눈금 위치가 0, π/2, π, 3π/2, 2π라면, 이를 0, π/2, π, 3π/2, 2π로 표시하거나, 0, 1/2π, 1π, 3/2π, 2π처럼 표시할 수 있습니다.
주요 Locator¶
- FuncFormatter(func): 사용자가 정의한 함수로 레이블을 생성합니다.
- FormatStrFormatter(fmt): 문자열 포맷팅(예: "%0.2f").
- NullFormatter(): 레이블을 완전히 제거합니다.
- ScalarFormatter(): 일반 숫자 포맷(기본 값).
- LogFormatter(): 로그 축에 적합한 포맷.
눈금의 종류¶
- major
- minor
[눈금 없애기]¶
In [55]:
# 데이터 생성
data = np.random.rand(50)
# 기본 플롯
fig, ax = plt.subplots()
ax.plot(data, label="Random Data")
# 눈금 없애기
ax.xaxis.set_major_locator(NullLocator()) # X축의 주요 눈금을 제거
ax.xaxis.set_major_formatter(NullFormatter()) # X축의 주요 눈금 레이블 제거
ax.yaxis.set_major_locator(NullLocator()) # Y축의 주요 눈금을 제거
ax.yaxis.set_major_formatter(NullFormatter()) # Y축의 주요 눈금 레이블 제거
# 범례 추가
ax.legend()
plt.show()
In [ ]:
[눈금 상세 설정 - MaxNLocator]¶
In [93]:
# 4x4 서브플롯 생성
fig, axs = plt.subplots(4, 4, figsize=(10, 10), sharex=True, sharey=True)
# 모든 서브플롯에 데이터와 눈금 설정 적용
for ax in axs.flat:
ax.xaxis.set_major_locator(MaxNLocator(3)) # X축에 최대 3개의 주요 눈금 설정
ax.yaxis.set_major_locator(MaxNLocator(3)) # Y축에 최대 3개의 주요 눈금 설정
ax.grid(True, linestyle='--', alpha=0.5) # 격자선 추가 (선택 사항)
# 레이아웃 조정
plt.tight_layout()
plt.show()
In [ ]:
In [ ]:
In [ ]:
[Locator와 Formatter의 분리]¶
In [107]:
# 데이터 생성
x = np.linspace(0, 3 * np.pi, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
# 플롯 생성
fig, ax = plt.subplots()
ax.plot(x, y1, lw=3, label="Sine", color="blue")
ax.plot(x, y2, lw=3, label="Cosine", color="green")
# 축 설정
ax.axis('equal') # 축 비율 동일하게
ax.set_xlim(0, 3 * np.pi) # x축 범위 설정
# Locator 설정 (x축)
ax.xaxis.set_major_locator(MultipleLocator(np.pi / 2)) # x축 주요 눈금을 π/2 간격으로 설정
ax.xaxis.set_minor_locator(MultipleLocator(np.pi / 4)) # x축 보조 눈금을 π/4 간격으로 설정
# 격자선 추가
ax.grid(True)
# 범례 추가
ax.legend(frameon=False)
# 플롯 표시
plt.show()
In [127]:
# 데이터 생성
x = np.linspace(0, 3 * np.pi, 1000)
y1 = np.sin(x)
y2 = np.cos(x)
# 플롯 생성
fig, ax = plt.subplots()
ax.plot(x, y1, label="Sine", color="blue")
ax.plot(x, y2, label="Cosine", color="green")
# 축 설정
ax.axis('equal') # 축 비율 동일하게
ax.set_xlim(0, 3 * np.pi) # x축 범위 설정
# Locator 설정 (x축)
ax.xaxis.set_major_locator(MultipleLocator(np.pi / 2)) # x축 주요 눈금을 π/2 간격으로 설정
ax.xaxis.set_minor_locator(MultipleLocator(np.pi / 4)) # x축 보조 눈금을 π/4 간격으로 설정
# Formatter 설정 (x축)
def format_func(value, tick_number):
"""x축 눈금을 π 단위로 포맷팅"""
N = int(np.round(2 * value / np.pi)) # π의 배수를 계산
if N == 0:
return "0"
elif N == 1:
return r"$\pi/2$" # 수식 표현
elif N == 2:
return r"$\pi$"
elif N % 2 > 0:
return r"${0}\pi/2$".format(N)
else:
return r"${0}\pi$".format(N // 2)
ax.xaxis.set_major_formatter(FuncFormatter(format_func)) # x축 주요 눈금 레이블에 포맷 적용
# 격자선 추가
ax.grid(True)
# 범례 추가
ax.legend(frameon=False)
# 플롯 표시
plt.show()
In [ ]:
'2학년 2학기 > 데이터 사이언스 입문' 카테고리의 다른 글
[Visualization] Colormap (0) | 2024.12.02 |
---|---|
[Visualization] Regend (0) | 2024.12.02 |
[Visualization] Contour Plot(등고선) (0) | 2024.11.26 |
[Visualization] Error Bar (0) | 2024.11.26 |
[Visualization] Scatter Plot(산점도) (0) | 2024.11.26 |