matplotlib으로 Box plot 그리기

김유정·2021년 11월 13일
0
post-thumbnail
post-custom-banner


matplotlib은 python의 데이터 시각화 라이브러리입니다.
이 라이브러리를 사용하여 아래의 그림과 같은 박스형태의 그래프(Box plot)를 그려보도록 하겠습니다.

Box plot이란?

Box plot은 수치 데이터를 표현하는 방식입니다. 우리가 흔히 아는 막대 그래프, 꺾은선 그래프, 원그래프 처럼 데이터를 표현하는 그래프입니다.
자료에서 얻어진 다섯 개의 값을 가지고 그래프를 그리게 됩니다. 다섯 개의 값은 다음과 같습니다.

  1. 최솟값
  2. 제 1사분위(Q1, Quartiles1) : 25%의 위치를 의미
  3. 제 2사분위(Q2, Quartiles2) : 중앙값을 의미
  4. 제 3사분위(Q3, Quartiles3) : 75%의 위치를 의미
  5. 최댓값

위의 값들을 가지고 Boxplot이 어떻게 그려지는지 간단하게 보도록 하겠습니다.
그 전에 IQR에 대해 짚고 넘어가겠습니다.
IQR은 사분위의 범위에 해당하는 수입니다. 범위는 Q1 부터 Q3이기 때문에 IQR은 아래와 같이 구할 수 있습니다.

IQR = Q3 - Q1


이미지 출처 : https://www.simplypsychology.org/boxplots.html

먼저 Q1과 Q3의 범위에 해당하는 박스가 그려집니다.
그리고 박스와 최솟값, 최댓값을 잇는 수평으로 그어진 선을 수염(whisker)라고 합니다. 그래서 Boxplot을 Box-and-whisker plot(상자수염그림)이라고도 합니다.

다섯 개의 값(Five-number-summary) 구하기

이 부분은 맨아래 첨부한 Khan Academy의 설명을 번역한 것입니다.

sample = [25, 28, 29, 29, 30, 34, 35, 35, 37, 38]

1. 오름차순으로 정렬하기

값을 구하기 전에 먼저 오름차순으로 정렬을 해야합니다. sample은 이미 정렬된 상태입니다.

2. 중위수(median) 찾기

현재 샘플에는 짝수 개의 데이터가 있기 때문에 가운데 두 값을 더해서 2로 나눠줄겁니다.

25, 28, 29, 29, 30, 34, 35, 35, 37, 38
(30+34)/2 = 32
→ 중앙값 = 32

3. 사분위 값(quartiles) 찾기

저는 처음에 "사분위"라는 말이 조금 낯설었는데요. 백분위가 데이터를 백등분 한 것이니까 사분위는 데이터를 4등분한 것이라 생각하면 됩니다.

  • 제 1사분위(Q1, Quartiles1)
    중위수 왼쪽에 있는 데이터들의 중간값
    25, 28, 29, 29, 30,
    → Q1 = 29
  • 제 3사분위(Q3, Quartiles3)
    중위수 오른쪽에 있는 데이터들의 중간값
    34, 35, 35, 37, 38
    → Q3 = 35

4. 최솟값, 최댓값을 구하고 Five-number-summary 완성하기

Boxplot은 Q1 - 1.5*IQR 에서부터 Q3 + 1.5*IQR의 범위 내에서 그려집니다.
만약 데이터 중 가장 작은 값이 Q1 - 1.5*IQR 값보다 작다면 범위에서 벗어나기 때문에,
Q1 - 1.5*IQR가 최솟값이 됩니다.
데이터 중 가장 큰 값이 Q3 + 1.5*IQR보다 크다면 범위에서 벗어나기 때문에,
Q3 + 1.5*IQR가 최댓값이 됩니다.
범위에서 벗어나는 값을 이상치(outlier)라고 하며 아래의 그림과 같이 boxplot의 위나 아래에 동그란 점으로 표시됩니다.

이미지 출처 : https://codetorial.net/matplotlib/box_plot.html

  • 최솟값 구하기
    샘플 데이터에서 가장 작은 값 : 25
    Q1 - 1.5*IQR = 29 - 1.5*(35-29) = 29 - 9 = 20
    25는 Boxplot이 그려지는 범위 내에 있는 값이기 때문에 25가 최솟값이 됩니다.
  • 최댓값 구하기
    샘플 데이터에서 가장 큰 값 = 38
    Q3 + 1.5*IQR = 35 + 1.5*(35-29) = 35 + 9 = 44
    38은 범위 내에 있는 값이기 때문에 38이 최댓값이 됩니다.

결과적으로 아래와 같은 그래프가 그려지게 됩니다. 중위수에는 노란색 선(Whisker)이 그려집니다.

matplotlib으로 Box plot 그리는 방법

이번에는 다른 데이터를 가지고 Box plot을 그려보겠습니다.
가장 기본적인 코드는 아래와 같습니다.

import matplotlib.pyplot as plt

plt.boxplot([데이터리스트1, 데이터리스트2, ...])

notch, whis, vert와 같은 다양한 옵션들이 있으니 더 많은 옵션이 궁금하시다면 아래의 링크를 참고하시면 됩니다.
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.boxplot.html

  • 전체 코드
import numpy as np
import matplotlib.pyplot as plt

# random으로 5개의 정수 생성
np.random.seed(0)
i1 = np.random.randint(99, size=5)

np.random.seed(1)
i2 = np.random.randint(99, size=5)

print('i1 :', i1)
print('i2 :', i2)

# Boxplot 그리기
plt.boxplot([i1, i2])

# X축 설정
plt.xticks([1, 2],['i1', 'i2'])

# Y축 설정
plt.ylabel('Value')
plt.ylim(0, 100)
  • 결과

    i1에서는 median(중위수) = 64, Q1 = 47, Q3 = 67 입니다.
    i2에서는 median(중위수) = 37, Q1 = 12, Q3 = 72 입니다.
    i1의 경우 최댓값과 Q3가 같아서 위쪽 수염이 안그려졌네요.

참고

https://wikidocs.net/141959
https://matplotlib.org/stable/gallery/statistics/boxplot_demo.html?highlight=boxplot
https://www.khanacademy.org/math/statistics-probability/summarizing-quantitative-data/box-whisker-plots/a/box-plot-review

post-custom-banner

0개의 댓글