6. 그래프

김동웅·2021년 8월 22일
0

Pandas with python

목록 보기
6/23

Matplotlib 기본 그래프 도구

  • 데이터 분석에서 다루는 데이터의 종류는 매우 다양하다.
    그래프를 이용하면 데이터의 구조와 패턴을 파악하기 쉽다.

Matplotlib은 파이썬 시각화 도구라고 부를 수 있을 정도로 2D평면 그래프에 관한 다양한 포맷과 기능을 제공한다.

  • 기본 사용법
    - matplotlib.pyplot 을 임포트하여 "as plt" 와 같이 약칭으로 plt로 임포트한다.

    import matplotlib.pyplot as plt

  • 한글 폰트 오류 해결
    - matplotlib은 한글폰트를 지원하지 않는 문제가 있다. 다음과 같은 코드를 사용하면 한글 폰트가 깨지는 현상을 해결할 수 있다.
    from matplotlib import font_manager,rc
    font_path = "" 폰트파일 위치
    font_name = font_manager.FontProperties(fname=font_path).get_name()
    rc('font',family=font_name)

1. 선 그래프

  • 연속적인 값의 변화와 패턴을 파악하는데 적합

ex)

import pandas as pd
import matplotlib.pyplot as plt


# 한글 폰트문제 해결 
from matplotlib import font_manager,rc
font_path = "" 폰트파일 위치
font_name = font_manager.FontProperties(fname=font_path).get_name()
rc('font',family=font_name)
df = pd.read_excel(path,engine='openpyxl',header=0)

# 누락값(NaN)을 앞데이터로 채움
df = df.fillna(method='ffill')

# 서울에서 다른 지역으로 이동한 데이터만 추출하여 정리 
mask = (df['전출지별'] == '서울특별시' ) & (df['전입지별'] != '서울특별시')
df_seoul = df[mask]

# 전출지별 열 삭제
df_seoul = df_seoul.drop(['전출지별'],axis=1)

# 전입지별-> 전입지 이름변경
df.seoul.rename({'전입지별':'전입지'},axis=1,inplace=True)

# 전입지 열을 행인덱스로 변경
df_seoul.set_index('전입지',inplace=True)

# df_seoul에서 '전입지'가 '경기도'인 행 데이터를 선택하여 sr_one에 저장한다.
sr_one = df_seoul.loc['경기도']

# x축 = sr_one.index, y축 = sr_one.value 으로 한 그래프를 그린다. 
plt.plot(sr_one)으로 입력해도 가능.

plt.plot(sr_one.index,sr_one.values)

# 차트 제목 설정
plt.title('서울->경기 인구이동')

# 축이름추가

plt.xlabel('기간')
plt.ylabe('이동 인구수')

plt.show()

실행결과


2. 그래프 꾸미기

0. 그림틀 크기 설정

  • plt.figure(figsize(가로크기,세로크기))

1. 제목 설정

  • plt.title('제목')

2. 축이름 설정

  • plt.xlabel('x축이름')
  • plt.ylabel('y축이름')

3. 범례 설정

  • plt.legend(labels=['범례이름'],loc='best',font_size=범례크기)
    loc옵션은 범례의 위치인데, 디폴트값은 'best'이며 'upper right', 'lower left'등등의 옵션이 존재한다.

4. 눈금라벨 설정

  • x축 눈금라벨 크기 설정 및 회전 :
    plt.xtics(눈금라벨크기,rotation='vertical')
    rotation 옵션에 숫자입력하면 해당숫자 각도만큼 반시계 방향으로 회전한다.

  • y축 눈금라벨 크기 설정 및 회전 :
    plt.ytics(눈금라벨크기,rotation='vertical')
    rotation 옵션에 숫자입력하면 해당숫자 각도만큼 반시계 방향으로 회전한다.

5. 스타일서식 설정

  • plt.style.use('서식종류')
    matplotlib 스타일 서식의 종류는
    'ggplot', 'classic', ' 'bmh', 'dark_background', 'fast', 'grayscale', 'seaborn' 등등 여러 종류가 존재한다.

다음과 같은 코드를 통해 스타일 서식의 옵션의 종류를 확인할 수 있다.

import matplotlib.pyplot as plt

print(plt.style.available)

6. x축, y축 범위 조절

  • plt.ylim(최솟값,최댓값)
  • plt.xlim(최솟값,최댓값)

7. 주석 설정

  • 주석내용, 주석내용을 넣을 위치, 정렬 방법 등을 annotate() 함수에 전달하여 주석을 넣을 수 있다.

또한 arrowprops 옵션을 사용하면 텍스트 대신 화살표가 표시된다.

ex)

import pandas as pd
import matplotlib.pyplot as plt

from matplotlib import font_manager, rc
font_path = r'C:\Users\kjt63\OneDrive\바탕 화면\python\data_analysis\sample\part4\malgun.ttf'
font_name = font_manager.FontProperties(fname=font_path).get_name()
rc('font',family=font_name)

df = pd.read_excel(r'C:\Users\kjt63\OneDrive\바탕 화면\python\data_analysis\sample\part4\시도별 전출입 인구수.xlsx',header=0)
df = df.fillna(method='ffill')

mask = (df.전출지별 == '서울특별시') & (df.전입지별 != '서울특별시')

df_seoul = df[mask]
df_seoul = df_seoul.drop('전출지별',axis=1)
df_seoul.rename({'전입지별':'전입지'},axis=1,inplace = True)
df_seoul.set_index('전입지',inplace=True)

sr_one = df_seoul.loc['경기도']

plt.style.use('ggplot')
plt.figure(figsize=(14,5))
plt.xticks(size=10,rotation=90)
plt.plot(sr_one.index,sr_one.values,marker='o',markersize=10)
plt.title('서울 to 경기',size=20)
plt.xlabel('연도')
plt.ylabel('이동인구수')
plt.legend(labels=['서울->경기'],loc='best',fontsize=15)


# y축 범위 지정 plot.ylim(최소값,최대값)
plt.ylim(50000,800000)

# 화살표1 주석
plt.annotate('', # 주석이름
	    xy=(20,620000), # 화살표의 머리부분(끝점)
	    xytext=(2,290000), # 화살표의 꼬리부분(시작점)
    	    xycoords='data', # 좌표체계
            arrowprops=dict(arrowstyle='->', color='skyblue', linewidth=5) # 화살표 서식
            )
            
# 화살표1 주석위에 붙힐 주석

plt.annotate('인구 이동 증가(1970-1995)',
	xy=(10,550000), # 텍스트 위치 기준점
    	rotation = 25, # 텍스트 회전 각도
        va='baseline', # 텍스트 상하정렬
        ha='center', # 텍스트 좌우정렬
        fontsize=15 # 텍스트 크기설정 
        )
        
        

# 화살표2
plt.annotate('', # 주석이름
	    xy=(47,450000), # 화살표의 머리부분(끝점)
	    xytext=(30,580000), # 화살표의 꼬리부분(시작점)
    	    xycoords='data', # 좌표체계
            arrowprops=dict(arrowstyle='->', color='olive', linewidth=5) # 화살표 서식
            )
            
# 화살표2 주석위에 붙힐 주석

plt.annotate('인구 이동 감소(1995-2017)',
	xy=(40,560000), # 텍스트 위치 기준점
    	rotation = -11, # 텍스트 회전 각도
        va='baseline', # 텍스트 상하정렬
        ha='center', # 텍스트 좌우정렬
        fontsize=15, # 텍스트 크기설정 
        )

plt.show()

실행 결과


3. 화면 분할하여 그래프 여러개 그리기 - axe 객체 활용

  • 화면을 여러 개로 분할하고 분할된 각 화면에 서로다른 그래프를 그리는 방법이다.

Step 1. figure()함수를 이용하여 그래프를 그리는 그림틀(fig) 생성

Step 2. figsize옵션으로 그림틀 크기설정

  • fig = plt.figure(figsize=(가로크기,세로크기)

Step 3. fig객체에 add_subplot()메소드를 이용하여 그림틀을 분할한다.

  • ax1 = fig.add_sublplot(행크기,열크기,서브플롯순서)
    ax2 = fig.add_sublplot(행크기,열크기,서브플롯순서)
    ax1,ax2은 fig라는 그림틀내부의 각각의 그래프객체가 된다.

Step 4. axe객체에 plot()메소드를 적용하여 그래프를 출력한다.


# marker옵션으로 'o'를 사용하지않고 그냥 'o'로 적용하면 점그래프가된다.
ax1.plot(sr_one,'o',markersize=10)

ax2.plot(sr_one,marker='o',markerfacecolor='green',markersize=10, color='olive',linewidth=2,label='서울->경기')
ax2.legend(loc='best')

+ 하나의 그림틀 내부에 존재하는 그래프객체를 꾸밀때에는

set_title,
set_xlabel,set_ylabel
set_ylim, set_xlim,
set_xticklabels(눈금라벨설정),tick_params(눈금라벨크기),
legend(범례) 메소드를 사용한다.
  • 선그래프 꾸미기 옵션
  1. 'o' : 점그래프

  2. marker='o' : 마커모양 (ex: '+', '*', '.' , 'o')

  3. markerfacecolor = 'green' : 마커 배경색

  4. color = 'olive' : 선의 색

  5. linewidth = 2 : 선의 두께

  6. label : 범례설정
    legend 메소드를 사용해서도 설정할 수 있다.

4. 화면 분할 예제

  • 서울->충남,경북,강원,전남 인구이동 그래프 그리기
import pandas as pd
import matplotlib.pyplot as plt

from matplotlib import font_manager, rc
font_path = r'C:\Users\kjt63\OneDrive\바탕 화면\python\data_analysis\sample\part4\malgun.ttf'   #폰트파일의 위치
font_name = font_manager.FontProperties(fname=font_path).get_name()
rc('font', family=font_name)

df = pd.read_excel(r'C:\Users\kjt63\OneDrive\바탕 화면\python\data_analysis\sample\part4\시도별 전출입 인구수.xlsx',engine='openpyxl',header=0)
df = df.fillna(method='ffill')

mask = (df.전출지별 =='서울특별시') & (df.전입지별 != '서울특별시')

df_seoul = df[mask]

df_seoul = df_seoul.drop('전출지별',axis=1)

df_seoul.rename({'전입지별':'전입지'},axis=1,inplace=True)

df_seoul.set_index('전입지',inplace=True)

col_years = list(map(str,range(1970,2018)))

df_4 = df_seoul.loc[['충청남도','경상북도','강원도','전라남도'], col_years]

plt.style.use('ggplot')

fig = plt.figure(figsize=(20,10))

ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
ax4 = fig.add_subplot(2,2,4)

ax1.plot(col_years, df_4.loc['충청남도',:],marker='o',markerfacecolor='green',
        markersize=10,color='olive',lw=2,label='서울->충남')
ax2.plot(col_years, df_4.loc['경상북도',:],marker='o',markerfacecolor='blue',
        markersize=10,color='skyblue',lw=2,label='서울->충남')
ax3.plot(col_years, df_4.loc['강원도',:],marker='o',markerfacecolor='red',
        markersize=10,color='magenta',lw=2,label='서울->강원')
ax4.plot(col_years, df_4.loc['전라남도',:],marker='o',markerfacecolor='orange',
        markersize=10,color='yellow',lw=2,label='서울->전남')


ax1.legend(loc='best')
ax2.legend(loc='best')
ax3.legend(loc='best')
ax4.legend(loc='best')


ax1.set_title('서울->충남 인구이동')
ax2.set_title('서울->경북 인구이동')
ax3.set_title('서울->강원 인구이동')
ax4.set_title('서울->전남 인구이동')

ax1.set_xticklabels(col_years,rotation=90,size=5)
ax2.set_xticklabels(col_years,rotation=90,size=5)
ax3.set_xticklabels(col_years,rotation=90,size=5)
ax4.set_xticklabels(col_years,rotation=90,size=5)

plt.show()

실행결과

0개의 댓글