더 이상 tistory 블로그를 운영하지 않습니다. glanceyes.github.io에서 새롭게 시작합니다.

새소식

Data Science/데이터 시각화

Matplotlib 모듈로 Chart를 그리기 위한 팁

  • -

 

2022년 2월 3일(목)부터 4일(금)까지 네이버 부스트캠프(boostcamp) AI Tech 강의를 들으면서 개인적으로 중요하다고 생각되거나 짚고 넘어가야 할 핵심 내용들만 간단하게 메모한 내용입니다. 틀리거나 설명이 부족한 내용이 있을 수 있으며, 이는 학습을 진행하면서 꾸준히 내용을 수정하거나 추가해 나갈 예정입니다.

 

 

More Tips for Chart

Grid 이해하기

기본적인 Grid는 축과 평행한 선을 사용하여 거리 및 값 정보를 보조적으로 제공한다.

 

Grid의 요소

다음은 기본적인 Grid의 요소이다.

 

color

색은 다른 표현들을 방해하지 않도록 무채색으로 만든다.

 

zorder

항상 Layer 순서 상 맨 밑에 오도록 조정한다.

 

예시 코드

np.random.seed(970725)

x = np.random.rand(20)
y = np.random.rand(20)


fig = plt.figure(figsize=(16, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)


ax.scatter(x, y, s=150, 
           c='#1ABDE9',
           linewidth=1.5,
           edgecolor='black', zorder=10)

# xticks에 값이 직접 명시지는 않는 minor한 tick을 추가할 수도 있다.
ax.set_xticks(np.linspace(0, 1.1, 12, endpoint=True), minor=True)

ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)

    
ax.grid(zorder=0, linestyle='--')    
ax.set_title(f"Default Grid", fontsize=15,va= 'center', fontweight='semibold')

plt.tight_layout()
plt.show()

1644932216948

 

 

which = 'major', 'minor', 'both'

큰 격자와 세부 격자를 나눈다.

 

예시 코드

ax.grid(zorder=0, linestyle='--', which = 'both')

 

axis = 'x', 'y', 'both'

$x$축 따로, $y$축 따로, 동시에 등 격자 축을 다양하게 그릴 수 있다.

 

 

다양한 Type의 Grid

$x + y = c$를 사용한 Grid

Feature의 절대적 합이 중요한 경우에 사용한다.

 

예시 코드

fig = plt.figure(figsize=(16, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)

# x + y < 1인 것과 x + y ≥ 1인 것의 색상을 각각 하늘색, 회색으로 다르게 설정한다.
ax.scatter(x, y, s=150, 
           c=['#1ABDE9' if xx+yy < 1.0 else 'darkgray' for xx, yy in zip(x, y)],
           linewidth=1.5,
           edgecolor='black', zorder=10)

## Grid Part
# Grid의 간격을 설정한다.
x_start = np.linspace(0, 2.2, 12, endpoint=True)

# 절편을 이용해서 사선인 Grid 그리는 방법
for xs in x_start:
    ax.plot([xs, 0], [0, xs], linestyle='--', color='gray', alpha=0.5, linewidth=1)


ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)

ax.set_title(r"Grid ($x+y=c$)", fontsize=15,va= 'center', fontweight='semibold')

plt.tight_layout()
plt.show()

1644932226891

 

 

$y = cx$를 사용한 Grid

가파를수록 $y/x$가 커진다.

Feature의 비율이 중요한 경우에 사용한다.

 

예시 코드

fig = plt.figure(figsize=(16, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)


ax.scatter(x, y, s=150, 
           c=['#1ABDE9' if yy/xx >= 1.0 else 'darkgray' for xx, yy in zip(x, y)],
           linewidth=1.5,
           edgecolor='black', zorder=10)

## Grid Part
radian = np.linspace(0, np.pi/2, 11, endpoint=True)

for rad in radian:
    # (0, 0)와 (2, 2tan(rad))를 연결하는 line plot을 그린다.
    ax.plot([0,2], [0, 2*np.tan(rad)], linestyle='--', color='gray', alpha=0.5, linewidth=1)


ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)

ax.set_title(r"Grid ($y=cx$)", fontsize=15,va= 'center', fontweight='semibold')

plt.tight_layout()
plt.show()

1644932254826

 

 

동심원인 $(x-x)^2+(y-y')^2=c$을 사용한 Grid

특정 지점에서 거리를 살펴볼 수 있다.

가장 가까운 포인트를 찾거나 한 데이터에서 특정 범위의 데이터를 찾을 때 사용한다.

 

예시 코드

fig = plt.figure(figsize=(16, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)


ax.scatter(x, y, s=150, 
           c=['darkgray' if i!=2 else '#1ABDE9'  for i in range(20)] ,
           linewidth=1.5,
           edgecolor='black', zorder=10)

## Grid Part
rs = np.linspace(0.1, 0.8, 8, endpoint=True)

for r in rs:
    # line plot을 이용해서 곡선 그리기
    xx = r*np.cos(np.linspace(0, 2*np.pi, 100))
    yy = r*np.sin(np.linspace(0, 2*np.pi, 100))
    # (x[2], y[2])를 동심원의 중심으로 둔다.
    ax.plot(xx+x[2], yy+y[2], linestyle='--', color='gray', alpha=0.5, linewidth=1)

    # 오른쪽 45도 아래로 동심원 별로 텍스트를 추가
    ax.text(x[2]+r*np.cos(np.pi/4), y[2]-r*np.sin(np.pi/4), f'{r:.1}', color='gray')

ax.set_xlim(0, 1.1)
ax.set_ylim(0, 1.1)

ax.set_title(r"Grid ($(x-x')^2+(y-y')^2=c$)", fontsize=15,va= 'center', fontweight='semibold')

plt.tight_layout()
plt.show()

1644932268722

 

 

 

심플한 처리

선 추가하기

axvline()axhline()를 사용해서 직교좌표계에서 평행선을 원하는 곳에 그릴 수 있다.

선은 line plot으로 그리는게 더 편할 수 있기에 원하는 방식으로 그리면 된다.

fig, ax = plt.subplots()

ax.set_aspect(1)
ax.axvline(0, color='red')
ax.axhline(0, color='green')

ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)

plt.show()

1644932278639

 

 

fig, ax = plt.subplots(figsize=(10, 10))
ax.set_aspect(1)

math_mean = student['math score'].mean()
reading_mean = student['reading score'].mean()

ax.axvline(math_mean, color='gray', linestyle='--')
ax.axhline(reading_mean, color='gray', linestyle='--')

# 원하는 영역에 속하는 점들을 조건 분기문을 이용해 royalblue 색으로 칠한다.
ax.scatter(x=student['math score'], y=student['reading score'],
           alpha=0.5,
           color=['royalblue' if m>math_mean and r>reading_mean else 'gray'  for m, r in zip(student['math score'], student['reading score'])],
           zorder=10,
          )

ax.set_xlabel('Math')
ax.set_ylabel('Reading')

ax.set_xlim(-3, 103)
ax.set_ylim(-3, 103)
plt.show()

1644932288097

 

 

면 추가하기

axvspanaxhspan를 사용해서 선과 함께 다음과 같이 특정 부분 면적을 표시할 수 있다.

fig, ax = plt.subplots()

ax.set_aspect(1)
ax.axvspan(0,0.5, color='red')
ax.axhspan(0,0.5, color='green')

ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)

plt.show()

1644932303508

 

fig, ax = plt.subplots(figsize=(8, 8))
ax.set_aspect(1)

math_mean = student['math score'].mean()
reading_mean = student['reading score'].mean()

ax.axvspan(-3, math_mean, color='gray', linestyle='--', zorder=0, alpha=0.3)
ax.axhspan(-3, reading_mean, color='gray', linestyle='--', zorder=0, alpha=0.3)

ax.scatter(x=student['math score'], y=student['reading score'],
           alpha=0.4, s=20,
           color=['royalblue' if m>math_mean and r>reading_mean else 'gray'  for m, r in zip(student['math score'], student['reading score'])],
           zorder=10,
          )

ax.set_xlabel('Math')
ax.set_ylabel('Reading')

ax.set_xlim(-3, 103)
ax.set_ylim(-3, 103)
plt.show()

1644932319629

 

축 조정하기

ax.spines를 통해 서브 플롯을 감싸는 축(또는 변)을 변형할 수 있으며, 많은 요소가 있지만 그중 대표적인 세 가지 요소는 다음과 같다.

 

set_visible

예시 코드

fig = plt.figure(figsize=(12, 6))

_ = fig.add_subplot(1,2,1)
ax = fig.add_subplot(1,2,2)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_linewidth(1.5)
ax.spines['bottom'].set_linewidth(1.5)
plt.show()

1644932329198

 

set_linewidth

 

set_position

center 등의 문자열로 축의 위치를 지정할 수 있다.

.set_position(('data', 0.3))처럼 원하는 축의 특정 지점을 지나는 축을 그릴 수도 있다.

.set_position(('axes', 0.2))처럼 원하는 축의 비율을 지나는 축을 그릴 수도 잇다.

 

예시 코드

fig = plt.figure(figsize=(12, 6))

_ = fig.add_subplot(1,2,1)
ax = fig.add_subplot(1,2,2)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
plt.show()

1644932338082

 

 

 

Setting 바꾸기

mpl.rc로 미리 설정하기

mpl로 해도 되고, plt로 해도 된다.

import matplotlib as mpl
import matplotlib.pyplot as plt

 

아래 두 방법은 같은 설정 방법이다.

plt.rcParams['lines.linewidth'] = 2
plt.rcParams['lines.linestyle'] = ':'
plt.rc('lines', linewidth=2, linestyle=':')

 

다음과 같이 해상도를 바꿀 수도 있다.

plt.rcParams['figure.dpi'] = 150

 

파라미터를 설정한 후 이를 Default Setting로 업데이트 해준다.

plt.rcParams.update(plt.rcParamsDefault)

 

 

Theme 사용하기

fivethirtyeight, ggplot등 다양한 Theme를 사용할 수 있다.

mpl.style.use('seaborn')

 

한 그래프에 대해서만 스타일을 적용하려면 다음과 같이 한다.

with plt.style.context('fivethirtyeight'):
    plt.plot(np.sin(np.linspace(0, 2 * np.pi)))
plt.show()

 

Contents

글 주소를 복사했습니다

부족한 글 끝까지 읽어주셔서 감사합니다.
보충할 내용이 있으면 언제든지 댓글 남겨주세요.