[Python] boxplot 그리기(matplotlib,seaborn)

반응형
    반응형

    matplotlib를 이용한 boxplot 그리는 방법입니다.

    boxplot에 나타내는 수치는 다섯가지로 다음 수치를 기반으로 그려집니다. 

    • 최소값 : 데이터의 0% 지점
    • 제 1사분위 수(Q1) : 데이터의 25% 지점
    • 제 2사분위 수 또는 중위수(Q2) : 데이터의 50% 지점
    • 제 3사분위 수(Q3) : 데이터의 75% 지점
    • 최대값 : 데이터의 100% 지점

    이 값들로 그려진 boxplot에서 데이터를 크기순으로 나열했을 때의 분포지점과 이상치를 알 수 있습니다.
    이상치는 $ Q3+1.5*IQR $ 보다 크거나 $ Q1-1.5*IQR$ 보다 작은 수로 나타냅니다. 여기서 IQR은 사분위수 범위로 Q3-Q1로 계산된 값입니다. 이상치로 판별된 데이터는 boxplot에서 점으로 나타나게 됩니다.

    matplotlib와 seaborn을 이용해 그리는 방법을 소개하도록 하겠습니다.

    dataset 셋팅

    sns에 내장되어 있는 penguins이라는 데이터셋을 가지고 boxplot을 그려보겠습니다.
    matplotlib와 seanborn을 임포트한 후 penguins 셋을 불러오겠습니다.

    import matplotlib.pyplot as plt
    import seaborn as sns
    penguins = sns.load_dataset('penguins')
    penguins

     

     

    펭귄에 대한 정보를 볼 수 있습니다.
    이 중에서 bill_length_mm을 가지고 boxplot을 그려보겠습니다.
    먼저 species 종끼리 비교를 하는게 좋으니 species에 따라 데이터프레임을 다시 만들겠습니다.

    category = penguins.species.unique()  # ['Adelie', 'Chinstrap', 'Gentoo']
    
    species1 = penguins[penguins['species']==category[0]]
    species2 = penguins[penguins['species']==category[1]]
    species3 = penguins[penguins['species']==category[2]]

    중간중간 NaN 값이 있는데 이를 제거해야만 boxplot을 그릴 수 있습니다. 데이터 중간에 NaN 값이 있으면 다음과 같이 텅빈 그림만 나오게 됩니다.

    dropna를 이용해 NaN 값이 있는 row 자체를 지우겠습니다.

    species1_dropna = species1.dropna()
    species2_dropna = species2.dropna()
    species3_dropna = species3.dropna()

    matploblib로 그리기

    plt.boxplot으로 바로 그릴 수 있습니다.
    반드시 plt.show()를 해주는 걸 추천합니다.
    그렇지 않으면  어떤 리스트 목록이 나온 후 그래프가 나와서 지저분하게 보입니다. 궁금하시면 plt.show()없이 해보시길 바랍니다. 이상치를 약간 다루어야 해서 이상치를 있는 데이터를 먼저 하겠습니다.

    plt.boxplot(species3_dropna[species3_dropna.columns[2]])
    plt.show()

    이렇게 그리면 밋밋합니다. 이상치 색깔과 모양을 바꾸고 제목과 라벨을 넣겠습니다.

    plt.boxplot(species3_dropna[species3_dropna.columns[2]],sym='r+')
    plt.title(f'{category[2]}')
    plt.xticks([1],[f'{species3_dropna.columns[2]}'])
    plt.show()

    sym 파라미터로 이상치에 대한 여러가지 모양과 색깔을 넣을 수 있는데 주로 쓰는 모양은 다음과 같습니다.

    • * : 별모양
    • s : 정사각형 모양
    • + : 십자가 모양
    • . : 작은 점
    • o : 큰점(디폴트값)
    • d : 다이아몬드 모양

    중앙값의 95% 신뢰구간을 표시하는 Notch 방식도 나타낼 수 있습니다.

    plt.boxplot(species3_dropna[species3_dropna.columns[2]],sym='rs',notch=1)
    plt.show()

    축을 바꿔 boxplot을 그리고 싶다면 vert=0을 입력합니다.

    plt.boxplot(species3_dropna[species3_dropna.columns[2]],sym='r.',vert=0)
    plt.show()

    여러개의 boxplot를 한꺼번에 그릴 수도 있습니다.

    fig,ax = plt.subplots()
    ax.boxplot([species1_dropna[species1_dropna.columns[2]],species2_dropna[species2_dropna.columns[2]],species3_dropna[species3_dropna.columns[2]]])
    plt.title('Species_bill_length')
    plt.xticks([1,2,3],[category[0],category[1],category[2]])
    plt.show()

    seaborn으로 그리기

    seaborn은 기본적으로 데이터프레임이라는 전제가 있어야 편리하게 사용할 수 있습니다. 물론 Series도 가능하지만 Series는 matplotlib가 더 편리하다는 느낌이 강하게 듭니다.
    데이터프레임이 훨씬 편리한 이유는 컬럼을 대상으로 x,y를 지정할 수 있습니다. 이 점이 굉장한 장점입니다.
    준비된 데이터셋인 penguins의 결측치를 제거한 후 boxplot을 그려보겠습니다.
    축을 잘 해야 하는데 x축,y축에 데이터 따라 가로 세로가 알아서 변합니다. x,y 파라미터에는 boxplot으로 표현할 컬럼의 이름을 넣어줍니다.

    penguins_dropna = penguins.dropna()
    sns.boxplot(y='bill_length_mm',x='species',data=penguins_dropna)

    x,y를 바꾸면 축이 바껴서 출력이 됩니다.

    sns.boxplot(x='bill_length_mm',y='species',data=penguins_dropna)
    plt.show()

    또 다른 범주를 섞어넣고 싶다면 hue 파라미터를 이용합니다.
    즉, 이변량으로 그려지는 게 되겠습니다.

    sns.boxplot(y='bill_length_mm',x='species',hue='island',data=penguins_dropna)
    plt.show()

    색깔을 변경하고 싶다면 palette를 이용합니다.
    palette는 팔레트(컬러맵)으로 구성됩니다.
    seaborn에 내장되어 있는 컬러맵을 사용해도 되고 본인이 직접 만들어서 해도 됩니다. 기본적으로 seaborn에 있는 팔레트가 색상이 좋기 때문에 굳이 본이이 만들지 않아도 되긴 합니다.

    sns.boxplot(y='bill_length_mm',x='species',hue='island',palette='Set3',data=penguins_dropna)
    plt.show()

    범주로 나누어 두개 이상의 boxplot 그래프를 그릴 수 있습니다. factorplot라고 했었는데 이제는 catplot으로 이름이 바뀌었습니다.
    성별별로 나누어서 boxplot을 보겠습니다.
    boxplot과 동일하지만 catplot은 boxplot만 다루는 함수가 아니기 때문에 kind='box'를 넣어주어야 하고 col 파라미터로 범주로 구별해서 따로 boxplot을 더 그려줍니다.

    sns.catplot(y='bill_length_mm',x='species',hue='island',col='sex',kind='box',data=penguins_dropna)
    plt.show()

     

    마치며

    boxplot에 대해 알아보았습니다.
    matplotlib는 기본에 충실한 boxplot을 만들 수 있고
    seaborn은 데이터프레임에 특화되었고 색감이 좋은 그래프를 만들 수 있습니다. 하지만 각 column의 특성을 잘 알아야합니다. 즉, 데이터 파악이 명확해야만 seaborn으로 다양하게 표현할 수 있습니다. 
    빠른 데이터 파악을 위해서 pandas에 내장되어 있는 plot을 이용할 수 있습니다. plot은 코드는 간단하지만 시각화가 잘 되지는 않습니다. pandas의 plot 내용은 관련포스팅에 링크를 걸어두겠습니다. 관심이 있으신 분들은 한번 보시면 좋을 것 같습니다.

     

    관련 포스팅
    pandas로 box,area,scatter 그리기

    [파이썬] 사분위수(Quantiles)란?

    댓글

    Designed by JB FACTORY

    ....