산점도 (Scatter plot) 가 두 변수 간의 관계를 2차원(2D으로 시각화해서 볼 수 있는 그래프라면, 버블 그래프(Bubble chart)는 산점도에 버블의 크기와 색깔을 추가하여 3차원(3D) 또는 4차원(4D)의 정보를 2차원에 시각화해서 볼 수 있는 그래프입니다. 그리고 시간 축을 추가하여 애니메이션 형태의 버블 그래프를 그린다면 5차원(5D)의 시각화도 가능합니다. 

 

이번 포스팅에서는 Python의 matplotlib, seaborn, plotly, bubbly 등의 시각화 모듈을 이용해서 버블 그래프를 그리는 방법을 소개하겠습니다. 

 

(1) matplotlib 으로 버블 그래프 그리기 (Bubble chart using Matplotlib)

(2) seaborn 으로 버블 그래프 그리기 (Bubble chart using Seaborn)

(3) plotly 로 동적인 버블 그래프 그리기 (Interactive Bubble chart using Plotly)

(4) bubbly 로 시간의 흐름에 따라 변화하는 버블 그래프 그리기 (Animated Bubble chart using bubbly)

 

 

plotly 모듈에 들어있는 Gapminder  Global Indicator 데이터셋을 대상으로 버블 그래프를 그려보겠습니다. x 축에는 gpdPercap, y 축에는 lifeExp 를 사용하겠으며, pop 에 비례해서 버블의 크기를 조절하고, continent 에 따라서 버블의 색깔을 다르게 해보겠습니다. 

 

## importing modules
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import pandas as pd
import numpy as np

## getting dataset
df = px.data.gapminder()


df.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 1704 entries, 0 to 1703
# Data columns (total 8 columns):
#  #   Column     Non-Null Count  Dtype  
# ---  ------     --------------  -----  
#  0   country    1704 non-null   object 
#  1   continent  1704 non-null   object 
#  2   year       1704 non-null   int64  
#  3   lifeExp    1704 non-null   float64
#  4   pop        1704 non-null   int64  
#  5   gdpPercap  1704 non-null   float64
#  6   iso_alpha  1704 non-null   object 
#  7   iso_num    1704 non-null   int64  
# dtypes: float64(2), int64(3), object(3)
# memory usage: 106.6+ KB


df.head(3)
# 	country	continent	year	lifeExp	pop	gdpPercap	iso_alpha	iso_num
# 0	Afghanistan	Asia	1952	28.801	8425333	779.445314	AFG	4
# 1	Afghanistan	Asia	1957	30.332	9240934	820.853030	AFG	4
# 2	Afghanistan	Asia	1962	31.997	10267083	853.100710	AFG	4


df.year.max() # ==> keep year 2007
# 2007


df.gdpPercap.describe()   # right-skewed => log scaling
# count      1704.000000
# mean       7215.327081
# std        9857.454543
# min         241.165877dd
# 25%        1202.060309
# 50%        3531.846989
# 75%        9325.462346
# max      113523.132900
# Name: gdpPercap, dtype: float64

 

 

(1) matplotlib 으로 버블 그래프 그리기 (Bubble chart using Matplotlib)

 

matplotlib.pyplot.scatter() 메소드를 사용해서 산점도를 그리면서, 버블의 크기(s)와 색깔(c)을 추가로 지정해주면 됩니다. continent 별로 색깔을 다르게 지정해주었는데요, 아래의 범례(plt.legend()) 설정 방법 참고하세요. alpha=0.5 로 버블이 겹쳤을 때 파악할 수 있도록 투명도를 설정해주었습니다. 

 

x축의 gdpPercap 변수가 왼쪽으로 값이 많이 쏠려있는 형태를 띠고 있으므로 plt.xscale('log') 을 사용해서 x축을 로그 변환 (log transformation) 해주었습니다. plt.grid() 로 점선을 사용해서 그리드 선을 추가해주었습니다. 

 

## (1) Bubble chart with Matplotlib
fig = plt.figure(figsize=(16, 9))
df_2007 = df[df['year']==2007]

ax = plt.scatter(
    x = df_2007['gdpPercap'], 
    y = df_2007['lifeExp'], 
    s = df_2007['pop']/300000, 
    c = pd.Categorical(df_2007['continent']).codes, 
    cmap = "Accent", 
    alpha = 0.5, 
    edgecolors = "gray", 
    linewidth = 1);

plt.xscale('log') # log scaling
plt.xlabel("GDP per Capita")
plt.ylabel("Life Expectancy")
plt.title('Gapminder Global Indicators with Matplotlib', fontsize=16)
plt.grid(True, which='major', linestyle='--', linewidth=0.5)
## setting legend using colors in matplotlib scatter plot
plt.legend(
    handles=ax.legend_elements()[0], 
    labels=['Asia', 'Europe', 'Africa', 'Americas', 'Oceania'])

plt.show()

bubble chart using matplotlib

 

 

 

(2) seaborn 으로 버블 그래프 그리기 (Bubble chart using Seaborn)

 

위의 matplotlib 대비 seaborn.scatter() 메소드는 x축, y축, size, hue(그룹별 색깔 구분) 을 각각 지정해줄 수 있어서 비슷한데요, legend=True 로 지정해주면 size 와 hue (그룹별 색깔 구분) 에 대한 범례를 자동으로 추가해주어서 편리합니다. 

 

## (2) Bubble chart with Seaborn
fig = plt.figure(figsize=(16, 9))
df_2007 = df[df['year']==2007]

sns.scatterplot(
    data = df_2007, 
    x = "gdpPercap", 
    y = "lifeExp", 
    size = "pop", 
    hue = "continent",
    legend = True, 
    sizes = (20, 2000) ,
    alpha=0.5
)

plt.xscale('log') # log scaling
plt.xlabel("GDP per Capita")
plt.ylabel("Life Expectancy")
plt.title('Gapminder Global Indicators with Seaborn', fontsize=16)
plt.grid(True, which='major', linestyle='--', linewidth=0.5)
plt.show()

bubble chart using seaborn

 

 

 

(3) plotly 로 동적인 버블 그래프 그리기 (Interactive Bubble chart using Plotly)

 

plotly 는 위의 matplotlib, seaborn 대비 사용자가 커서를 사용해서 동적으로 버블 그래프(interactive bubble chart)를 조회할 수 있다는 점입니다. hover_name="country" 를 지정해주면 버블 위에 커서를 가져다 놓을 경우 국가 이름과 함께 x축, y축, 버블 크기, 색깔 지정 정보를 팝업 메시지로 보여줍니다. 그리고 커서로 블록을 설정해주면 해당 블록에 대해 줌인(zoom in) 해서 확대해주는 기능도 있습니다. 그 외에 첫번째 줄의 df.query("year==2007") 처럼 px.scatter() 함수 안에서 데이터의 subset 을 query 해서 쓸 수 있으며, log_x = True 를 설정하면 x축의 값을 로그 변환하도록 설정해줄 수도 있습니다. 코드가 매우 깔끔하고 그래프가 이쁜데다 동적이기까지 해서 가독성이 매우 뛰어나기 때문에 왠만하면 matplotlib 이나 seaborn 대신에 plotly 를 사용하는 것이 사용자 입장에서는 좋을 것 같아요. 

 

## (3) Bubble chart with Plotly
import plotly.express as px

fig = px.scatter(
    df.query("year==2007"), 
    x="gdpPercap", 
    y="lifeExp",
    size="pop", 
    color="continent",
    hover_name="country", 
    log_x=True, 
    title='Gapminder Global Indicators with Plotly',
    size_max=60,
    height=650)

fig.show()

 

아래의 Plotly 로 그린 버블 그래프의 버블 위에 커서를 가져가면 뜨는 캡션 정보와, 커서로 블록을 선정해서 hover 해서 zoom in 하는 모습을 화면 녹화한 것이예요. 코드 몇줄로 이게 된다는게 신기하지요?! plotly 짱! ^^

 

 

 

 

(4) bubbly 로 시간의 흐름에 따라 변화하는 버블 그래프 그리기 (Animated Bubble chart using bubbly)

 

이번에는 시간 축을 추가 (adding timestamp axis)해서 시간의 흐름에 따라서 버블 그래프가 변화하는 애니메이션을 시각화 해보겠습니다. bubbly 모듈의 bubbleplot() 메소드를 사용하며, time_column='year' 에 년도(year)를 시간 축으로 설정해주었습니다. x축은 x_column, y축은 y_column, 버블 크기는 size_column, 버블 색깔은 color_column 로 설정해주면 됩니다. x_logscale=True 로 x축 값을 로그 변환해주었으며, scale_bubble=3 으로 버블의 스케일을 지정해주었습니다. 

 

#!pip install bubbly

## (4) Animated Bubble Chart
## Using the function bubbleplot from the module bubbly(bubble charts with plotly)
## ref: https://github.com/AashitaK/bubbly

from bubbly.bubbly import bubbleplot 
from __future__ import division
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode()

figure = bubbleplot(
    dataset=df, 
    x_column='gdpPercap', 
    y_column='lifeExp', 
    bubble_column='country', 
    time_column='year', 
    size_column='pop', 
    color_column='continent', 
    x_title="GDP per Capita", 
    y_title="Life Expectancy", 
    title='Animated Gapminder Global Indicators with Bubbly',
    x_logscale=True, 
    scale_bubble=3, 
    height=650)

iplot(figure, config={'scrollzoom': True})

 

 

아래는 애니메이션 버블 차트를 실행시킨 모습을 화면 녹화한 것이예요. 왼쪽 하단의 'Play' 버튼을 누르면 애니메이션이 실행이 되면서 년도의 순서대로 버블 차트가 변화는 것을 볼 수 있습니다. 신기하지요?! ^^ bubbly 짱!! (bubbly 의 백본이 plotly 이므로 역시 plotly 짱!!)

 

 

 

 

이번 포스팅이 많은 도움이 되었기를 바랍니다. 

행복한 데이터 과학자 되세요!  :-)

 

반응형
Posted by Rfriend

댓글을 달아 주세요

이번 포스팅은 두 개의 연속형 변수에 대한 관계를 파악하는데 유용하게 사용할 수 있는 산점도(Scatter Plot) 의 세번째 포스팅으로서 4개의 연속형 변수를 사용하여 X축, Y축, 점의 색깔(color)과 크기(size)을 다르게 하는 방법을 소개합니다. 


즉, 산점도를 사용하여 4차원의 데이터를 2차원에 시각화하는 방법입니다. 




(1) 산점도 (Scatter Plot)

(2) 그룹별 산점도 (Scatter Plot by Groups)

(3) 4개 변수로 점의 크기와 색을 다르게 산점도 그리기 (Scatter plot with different size, color)

(4) 산점도 행렬 (Scatter Plot Matrix)

 



예제로 활용할 데이터는 iris 의 4개의 연속형 변수들입니다. 



# importing libraries

import numpy as np

import pandas as pd


import matplotlib.pyplot as plt

import seaborn as sns

plt.rcParams['figure.figsize'] = [10, 8] # setting figure size

 


 

# loading 'iris' dataset from seaborn

iris = sns.load_dataset('iris')

iris.shape

(150, 5)


iris.head()

sepal_lengthsepal_widthpetal_lengthpetal_widthspecies
05.13.51.40.2setosa
14.93.01.40.2setosa
24.73.21.30.2setosa
34.63.11.50.2setosa
45.03.61.40.2setosa





  (1) matplotlib에 의한 4개 연속형 변수를 사용한 산점도 (X축, Y축, 색, 크기)


plt.scatter() 함수를 사용하며, 점의 크기는 s, 점의 색깔은 c 에 변수를 할당해주면 됩니다. 



# 4 dimensional scatter plot with different size & color

plt.scatter(iris.sepal_length, # x

           iris.sepal_width, # y

           alpha=0.2, 

           s=200*iris.petal_width, # marker size

           c=iris.petal_length, # marker color

           cmap='viridis')

plt.title('Scatter Plot with Size(Petal Width) & Color(Petal Length)', fontsize=14)

plt.xlabel('Sepal Length', fontsize=12)

plt.ylabel('Sepal Width', fontsize=12)

plt.colorbar()

plt.show()





점(marker)의 모양을 네모로 바꾸고 싶으면 marker='s' 로 설정해주면 됩니다. 



# 4 dimensional scatter plot with different size & color

plt.scatter(iris.sepal_length, # x

           iris.sepal_width, # y

           alpha=0.2, 

           s=200*iris.petal_width, # marker size

           c=iris.petal_length, # marker color

           cmap='viridis'

           marker = 's') # square shape

plt.title('Size(Petal Width) & Color(Petal Length) with Square Marker', fontsize=14)

plt.xlabel('Sepal Length', fontsize=12)

plt.ylabel('Sepal Width', fontsize=12)

plt.colorbar()

plt.show()

 





  (2) seaborn에 의한 4개 연속형 변수를 사용한 산점도 (X축, Y축, 색, 크기)


seaborn 의 산점도 코드는 깔끔하고 이해하기에 쉬으며, 범례도 잘 알아서 색깔과 크기를 표시해주는지라 무척 편리합니다. 



# 4 dimensional scatter plot by seaborn

sns.scatterplot(x='sepal_length', 

                y='sepal_width', 

                hue='petal_length',

                size='petal_width',

                data=iris)

plt.show()





  (3) pandas에 의한 4개 연속형 변수를 사용한 산점도 (X축, Y축, 색, 크기)


pandas의 DataFrame에 plot(kind='scatter') 로 해서 color=iris['petal_length']로 색깔을 설정, s=iris['petal_width'] 로 크기를 설정해주면 됩니다. pandas 산점도 코드도 깔끔하고 이해하기 쉽긴 한데요, 범례 추가하기가 쉽지가 않군요. ^^; 



iris.plot(kind='scatter'

          x='sepal_length', 

          y='sepal_width', 

          color=iris['petal_length'],

          s=iris['petal_width']*100)


plt.title('Size(Petal Width) & Color(Petal Length) with Square Marker', fontsize=14)

plt.show()




참고로, 산점도의 점(marker)의 모양(shape)을 설정하는 심벌들은 아래와 같으니 참고하시기 바랍니다. 



# set the size

plt.rcParams['figure.figsize'] = [10, 8]


# remove ticks and values of axis

plt.xticks([])

plt.yticks([])


# markers' shape

all_shape=['.','o','v','^','>','<','s','p','*','h','H','D', 'd', '', '', '']


num = 0

for x in range(1, 5):

    for y in range(1, 5):

        num += 1

        

        plt.plot(x, y, 

                 marker = all_shape[num-1], 

                 markerfacecolor='green', 

                 markersize=20, 

                 markeredgecolor='black')

        

        plt.text(x+0.1, y, 

                 all_shape[num-1], 

                 horizontalalignment='left', 

                 size='medium', 

                 color='black', 

                 weight='semibold')

        

plt.title('Markers', fontsize=20)        

plt.show()



많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. ^^


다음번 포스팅에서는 산점도 행렬 (Scatter Plot Matrix) 에 대해서 소개하겠습니다. 



반응형
Posted by Rfriend

댓글을 달아 주세요

  1. 곰가 2020.12.11 02:44  댓글주소  수정/삭제  댓글쓰기

    안녕하세요
    (2) seaborn에 의한 4개 연속형 변수를 사용한 산점도 (X축, Y축, 색, 크기)

    에서 hue 옵션으로 범례를 지정하고 0.0만 회색으로 지정하고 나머지는 기존과 동일하게 자동으로 들어가게 코드를 작성하려고하면 어떤식으로 하면좋을지 여쭤봅니다.

    • Rfriend 2020.12.11 20:03 신고  댓글주소  수정/삭제

      안녕하세요.

      원래의 데이터에 조건절을 사용해서 color 라는 칼럼을 추가해주고, seaborn으로 그래프 그릴 때 hue에 새로만든 color 칼럼을 넣어주면 되겠네요. (legend=False 옵션 추가해주었습니다.)

      import seaborn as sns
      import pandas as pd
      import numpy as np
      import matplotlib.pyplot as plt
      plt.rcParams['figure.figsize'] = [10, 8]

      df['color'] = np.where(df.x == 0.0, 'gray', df.x)

      sns.scatterplot(x='x',
      y='y',
      hue='color',
      size='z',
      legend=False,
      data=df)
      plt.show()

이번 포스팅에서는 하나의 연속형 변수에 대해서 분포 형태, 퍼짐정도, 이상치 여부 등을 시각화하고, 하나의 그룹 혹은 여러개의 그룹 간 비교하는데 유용한 상자 그림 (Box plot, Box-and-Whisker Plot)을 그리는 방법을 소개하겠습니다. 


상자 그림은 연속형 변수에 대해서 최소값(min), 제 1사분위수(Q1), 중앙값(Q2, median), 제 3사분위수(Q3), 최대값(max) 의 요약통계량을 계산하는 것에서 시작합니다. 



[상자 그림 그리는 순서 및 방법]


  1. 주어진 데이터에서 각 사분위수를 계산한다.
  2. 그래프에서 제1 사분위와 제3 사분위를 밑변으로 하는 직사각형을 그리고, 제 2사분위에 해당하는 위치에 선분을 긋는다.
  3. 사분위수 범위(IQR, Interquartile range, )를 계산한다.
  4. 과 차이가 1.5*IQR 이내인 값 중에서 최댓값을 과 직선으로 연결하고, 마찬가지로 과 차이가 1.5*IQR 이내인 값 중에서 최솟값을 과 연결한다.
  5. 보다 1.5*IQR 이상 초과하는 값과 보다 1.5*IQR 이상 미달하는 값은 점이나, 원, 별표등으로 따로 표시한다(이상치 점).

* source: https://ko.wikipedia.org/wiki/상자_수염_그림

 



위의 상자 그림 그리는 방법에 대한 내용은 아래의 표준정규분포 확률밀도함수 분포 곡선에 대한 상자 그림 매핑을 보면 좀더 이해가 쉬울 것입니다. 


[Boxplot and a probability density function (pdf) of a Normal N(0,1σ2) Population]


* source: https://en.wikipedia.org/wiki/Box_plot




상자 그림을 (1) matplotlib, (2) seaborn, (3) pandas 패키지를 이용해서 그리는 방법을 차례대로 소개하겠습니다. 



import numpy as np

import pandas as pd


import matplotlib.pyplot as plt

import seaborn as sns

plt.rcParams['figure.figsize'] = [10, 6]

%matplotlib inline




예제로 사용할 데이터셋은 seaborn 패키지에 내장되어 있는 tips 라는 DataFrame 을 사용하겠습니다. 



# loading 'tips' dataset

tips = sns.load_dataset('tips')


tips.shape

(244, 7)


tips.head()

total_billtipsexsmokerdaytimesize
016.991.01FemaleNoSunDinner2
110.341.66MaleNoSunDinner3
221.013.50MaleNoSunDinner3
323.683.31MaleNoSunDinner2
424.593.61FemaleNoSunDinner4


tips.groupby(['sex', 'day']).size()

sex     day 
Male    Thur    30
        Fri     10
        Sat     59
        Sun     58
Female  Thur    32
        Fri      9
        Sat     28
        Sun     18
dtype: int64




tips DataFrame의 tip 연속형 변수에 대해서 상자 그림을 그려보겠습니다. 


  (1) matplotlib 으로 상자 그림 그리기


boxplot() 함수를 사용해서 default 세팅으로 상자 그림을 그려보겠습니다. 


# Basic box plot

plt.boxplot(tips['tip'])

plt.show()



이번에는 상자 그림의 이상치(outlier) 모양과 색깔, 제목(title), X축 이름(X label)을 설정해보겠습니다. 



# setting outlier symbol, title, xlabel

plt.boxplot(tips['tip'], sym="bo")

plt.title('Box plot of tip')

plt.xticks([1], ['tip'])

plt.show()




다음으로 상자그림을 가로로 눕히고, 가운데 상자는 중앙값 부근에서 V자 형태로 골이 패이게(notch) 그려보겠습니다. 


 

# Horizontal Box plot with notched box & red color outliers

plt.boxplot(tips['tip'], 

            notch=1, # if 'True' then notched box plot

            sym='rs', # symbol: red square

            vert=0 # vertical : if 'False' then horizontal box plot

           )

plt.show()




한 개의 축에 여러 개의 연속형 변수(total_bill, tip)에 대한 여러 개의 상자 그림을 한꺼번에 그려보겠습니다. (다수 개의 연속형 변수, 한개의 그룹)



# Multiple box plots on one Axes

fig, ax = plt.subplots()

ax.boxplot([tips['total_bill'], tips['tip']], sym="b*")

plt.title('Multiple box plots of tips on one Axes')

plt.xticks([1, 2], 

           ['total_bill', 'tip'])

plt.show()

 




  (2) seaborn 으로 여러개 그룹에 대한 상자 그림 그리기 

      (Grouped box plots by seaborn)


요일(day) 그룹별러 팁(tip)에 대한 상자 그림을 같이 그려서 비교를 해보겠습니다. (한 개의 연속 형 변수, 다수 개의 그룹)



# Grouped boxplots by seaborn

import seaborn as sns


sns.boxplot(x="day"

            y="tip"

            data=tips)

plt.show()





위의 요일(day: Thur, Fri, Sat, Sun) 그룹에 더해 hue 옵션을 사용하여 성별(sex: Male, Female)에 따른 그룹을 추가하여 (총 4개 그룹 x 2개 그룹 = 8개 그룹) 별 팁(tip) 에 대한 상자 그림을 그려서 비교해보겠습니다. 



#  2 by 4 multi-Grouped boxplots by seaborn

sns.boxplot(x="day", 

            y="tip", 

            hue="sex",

            data=tips)


plt.show()

 





  (3) pandas 로 상자 그림 그리기


pandas의 DataFrame에 df.boxplot() 함수를 사용하여 상자 그림을 그릴 수 있습니다. (2)번에서 그렸던 그룹 별 상자 그림을 pandas 의 boxplot() 함수로 그려보면 아래와 같습니다. 



# Grouped boxplots by pandas

tips.boxplot(column=["tip"], by=["day", "sex"])

plt.show()


제 개인적인 생각으로는, 그래프의 가독성은 seaborn이 더 나아 보이고, 코드의 가독성은 pandas가 더 우수해보이네요. 


많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요.


다음번 포스팅에서는 막대 그래프 그리는 방법을 소개하겠습니다. 



반응형
Posted by Rfriend

댓글을 달아 주세요

  1. 익명 2021.07.11 17:32  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • Rfriend 2021.07.11 17:35 신고  댓글주소  수정/삭제

      안녕하세요.
      링크 거는 것이거나 부분 인용이면 아무런 문제 없구요,
      혹시 제 포스팅 본문 전체 내용을 카피&페이스트 하는 것은 하지 말아주면 감사하겠습니다.

지난번 포스팅에서는 하나의 그룹, 하나의 변수에 대한 히스토그램, 커널밀도곡선을 그리는 방법을 소개하였습니다. 


이번 포스팅에서는

(1) 여러개의 그룹에 대한 히스토그램, 커널밀도곡선 그리기

(2) 여러개의 변수에 대한 히스토그램, 커널밀도곡선 그리기

에 대해서 알아보겠습니다. 



먼저, matlplotlib.pyplot, seaborn 패키지를 importing하고, 예제로 사용할 iris 데이터셋을 불러오겠습니다. 



import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import seaborn as sns


# loading 'iris' dataset

iris = sns.load_dataset('iris')

iris.shape

(150, 5)


iris.head()

sepal_lengthsepal_widthpetal_lengthpetal_widthspecies
05.13.51.40.2setosa
14.93.01.40.2setosa
24.73.21.30.2setosa
34.63.11.50.2setosa
45.03.61.40.2setosa

 

iris.groupby('species').size()

species
setosa        50
versicolor    50
virginica     50
dtype: int64




iris는 붓꽃인데요, 아래처럼 versicolor, setosa, virginica의 3개 종(species) 그룹별로 각 50개씩 꽃잎 길이와 넓이, 꽃받침 길이와 넓이의 4개 변수를 측정한 데이터셋입니다. 


* image source: https://www.datacamp.com/community/tutorials/machine-learning-in-r



  (1) 여러개 그룹의 히스토그램, 커널밀도곡선 그리기


petal_length 변수에 대해서 setosa, versicolor, virginica 종의 3개 그룹(groups)의 히스토그램과 커널밀도곡선을 그룹별로 색깔을 다르게 하여 그려보겠습니다. 



# 1-1. Multiple histograms on the same axis

sns.distplot(iris[iris.species == "setosa"]["petal_length"], 

             color="blue", label="setosa")


sns.distplot(iris[iris.species == "versicolor"]["petal_length"], 

             color="red", label="versicolor")


sns.distplot(iris[iris.species == "virginica"]["petal_length"], 

             color="green", label="virginica")


plt.legend(title="Species")

plt.show()


 




만약 그룹 개수가 많아서 위에서처럼 일일이 코딩하기가 시간이 오래걸리고 반복되는 코드가 길게 늘어서는게 싫다면 아래처럼 for loop 을 사용해주면 됩니다. 


그래프의 제목, X축 이름, Y축 이름, 범례 이름을 설정하는 방법도 같이 소개합니다. 



# 1-2. Via for loop

grp_col_dict = {'setosa': 'blue', 

                    'versicolor': 'red', 

                    'virginica': 'green'}


# for loop of species group

for group in grp_col_dict:

    

    # subset of group

    subset = iris[iris['species'] == group]

    

    # histogram and kernel density curve

    sns.distplot(subset['petal_length'], 

                    hist = True, # histogram

                    kde = True,  # density curve

                    kde_kws = {'linewidth': 2}, 

                    color = grp_col_dict[group],

                    label = group)


# setting plot format

plt.title('Histogram & Density Plot by Groups')

plt.xlabel('Petal Length(unit:cm)')

plt.ylabel('Density')

plt.legend(prop={'size': 12}, title = 'Group')

plt.show()




  (2) 여러개 변수의 히스토그램, 커널밀도곡선 그리기


이번에는 sepal_width, sepal_length, petal_width, petal_length 의 4개 변수(variable)에 대해서 히스토그램과 커널밀도곡선을 그려보겠습니다. (단, 종(species)의 구분없이 전체 사용)


for loop 을 사용하였는데요, 위의 그룹 indexing 과 이번의 변수 indexing 부분이 다르다는 점 유심히 살펴보시기 바랍니다. 



# 2-1. Multiple histograms on the same axis

var_color_dict = {'sepal_length': 'blue', 

                      'sepal_width': 'red', 

                      'petal_length': 'yellow', 

                      'petal_width': 'green'}


# for loop

for var in var_color_dict:

    sns.distplot(iris[var],                  

                    color = var_color_dict[var], 

                    hist_kws = {'edgecolor': 'gray'}, 

                    label = var)


plt.legend(title = 'Variables')

plt.show()





위의 (2-1) 그래프는 1개의 window에 동일한 축을 사용하여 4개 변수의 히스토그램과 밀도곡선을 그리다보니 중첩이 되면서 좀 헷갈리고 보기에 어려운 점이 있습니다. 


이런 경우에 그래프를 각 변수별로 분리해서 4개의 window subplots에 하나씩 그려서 비교하는 것도 좋은 방법입니다. ax=axes[0, 0] 은 좌상, ax=axes[0, 1]은 우상, ax=axes[1, 0]은 좌하, ax=axes[1, 1]은 우하 위치의 subplot 입니다. 



# 2-2. Multiple histograms at separate windows

f, axes = plt.subplots(2, 2, figsize=(8, 6), sharex=True)

sns.distplot(iris["sepal_length"], color="blue", ax=axes[0, 0])

sns.distplot(iris["sepal_width"], color="red", ax=axes[0, 1])

sns.distplot(iris["petal_length"], color="yellow", ax=axes[1, 0])

sns.distplot(iris["petal_width"], color="green", ax=axes[1, 1])

plt.show()





for loop을 사용해서 그리려면 아래 코드를 참고하세요. 



var_color_dict = {'sepal_length': 'blue', 

                      'sepal_width': 'red', 

                      'petal_length': 'yellow', 

                      'petal_width': 'green'}


i = [0, 0, 1, 1]

j = [0, 1, 0, 1]


# for loop

f, axes = plt.subplots(2, 2, figsize=(8, 6), sharex=True)

for var, i, j in zip(var_color_dict, i, j):

    sns.distplot(iris[var],                  

                    color = var_color_dict[var],

                    ax = axes[i, j])

    

plt.show()



많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요.  :-)



반응형
Posted by Rfriend

댓글을 달아 주세요