13.1 산포도

산포도(Scatter Plot)x축과 y축에 연속형인 두 변수의 값을 점으로 뿌려준 그래프로서, 연속형인 두 변수 간의 관계를 파악하는데 유용합니다. 다중 회귀분석을 할 때 제일 처음 하는 일이 바로 산포도 (행렬)을 그려보고 두 변수간의 선형성(linearity) 여부를 탐색해보는 일입니다.

13.1.1 데이터 세트

MASS패키지 내 Cars93 데이터 프레임의 고속도로연비(MPG.highway)엔진크기(EngineSize), 무게(Weight), 길이(Length) 와의 관계를 ggplot2 패키지의 geom_point() 함수를 이용하여 산포도로 알아보겠습니다.

그리고 차종(Type)별로 고속도로연비(MPG.highway) 는 어떻게 되는지도 산포도를 가지고 점의 색깔과 모양을 달리해서 살펴보는 방법을 알아보겠습니다.

library(tidyverse)
library(MASS)
str(Cars93)

13.1.2 변수들 간의 상관계수

먼저 변수들 간의 상관계수를 가지고 고속도로연비(MPG.highway)엔진크기(EngineSize), 무게(Weight), 길이(Length)와의 상관도를 살펴보겠습니다.

# 변수들 간의 상관계수 : cor() 함수
Cars93_MPG <- Cars93[, c("MPG.highway", "EngineSize", "Weight", "Length")]
cor(Cars93_MPG)          # 4개의 변수들 간의 상관계수를 구합니다.
##             MPG.highway EngineSize Weight Length
## MPG.highway        1.00      -0.63  -0.81  -0.54
## EngineSize        -0.63       1.00   0.85   0.78
## Weight            -0.81       0.85   1.00   0.81
## Length            -0.54       0.78   0.81   1.00

고속도로연비(MPG.highway)엔진크기(EngineSize), 무게(Weight), 길이(Length) 등과 모두 역의 상관관계가 있는 것을 알 수 있습니다. 특히 무게(Weight)가 가장 큰 역의 상관관계가 있음을 보여 주었습니다.

Go Top

13.1.3 산포도 행렬

13.1.3.1 산포도 행렬

이제 산포도 행렬을 그려서 고속도로연비(MPG.highway)엔진크기(EngineSize), 무게(Weight), 길이(Length) 관계를 살펴보겠습니다.

제일 쉬운 방법은 Base graphics 패키지에 있는 plot()함수를 사용하는 방법입니다. 위에서 분석하려는 4 개의 변수만 따로 선별해 놓은 Cars93_MPG 데이터 프레임을 가지고 산포도 행렬을 그려보겠습니다.

# 산포도 행렬 : plot() 함수 이용
plot(Cars93_MPG, main="산포도 행렬")
plot() 함수를 이용한 산포도 행렬

Figure 13.1: plot() 함수를 이용한 산포도 행렬

13.1.4 기본 산포도

ggplot2로는 산포도 행렬(Scatter Plot matrix)를 그리는 것이 힘듭니다.

대신 여러 조건을 주어서 두 변수 간 산포도를 다양하게 그려보는 데는 아주 강력합니다.

고속도로 연비(MPG.highway)와 엔진크기(EngineSize)의 관계를 geom_point() 함수를 이용하여 산포도로 시각화해 보겠습니다.

# 산포도 : MPG.highway 대 EngineSize, Weight, Length
ggplot(data = Cars93, 
       aes(x = EngineSize, 
           y = MPG.highway)) + 
   geom_point() +
   ggtitle("기본 산포도")
기본 산포도

Figure 13.2: 기본 산포도

13.1.4.1 점의 모양(Shape)과 색(Colour)의 지정

우선 ggplot2geom_point() 함수의 색깔(colour)과 모양(shape)의 모수 값을 달리하면서 산포도를 작성해 보겠습니다.

# 산포도 : MPG.highway 대 EngineSize, Weight, Length
g1 <- ggplot(data = Cars93, 
       aes(x = EngineSize, y = MPG.highway)) + 
       geom_point(shape = 12, 
                  size = 3, 
                  colour = "green") +           # shape 15: solid square
       ggtitle("산포도 : shape = 12, colour = \"green\"")

g2 <- ggplot(data = Cars93, 
       aes(x = EngineSize, y = MPG.highway)) + 
       geom_point(shape = 15, 
                  size = 3, 
                  colour = "blue") +            # shape 15: solid square
       ggtitle("산포도: shape = 15, colour = \"blue\"")

g3 <- ggplot(data = Cars93, 
             aes(x = Weight, 
                 y = MPG.highway)) + 
       geom_point(shape = 19, 
                  size = 3, 
                  colour = "red") +             # shape 19: solid circle
       ggtitle("산포도: shape = 19, colour = \"red\"")

g4 <- ggplot(data = Cars93, 
             aes(x = Length, 
                 y = MPG.highway)) + 
        geom_point(shape = 24, 
                   size = 3, 
                   colour = "black") +           # shape 24: filled triangle point-up
        ggtitle("산포도: shape = 24, colour = \"black\"")

multiplot(g1, g2, g3, g4, cols = 2)
다양한 산포도

Figure 13.3: 다양한 산포도

참고로, ggplot2 패키지의 Vignette에는 Aesthetic specifications를 통해 다양한 형식들을 요약해서 보여주고 있습니다.

# R 플롯 기호 : 점 모양
?? aes          # Vignettes:  ggplot2::ggplot2- Aesthetic specification 선택.

Go Top

13.1.4.2 산포도에 레이블 달기

이번에는 두 변수의 산포도의 각 점이 나타내는 자동차 모델명(Model)geom_text(label =) 함수를 이용하여 표시해 보겠습니다.

# 산포도에 레이블 달기 (모델명)
ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway)) + 
   geom_point(shape = 19,             # 점의 모양
              size = 1.5,             # 점의 크기
              colour="red") +         # 점의 색깔                        
   ggtitle("산포도의 점에 레이블 달기") + 
   geom_text(aes(label = Model,       # 레이블 변수 지정 
                 vjust = -1,          # vjust = -는 위, +는 아래
                 hjust = 0.5))          # hjust = +는 왼쪽, -는 오른쪽 
산포도의 점에 레이블 달기

Figure 13.4: 산포도의 점에 레이블 달기

Go Top

13.1.5 그룹별 산포도 그리기

다음으로 범주형 변수인 차종(Type)별로 무게(Weight)고속도로연비(MPG.highway) 간의 관계를 3가지 방법에 의해 산포도로 그려보도록 하겠습니다.

  1. aes() 함수의 모수를 이용하여

    • 차종(Type)별로 색깔(colour)을 달리해서 : colour = Type
    • 차종(Type)별모양(shape)을 달리해서 : shape = Type
  2. facet_grid() 함수를 이용하여

  3. facet_wrap() 함수를 이용하여

산포도를 그려보겠습니다.

13.1.5.1 aes() 함수의 모수 이용

차종(Type)별색깔(colour)을 달리하여 산포도를 그리려면 aes() 함수의 모수에 colour = Type 을 추가해 주면 됩니다.

# 차종별 산포도 : aes()의 colour 모수 이용
ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway, 
           colour = Type)) +    # aes() 함수에 colour 모수를 설정합니다.
   geom_point(shape=19,         # 점의 모양을 19로 지정합니다.
              size=3) + 
   ggtitle("차종별 산포도 : aes() 함수 이용 - 색 구분")
차종별 산포도 : aes() 함수 이용 - 색 구분

Figure 13.5: 차종별 산포도 : aes() 함수 이용 - 색 구분

지금까지 설명한 aes() 의 모수애는 fill, colour 이외에도 shape 이 있습니다.

다음의 예는 aes() 함수의 shape 모수를 이용하여 차종(Type)별모양(shape)을 달리 표현하는 예입니다.

# 차종별 산포도 : aes()의 shape 모수 이용
ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway, 
#           colour = Type,        # aes() 에 colour 모수도 추가해 보세요.
           shape = Type)) +      # aes() 함수에 shape 모수를 설정합니다.
   geom_point(size = 3) +        # shape 모수를 제거해 줍니다.
   ggtitle("차종별 산포도 : aes() 함수 이용 - 점의 모양 구분")
차종별 산포도 : aes() 함수 이용 - 점의 모양 구분

Figure 13.6: 차종별 산포도 : aes() 함수 이용 - 점의 모양 구분

# 차종별 산포도 : aes()의 shape 모수와 colour 모수
ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway, 
           colour = Type,        # aes() 에 colour 모수도 추가해 보세요.
           shape = Type)) +      # aes() 함수에 shape 모수를 설정합니다.
   geom_point(size = 3) +        # shape 모수를 제거해 줍니다.
   ggtitle("차종별 산포도 : aes() 함수 이용 - 점의 모양과 색 구분")
차종별 산포도 : aes() 함수 이용 - 점의 모양 구분

Figure 13.7: 차종별 산포도 : aes() 함수 이용 - 점의 모양 구분

처음의 색 구분 예에서는 geom_point() 함수에 shape 모수를 지정해 주었기 때문에 Type에 상관없이 모든 점이 19 형태의 점으로 표시가 됩니다. 그리고 범례Type 별로 colour를 구분해 주고 있습니다.

반면에 두 번째의 점의 모양 구분 예에서는 ggplot() 함수 내의 aes() 함수의 모수로 shape을 지정해 주어 Type 의 값에 따라 점의 모양이 구별되고 있음을 주목하기 바랍니다. 그리고 범례에서는 Type 별로 shape을 구분해 주고 있습니다. 이때, aes() 함수 내에 colour 모수를 동시에 설정해 주면 색도 지정이 됨을 알 수 있습니다.

Go Top

13.1.5.2 facet_grid() 함수의 이용

이번에는 facet_grid() 함수를 이용하여 차종(Type)별로 산포도를 그려 보겠습니다.

# 차종별 산포도 : facet_grid() 함수 이용
ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway,
           colour = Type,           # aes() 에 colour 모수도 추가해 보았습니다.
           shape = Type)) +                            
   geom_point(size = 3) +                              
   facet_grid(Type ~.) +            # facet_grid() : Type을 Y축에 표시합니다.
   ggtitle("차종별 산포도 : facet_grid() 함수 이용")
차종별 산포도 : facet_grid() 함수 이용

Figure 13.8: 차종별 산포도 : facet_grid() 함수 이용

ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway,
           colour = Type,           # aes() 에 colour 모수도 추가해 보았습니다.
           shape = Type)) +                            
   geom_point(size = 3) +                              
   facet_grid(. ~ Type) +           # facet_grid() : Type을 X축에 표시합니다.
   ggtitle("차종별 산포도 : facet_grid() 함수 이용")
차종별 산포도 : facet_grid() 함수 이용

Figure 13.9: 차종별 산포도 : facet_grid() 함수 이용

facet_grid() 함수에 대한 자세한 내용은 ? facet_grid()를 참고하기 바랍니다.

Go Top

13.1.5.3 facet_wrap() 함수의 이용

이번에는 facet_wrap() 함수를 이용하여 차종(Type)별로 산포도를 그려 보겠습니다.

# 차종별 산포도 : facet_wrap() 함수 이용
ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway,
           colour = Type,                     
           shape = Type)) +                            
   geom_point(size = 3) +                              
   facet_wrap(~Type, ncol = 2) +                      # facet_wrap() : Type을 Y축에 표시합니다.
   ggtitle("차종별 산포도 : facet_wrap() 함수 이용")
차종별 산포도 : facet_wrap() 함수 이용

Figure 13.10: 차종별 산포도 : facet_wrap() 함수 이용

facet_wrap() 함수에 대한 자세한 내용은 ? facet_wrap()를 참고하기 바랍니다.

Go Top

13.1.6 Theme의 사용

히스토그램에서 Theme을 사용하였듯이, 산포도에서도 Theme을 사용할 수 있습니다.

다음의 예는 앞서 작성한 차종별 산포도히스토그램에서 Theme으로 사용ggplot2::theme_classic() + 이하 부분을 복사해서 붙여넣기한 것입니다.

# 기본 산포도에 theme_classic() 적용
ggplot(data = Cars93, 
       aes(x = EngineSize, 
           y = MPG.highway,
           colour = Type,
           shape = Type)) + 
   geom_point(size = 3) +                             
   ggtitle("산포도: MPG.highway vs. EngineSize - Theme 적용") +
  ggplot2::theme_classic() +                     # 그래프 테마 지정
  ggplot2::theme(axis.title.x = element_text(size  = 10, 
                                             face  = "italic", 
                                             color = "gray", 
                                             angle = 0, 
                                             vjust = 0.5),
                 axis.title.y = element_text(size  = 10, 
                                             face  = "bold.italic", 
                                             color = "gray", 
                                             angle = 0, 
                                             vjust = 0.5)) +       
  ggplot2::scale_y_continuous(labels = scales::comma)              
산포도에 Theme 적용

Figure 13.11: 산포도에 Theme 적용

Go Top

13.1.7 회귀선의 표시

데이터를 산포도로 시각화하는데 있어서 중요한 것이 선형 회귀선 (신뢰구간 95%)으로 적합화(fitting)하는 것입니다.

이러한 데이터 간의 관계 즉, 엔진의 크기(EngineSize)와 고속도로 연비(MPG.highway) 사이의 관계성을 산포도로 표시하는 것도 좋지만, 또한 이 두 변수간의 관계를 선형 회귀선으로 시각화하는 것도 매우 중요합니다.13

13.1.7.1 선형 회귀선 적합화

stat_smooth() 함수를 이용하여 이러한 변수간의 선형 회귀선신뢰구 간을 시각화할 수 있습니다.

# 산포도 :  선형 회귀선과 신뢰구간의 표시
ggplot(data = Cars93, 
       aes(x = EngineSize, 
           y = MPG.highway)) + 
   geom_point(size = 3, 
              shape = 19, 
              colour = "blue") +   
# 선형회귀선과 신뢰구간의 시각화
   stat_smooth(method = lm,        # 선형 모델(linear model) 적용합니다.
               level = 0.95,       # 유의수준을 0.05로 설정합니다.(신뢰도 0.95)
               colour = "red") +   # 선형 회귀선의 색을 설정합니다,  
   ggtitle("산포도: 선형 회귀선과 신뢰구간의 표시")
## `geom_smooth()` using formula 'y ~ x'
산포도 : 선형 회귀선과 신뢰구간의 표시

Figure 13.12: 산포도 : 선형 회귀선과 신뢰구간의 표시

산포도에 회귀선을 적합시켰는데, 아래와 같이 신뢰구간은 제외할 수도 있습니다.

# 산포도 :  선형 회귀선만 표시
ggplot(data = Cars93, 
       aes(x = EngineSize, 
           y = MPG.highway)) + 
   geom_point(size = 3, shape = 19, colour = "blue") +   
# 선형회귀선과 신뢰구간의 시각화
   stat_smooth(method = lm,                        
               level = 0.95,                       
               colour = "red",                     
               se = FALSE) +                       # 신뢰구간을 제외합니다.
   ggtitle("산포도: 산포도 : 선형 회귀선에서 신뢰구간의 제외")
## `geom_smooth()` using formula 'y ~ x'
산포도 : 선형 회귀선에서 신뢰구간의 제외

Figure 13.13: 산포도 : 선형 회귀선에서 신뢰구간의 제외

13.1.7.2 비모수 회귀선 적합화

산포도에 선을 적합시킬 때 선형 회귀선 말고도 loess(locally weighted polynomial) 를 이용하여 비모수 회귀(Nonparametric regression) 선을 적합시킬 수도 있습니다.

stat_smooth() 함수의 method 모수 값을 loess로 설정해 주면 됩니다.

# 산포도 :  비선형 회귀선(loess)
ggplot(data = Cars93, 
       aes(x = EngineSize, 
           y = MPG.highway)) + 
   geom_point(size = 3, shape = 19, colour = "blue") +   
# 선형회귀선과 신뢰구간의 시각화
   stat_smooth(method = loess,                     # 비모수 회귀선 모델인 loess를 적용합니다.
               level = 0.95,                       # 유의수준을 0.05로 설정합니다.(신뢰도 0.95)
               colour = "red") +                   # 선형 회귀선의 색을 설정합니다,  
   ggtitle("산포도 : 비선형 회귀선과 신뢰구간의 표시")
## `geom_smooth()` using formula 'y ~ x'
산포도 : 비선형 회귀선과 신뢰구간의 표시

Figure 13.14: 산포도 : 비선형 회귀선과 신뢰구간의 표시

Go Top

연습문제

1. Cars93 데이터 세트에 있는 차량의 무게(Weight)와 고속도로 연비(MPG.highway) 등의 2개의 연속형 변수들을 산포도로 시각화하시오.

ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway)) + 
   geom_point() +
   ggtitle("기본 산포도")

2. 1.에서 작성한 산포도의 각 점이 나타내는 자동차 모델명(Model)을 geom_text(label =) 함수를 이용하여 표시하시오.

ggplot(data = Cars93, 
       aes(x = Weight, 
           y = MPG.highway)) + 
   geom_point() +
   ggtitle("기본 산포도 : 데이터 레이블 표시하기") + 
   geom_text(aes(label = Model,       # 레이블 변수 지정 
                 vjust = -1,          # vjust = -는 위, +는 아래
                 hjust = 0.5))          # hjust = +는 왼쪽, -는 오른쪽 

Go Top