본문 바로가기
Python/matplotlib

[matplotlib] patches: 도형 그리기.

by ds31x 2024. 3. 18.
728x90
반응형

patches 는 모듈은

Artist 의 subclass인 Patch 클래스들을 제공하여,

다음의 다양한  2D 도형을 쉽게 그릴 수 있게 해줌.

  • Arc (호),
  • Circle (원),
  • CirclePolygon (원의 근사 다각형),
  • Ellipse (타원),
  • Arrow (화살표),
  • FancyArrow (모양 변경 기능이 좀 더 보강된 화살표),
  • Rectangle (사각형),
  • RegularPolygon (정규다각형), 
  • PathPatch 등등 

 

다음 그림은 Artist와 Patch, 그리고 patches에서 실제 사용되는 다양한 도형을 추상화한 클래스간의 상속관계를 보여줌.

ref. https://matplotlib.org/stable/api/patches_api.html

간단히 말하면,
Patch는
face color와 edge color를 가지는
Artist 임.

 


예제: 원그리기.

간단하게 Circle을 이용하여 원을 그리는 예제는 다음과 같음.

import matplotlib.pyplot as plt
import matplotlib.patches as patches

# 원의 중심 좌표와 반지름 설정
c_pnt = (0.5, 0.5)
r = 0.4

# Figure와 Axes 생성
fig, ax = plt.subplots(figsize=(5,5))

# 원 생성
circle = patches.Circle(
    c_pnt, 
    r, 
    edgecolor='r', 
    facecolor='none',
    )

# 원을 Axes에 추가
ax.add_patch(circle)

# 축 범위 설정
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

# 그래프 표시
plt.show()

 

위의 코드에서는 Axes객체인 ax에 포함시키는 과정이 ax.add_patch 메서드로 이루어짐.

 

결과는 다음과 같음.

여러 도형에 대한 예는 다음을 참고

import matplotlib.pyplot as plt
import matplotlib.patches as patches

# Figure와 Axes 생성 (캔버스와 그리는 영역)
fig, ax = plt.subplots(figsize=(6, 6))

# 1. 원 (Circle)
circle = patches.Circle(
    xy=(0.3, 0.7),       # 중심 좌표 (x, y)
    radius=0.1,          # 반지름
    edgecolor='r',       # 외곽선 색
    facecolor='none'     # 내부 색 없음 (투명)
)

# 2. 타원 (Ellipse)
ellipse = patches.Ellipse(
    xy=(0.7, 0.7),       # 중심 좌표
    width=0.3,           # 가로 길이
    height=0.15,         # 세로 길이
    angle=30,            # 회전 각도 (도 단위)
    edgecolor='g',       # 외곽선 색
    facecolor='lightgreen'  # 내부 색
)

# 3. 사각형 (Rectangle)
rectangle = patches.Rectangle(
    xy=(0.1, 0.1),       # 왼쪽 아래 꼭짓점 좌표
    width=0.3,           # 너비
    height=0.2,          # 높이
    edgecolor='b',       # 외곽선 색
    facecolor='lightblue'  # 내부 색
)

# 4. 정육각형 (RegularPolygon)
hexagon = patches.RegularPolygon(
    xy=(0.7, 0.2),       # 중심 좌표
    numVertices=6,       # 꼭짓점 수 (6각형)
    radius=0.1,          # 외접원의 반지름
    edgecolor='m',       # 외곽선 색
    facecolor='lavender'  # 내부 색
)

# 5. 화살표 (FancyArrow)
arrow = patches.FancyArrow(
    x=0.5, y=0.5,         # 시작점 좌표
    dx=0.3, dy=0.0,       # x, y 방향으로의 길이
    width=0.02,           # 화살표 몸통의 두께
    color='orange'        # 전체 색상
)

# 도형들을 Axes에 추가
for shape in [circle, ellipse, rectangle, hexagon, arrow]:
    ax.add_patch(shape)

# 축 설정
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect('equal')  # 비율 고정 (원형 유지)
plt.title("여러 Patch 도형 예제")
plt.show()


참고로 복수개의 patch를 추가하려면,

  • matplotlib.collections 모듈의 PatchCollection
  • Axes객체의 add_collection을 이용하는게 효율적임.

예제는 다음과 같음

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.collections import PatchCollection
import numpy as np

# Figure와 Axes 생성
fig, ax = plt.subplots(figsize=(6, 6))

patches_list = []  # Circle 객체들을 담을 리스트

# 난수 고정 (재현성 확보)
np.random.seed(0)

# 원 20개 생성
for _ in range(20):
    center = np.random.rand(2)        # 중심 좌표: (x, y), [0.0 ~ 1.0)
    radius = np.random.rand() * 0.05 + 0.02  # 반지름: 0.02 ~ 0.07
    circle = patches.Circle(
        center,   # 중심 좌표
        radius    # 반지름
    )
    patches_list.append(circle)  # 리스트에 추가

# PatchCollection 생성
collection = PatchCollection(
    patches_list,          # 도형 객체들 리스트
    edgecolor='black',     # 외곽선 색상
    facecolor='skyblue',   # 내부 색상
    alpha=0.7              # 투명도
)

# 컬렉션을 Axes에 추가
ax.add_collection(collection)

# 축 설정
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect('equal')
plt.title("PatchCollection을 이용한 원 배열")
plt.show()


참고자료.

https://matplotlib.org/stable/api/patches_api.html

https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.Circle.html

 

matplotlib.patches.Circle — Matplotlib 3.8.3 documentation

{'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}

matplotlib.org

https://zephyrus1111.tistory.com/402

 

[Matplotlib] Tip! add_patch와 PatchCollection 비교

안녕하세요~ 꽁냥이에요. Matplotlib에서는 Patch라는 개념이 있는데요. 이는 도형이라고 생각하면 됩니다. 이러한 Patch를 추가할 때에는 add_patch를 사용하는데요. 만약 수많은 Patch를 추가한다면 add_p

zephyrus1111.tistory.com