ㅅㅇ

Seaborn _ 데이터 시각화 본문

AI_STUDY/데이터 시각화 Matplotlib Seaborn Pandas

Seaborn _ 데이터 시각화

SO__OS 2022. 6. 18. 16:32
플레이데이터 빅데이터캠프 공부 내용 _ 6/16

Seaborn _ 데이터 시각화

1.  Seaborn 이란?

- matplotlib을 기반으로 다양한 테마와 그래프를 제공하는 파이썬 시각화 패키지.


- 장점 : 시각적으로 좋다. matplotlib 보다 dataframe과 연동 사용이 편하다

- 설치: 아나콘다에는 포함되있다.

pip install seaborn
conda install seaborn

 

http://seaborn.pydata.org/

 

seaborn: statistical data visualization — seaborn 0.11.2 documentation

Seaborn is a Python data visualization library based on matplotlib. It provides a high-level interface for drawing attractive and informative statistical graphics. For a brief introduction to the ideas behind the library, you can read the introductory note

seaborn.pydata.org

 

- 공식사이트의 갤러리에 제공하는 다양한 그래프와 예제를 확인할 수 있다. 

http://seaborn.pydata.org/examples/index.html

 

Example gallery — seaborn 0.11.2 documentation

 

seaborn.pydata.org

 

 

 

1)  기본적인 데이터 시각화 패키지 import

기본적으로 아래 패키지들을 사용한다.

# 데이터 시각화 패키지
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

 # 실행 시 뜨는 경고메시지는 무시하기 위해
import warnings 
warnings.filterwarnings(action = 'ignore')

 

 

2) seaborn에서 제공하는 toy dataset을 DataFrame으로 가져오는 함수.

 

- toy dataset : 패키지에 사용할 수 있는 연습용 공개 데이터. (기업이 제공한 더미 아닌 실제 데이터 )

- pandas 의 read 처럼 DataFrame 을 읽어올 수 있다.

# 데이터셋 : tips df를 가져온다.
tips = sns.load_dataset('tips')

 

3) Seaborn 그래프 그리는 두 가지 방식

  rugplot 로 예를 들어 설명. 모든 그래프 그리는 메서드에 적용됨.

    (1) sns.rugplot(tips['total_bill'])

           - 사용할 값 =  df[컬러명]   :  컬럼명으로 조회한 series 를 넣음

    (2) sns.rugplot('total_bill', data = tips)

           - 사용할 값 = 컬럼명     data = DataFrame

 

--- > 이 부분에서도 seaborn 은 dataframe 과 연동이 matplotlib 보다 쉽다는 것을 알 수 있다.

 

2.  Seaborn 그래프

**  seabon 에서는 축의 label은 자동으로 들어간다. 따로 다른 이름을 붙이고 싶을 때 plt 그래프 설정으로 해주기

 

2.1 rugplot, kdeplot, distplot, displot

: 1차원 연속형 값들의 분포를 시각화 하는 그래프

 

1) rugplot

: 연속형 데이터의 각 데이터 값들의 위치를 보여준다.

 

- matplotlib 과 함께 사용가능하다. 주로, 그래프 설정은 matplotlib 으로 한다.

- histogram과 같이 시각화해서 각 계급(bin, group별 범위)안에서의 값의 분포를 확인할 수 있다.

    - > histogram은 구간 내 수량만 알려주는 것으로 세부적으로 값 별 수량은 모른다. 

         그래서 rug 와 함께 써 이 부분을 알고자 한다.

 

(방법 1) 

plt.figure(figsize=(7,4))
sns.rugplot(tips['total_bill'])
plt.show()

 

(방법 2)

sns.rugplot('total_bill', data = tips)
#plt.yticks([0.1, 0.2], labels = ['a', 'b'])
plt.yticks([]) # y 축 눈금 없애기.
plt.show()

 

- x축에 값이 있는 위치를 표시한다.

   (히스토그램처럼 수량을 보는 것도 아니고, 구간별도 아닌, 각 데이터 값들의 위치를 찍는 것)

- y축은 의미 없다.

- xlabel 은 자동으로 넣어준 컬럼명으로 나온다.

 

 

2) kdeplot

- 히스토그램을 부드러운 곡선 형태로 표현한다. 
- KDE(Kernel Density Estimation) : 확률밀도추정

sns.kdeplot(tips['total_bill']) # y축 : 수량의 비율
# sns.kdeplot('total_bill', data=tips)
plt.show()

3) distplot

히스토그램에 kdeplot, rugplot 한번에 그린다.
    - hist,   kdeplot  은 default로 나오고  /   rugplot은 default로 안나온다.

    - 컬럼명, data=DF 형식으로 호출할 수 없다. df['컬럼명'] 으로 값 넣어야 함.

plt.figure(figsize = (7,7))
sns.distplot(tips['total_bill'],# 컬럼명, data=DF 형식으로 호출할 수 없다.
            hist = True, # 히스토그램을 그릴지 여부(def = T)
            kde = True, # ked 을 그릴지 여부(def = T)
            rug = True, # rugplot 을 그릴지 여부(def = F)
            bins = 30 # histogrom의 bins의 개수
            )

 

- displot() : group 별로 나눠서 시각화
- distplot() : 하나의 컬럼에 대해서만 시각화

 

4) displot

: 히스토그램, rugplot, kdeplot 등을 확인을 확인할 건데,

    group 별로 나눠서 시각화 하고 싶을 때

 

      - 기본값 : hist = T   /    kde = F,     rug = F    (dist 랑 헷갈리지 말기!)
      hue = '범주형 컬럼'    :   그룹으로 나누고 싶을 때 해당 매개변수를 넣으면 됨. 

                                                 다른 그래프에서도 그룹으로 묶고 싶을 때 쓰임.! 

      - 매개변수 순서때문에 키워드 인자로 넣어주기.

     - 겹치는 애들 검정색으로. lagend 알아서 표시.

# group 별로 나눠서  히스토그램, rugplot, kdeplot 등을 확인

# 남성/여자 별 total_bill 분포를 비교
sns.displot(x ='total_bill', hue = 'sex' , data=tips, kde = True, rug = True)

 

- 두 개의 범주로 분류한 값 그래프들을 하나의 axes에 시각화하는 법

  모든 그래프 메서드에서 적용됨

분류할 범주형 컬럼(대분류)을 x 또는 y 에 넣고,

분류할 범주형 컬럼(소분류)을 hue에 넣는다.

 

 

2.2 boxplot(), violinplot(), swamplot()

  : 연속형 데이터(양적데이터)들의 분포를 확인하는 그래프를 그린다.


범주별로 연속형 데이터의 분포를 비교할 수 있다.

 

- 범주 별 데이터의 분포를 하나의 axes에 시각화

   수직 기준, 분류할 범주형 컬럼을 x에 넣기

 

- 두 개의 그룹화로 데이터의 분포를 하나의 axes에 시각화

   수직 기준, 분류할 범주형 컬럼(대분류)을 x에 넣고,

                     분류할 범주형 컬럼(소분류)을 hue에 넣는다.

 

 

1) boxplot()

 

- 매개변수 키워드 인자 쓰기

    x = 값     - > 수평방향의 boxplot

    y = 값     - > 수직방향의 boxplot

 

- 기본예제

plt.figure(figsize=(10,6))

# 하나의 figure에 2개의 axes를 이용해 시각화.
plt.subplot(1,2,1)
sns.boxplot(y=tips['total_bill'])
# sns.boxplot(y='total_bill', data=tips) #dataframe과 컬럼명을 분리해 설정
plt.title('수직방향의 boxplot')

plt.subplot(1,2,2)
sns.boxplot(x=tips['total_bill'])
plt.title('수평방향의 boxplot')

 

- 범주 별 데이터의 분포를 하나의 axes에 시각화

 

-- > 범주 별 비교를 위해선 흔히 하나의 axes에 시각화해야 한다.

 수직 : y = 값,    x = 범주형 컬럼,    data = 데이터 프레임

 

# 흡연여부별 tip의 분포를 boxplot 비교
# 수직
sns.boxplot(y = 'tip', x= 'smoker', data = tips)

 

- 두 개의 그룹화로 데이터의 분포를 하나의 axes에 시각화

 

  ex. 흡연 + 성별 tip 분포를 boxplot(smoker 중 또 성별로 나눔.)

 

 수직 : y = 값,    x = 범주형 컬럼(대분류),   hue =  범주형 컬럼(소분류) ,  data = 데이터 프레임

 수평 : x = 값,    y  = 범주형 컬럼(대분류),  hue =  범주형 컬럼(소분류) ,  data = 데이터 프레임

 

# 수직
sns.boxplot(y='tip', x='smoker', hue='sex', data=tips)

# 수평
sns.boxplot(x='tip', y='smoker', hue='sex', data=tips)

 

 

2) violin plot

:  boxplot 위에 분포 밀도(kernel density)를 좌우 대칭으로 덮어쓰는 방식으로

   데이터의 분포를 표현하므로 boxplot 보다 좀더 정확한 데이터의 분포를 볼 수 있다.
- 매개변수는 boxplot과 동일

 

- 기본예제

 

# 수직
sns.violinplot(y='total_bill', data = tips)

 

 

 

- 범주 별 데이터의 분포를 하나의 axes에 시각화

 

# 요일(data) 별 분포
sns.violinplot(y='total_bill', x = 'day', data = tips)

 

- 두 개의 그룹화로 데이터의 분포를 하나의 axes에 시각화

 

sns.violinplot(y='total_bill', x = 'day', hue='smoker', data = tips)

 

 

 

(3) swarmplot

- 실제 값들을 점으로 찍어 준다. (데이터 값만큼 점)
- boxplot이나 violin plot의 보안해주는 역할로 쓰인다. 같이 쓴다.

- swarmplot은 가운데 분류를 기준으로 분포시키는데 

   실제 값이 있는 위치에 점을 찍으므로 좀더 정확하게 값이 어디에 있는지 알 수 있다.

 

- 기본예제

sns.swarmplot(y='total_bill', data = tips )

 

- 범주 별 데이터의 분포를 하나의 axes에 시각화

 

sns.swarmplot(y='total_bill', x='smoker', data = tips )

 

 

- 두 개의 그룹화로 데이터의 분포를 하나의 axes에 시각화

 

sns.swarmplot(y='total_bill', x='smoker', hue = 'sex', data = tips )

 

- boxplot에 함께 써서 값의 분포를 확인하게

sns.boxplot(y='total_bill', x = 'smoker' , data=tips)
sns.swarmplot(y='total_bill', x= 'smoker', data=tips, color = 'gray') # 색 다르게 주기.

 

2.3 countplot   :   bar plot 

- 막대그래프(bar plot)을 그리는 함수
- 범주형 변수의 고유값의 개수를 표시

 

- matplotlib의 bar()  와 다른 점

  matplotilib의 경우, 개수를 세는 작업을 한 뒤에 그 결과를 시각화한다.  

  그러나, seaborn의 경우 개수를 세는 작업을 알아서 대신 해준다.

 

- 범주형 컬럼을 x 또는 y 에 전달 : 범주값 별로 개수를 세서 막대그래프를 그린다.

  수평막대그래프 :  y = 컬럼명

  수직막대그래프 :  x = 컬러명 

# seaborn 수직
sns.countplot(x='smoker', data=tips) 

# seaborn 수평
sns.countplot(y='smoker', data=tips) 

# matplotlib
vc=tips['smoker'].value_counts() # 이걸 대신 해준다.
plt.bar(vc.index, vc)

 

 

- 두 개의 범주형에 대해 그룹화하여 하나의 axes에 시각화 

   -- > hue

# 요일별 흡연자/비흡연자 별 수
sns.countplot(x='day', hue = 'smoker', data=tips)

 

2.4  scatterplot, lmplot, jointplot, pairplot

 : 산점도를 그린다.
  - 두 변수 간의 관계성

 

(1) scatterplot

 

-  기본예제

# total_bill과 tip 관계
sns.scatterplot(x='total_bill', y='tip', data =tips, alpha = 0.5)

 

- 하나의 범주형에 대해 그룹화하여 하나의 axes에 시각화 

  -- > 성별에 따른 두 변수 간의 상관관계를 한 axes에서 비교할 수 있다.

# 성별에 따른 total_bill 과 tip 데이터 간의 관계
sns.lmplot(x='total_bill', y='tip', hue='sex', data=tips)
plt.grid(True)

 

(2) lmplot()

선형회귀 적합선을 포함한 산점도를 그린다.
     - 선형회귀 적합선 : 상관관계를 가장 잘 표현할 수 있는 선을 같이 그려준다.
- scatterplot보다 많이 쓰임.

 

# 증감치를 잘 표현하는 선.

sns.lmplot(x='total_bill', y='tip', data=tips)
plt.grid(True)
plt.show()

 

- 추론의 모델로 쓰인다.
   # 30달러 냈을 때 tip 4 달러 정도 줄 것 같다라는 예측.

 

- 하나의 범주형에 대해 그룹화하여 하나의 axes에 시각화 

  -- > 성별에 따른 두 변수 간의 상관관계를 한 axes에서 비교할 수 있다.

sns.lmplot(x='total_bill', y='tip', hue='sex', data=tips)
plt.grid(True)

 

(3) jointplot()

- scatter plot 과 각 변수의 히스토그램을 같이 그린다.
- pandas DataFrame만 사용할 수 있다.
    - 컬럼명과 dataframe을 따로 설정해야 한다. - >  x='total_bill', y ='tip', data=tips

 

sns.jointplot(x='total_bill', y ='tip', data=tips)

 

# total_bill과 tip이 삼전도로  # total_bill이 x축으로 히스토그램 # tip이 y축으로 히스토그램

 


(4) pairplot

 

다변수(다차원) 데이터들 간의 산점도를 보여준다. 
데이터프레임을 인수로 받아 그리드(grid) 형태로 각 변수간의 산점도를 그린다. 

  같은 변수가 만나는 대각선 영역에는 해당 데이터의 히스토그램을 그린다.

-  dataframe의 수치형 컬럼들만 이용해서 그린다.

 

sns.pairplot(tips) # 매개변수 : dataframe

 

# x, y축 똑같은 애들은 히스토그램  # x, y축 다른 애들은 삼전도

 

 

2.5 heatmap()

- 값들에 비례해서 색깔을 다르게 해 2차원 자료로 시각화
- 상관계수를 시각화할 때 주로 쓰임.

 

(1) 상관계수 

 

상관계수 값에 따라 색을 다르게 하여 시각화하고자 한다.

 

corr_df = tips[['total_bill', 'tip', 'size']].corr()
corr_df

 

 

(2) matplotlib 으로 하는 방법 : imshow()

 

 : image 를 그려줌. - > pixcel 값(정수)을 redering(이미지화)


 - 이것은 heatmap 용도로 만들어준 메소드는 아니고 사진을 화면에 뿌리는 용도로 만들어짐.
   heatmap과 관련된 기능은 몇 없다.

 

plt.imshow(corr_df)
plt.colorbar() # 값의 색에 대해. 노랑색일 수록 큰, 파랑색일수록 작고, 청록생이 중간이고
plt.show()

 

 

(3)  seaborn 으로 하는 방법 : heatmap()

 

- annot = T : 상관계수 갑을 보여줌. (def : F)

sns.heatmap(corr_df, annot = True) # annot 값 보여줌.

 

 

 

(4)  cmap : colormap / palette - 미리 사용할 색들을 모아놓은 것.
     - color bar 해당 값에 따른 색을 정해 미리 모아둔다. 
     - 일반적으로 그래프 그릴 때 파랑 - > 주황 .. 이렇게 간다. 이것도 색을 미리 모아둔 것.
     - 우리가 만들 수 도 있고, 미리 만들어진 것을 사용할 수도 있다. 

 

# seaborn : heatmap() 색 범위 바꾸기
sns.heatmap(corr_df, annot = True, cmap = 'Blues')

 

 

팔레트 - https://seaborn.pydata.org/tutorial/color_palettes.html#palette-tutorial

 

Choosing color palettes — seaborn 0.11.2 documentation

Components of color Because of the way our eyes work, a particular color can be defined using three components. We usually program colors in a computer by specifying their RGB values, which set the intensity of the red, green, and blue channels in a displa

seaborn.pydata.org

 

 

2.6 lineplot

 

- 선그래프
- 시간의 흐름에 따른 값의 변화를 보여주는데 유용하다. (시계열 데이터)

 

sns.lineplot(x = 시간역할, y = 변화값 컬럼)


- 시계열 데이터는 보통 일시는 인덱스에 있다. x = 'index' 라 하면 index라는 컬럼을 찾을 것이다.
  x에 dataframe의 index를 사용해야 할 경우 = > 따로 조회해서 넣어준다.  -- >  df.index

 

sns.lineplot(x = web_df.index, y = 'Chrome', data = web_df)
plt.xticks(rotation = 40) # tick 라벨을 40도 돌려라

 

- 한 axes 에 여러 컬럼의 데이터를 보고 싶을 때

   - - > 판다스.   seaborn으로 안됨. 한다며 일일이 따로 해줘야 함.

# 판다스
df2 = web_df[web_df.columns[:3]]  # 데이터프레임
df2.plot(kind = 'line')
plt.show()

# seaborn 할 순 있지만 판다스가 편리하다.
plt.figure(figsize = (10,5))
sns.lineplot(x=df2.index, y = 'Chrome', data = df2, label = 'Chrome')
sns.lineplot(x=df2.index, y = 'IE', data = df2, label = 'IE')
sns.lineplot(x=df2.index, y = 'Edge', data = df2, label = 'Edge')