[Matplotlib] 00. Intro + 01. Page Setup

in #kr-dev7 years ago (edited)

"""
제 개인적 목표는

  1. Github와 친해지기
  2. Object-Oriented Programming과 친해지기 입니다.

이 목표에 닿기 위해 일단 제가 나름 좀 아는 Python, 그 중에서도 NumpyMatplotlib로부터 시작하려 합니다.
"""

00. Intro

저는 제 직업 상, 데이타의 시각화를 자주 행하고 있으며, 대부분의 도표/차트를 Matplotlib 모듈을 통해 그리고 있습니다. 그런데 제가 Matplotlib를 체계적으로 배운게 아니고, 필요한 기능에 대한 지식을 조금씩 늘려왔기 때문에, 한 번 정리할 때가 되었음을 느끼고 있었습니다. 또한 차트를 그릴 때, 예전 코드를 복사해온 후 조금씩 수정하며 이용하다보니, 정리가 안된, 지저분해 보이는 코드가 반복되고 있습니다. 그래서 이번 기회를 통해 객체 지향적(object-oriented) 접근을 도입하여, 제가 많이 쓰는 주요 기능들이 담긴 Class를 만들어 '정리된' 코드를 구축하고, 또한 정리물을 Github에 올려보는 것이 제 목표입니다.

Matplotlib를 체계적으로 소개하기 위해, 1. Page setup, 2. Axes setup 및 꾸미기, 그리고 마지막으로 3. 여러 종류의 차트를 차례로 정리해 보도록 하겠습니다. Numpy의 경우, Matplotlib를 소개하기 위한 보조 툴로써, 특히 예제용 데이타를 생성하고 가공할 때 이용해보도록 하겠습니다.

거창하게 계획을 얘기했지만, 부족한 점이 많을 것 같습니다. 사실 지금은, '나중에 어떻게 되겠지'라는 안일한 마음가짐으로, 일단 첫 발걸음을 떼어 보도록 하겠습니다.

제 코드는
Python 3.5.3
Numpy 1.11.0
Matplotlib 1.5.1
기준임을 알려드립니다.
Python2를 쓰시는 분은 "print"만 바꿔주시면 문제 없을 것입니다. (아마도)
예) Python3: print("Test") ==> Python2: print "Test"

01. Page Setup

Figure instance는 모든 종류의 그림(plot)을 관장하는 최상위 객체입니다. 쉽게 말해 Figure를 정의함으로써 그림그리기가 시작됩니다. 이 Figure instance를 정의하고 손보는 것을 저는 "페이지 셑업"이라고 이름붙였습니다. Figure밑에 Axes가 정의되고, 이후 각종 그림(plot)의 세부사항이 정해집니다. 이번 포스팅에서는 Axesplot은 최소한도로만 이용하고, Figure에 집중해보겠습니다.

"1_page_setup.py3.py"

import sys
import numpy as np
import matplotlib.pyplot as plt

###--- Synthesizing data to be plotted ---###
x = np.arange(5)     # Same as x = np.array(range(5))
y = x**2             # Basically item-wise calculation for numpy arrays


###--- Plotting Start ---###  

##-- Page Setup --##
fig = plt.figure()            # Define "figure" instance
fig.set_size_inches(6,4.5)    # Physical page size in inches, (lx,ly)
suptit="TEST"
fig.suptitle(suptit,fontsize=15)   # Title for the page

##-- Plotting for axis1 --##
ax1 = fig.add_subplot(1,1,1)   # subplot(# of rows, # of columns, indicater)
ax1.plot(x,y)                                      # plotting line graph

##-- Seeing or Saving Pic --##

#- If want to see on screen -#
#plt.show()

#- If want to save to file
outdir = "./"
outfnm = outdir+"1_page_setup.basic1.png"     # File format is decided by the file name, eg. png here
fig.savefig(outfnm,dpi=100)   # dpi: pixels per inch

sys.exit()



위 프로그램을 실행시키면 다음과 같은 그림이 나옵니다.
page_setup.basic1.png

x축, y축, 선 모양 등 만져야 할 곳이 여럿이지만, 다음을 위해 남겨놓겠습니다.

위 프로그램 중 중점적으로 살펴볼 명령어들은,

  1. fig = plt.figure()
    Figure 객체가 생성되었습니다. plt는 처음에 matplotlib.pyplot를 가져온 후 정의된 약어입니다.

  2. fig.set_size_inches(6,4.5)
    페이지의 물리적 크기를 정합니다. 단위는 인치(inch)이며, 첫째가 가로, 둘째가 세로 길이 입니다.
    설정된 숫자 2개를 서로 바꾸어 적용하면 이런 그림이 나옵니다.

    실제 그림의 크기는 뒤에 나올 dots per inch (dpi)와 조합하여 결정됩니다.

  3. fig.suptitle(suptit,fontsize=15)
    페이지 전체의 제목을 표시합니다.
    제목의 위치(예: x=0.,5 y=0.98)와 더불어 Text 개체의 여러 설정들을 적용시킬 수 있습니다. (예: 배열, 글자폭, 등등)

  4. fig.savefig(outfnm,dpi=100)
    그림을 파일로 저장합니다. 그림의 포맷은 그림 이름으로 정해준 확장자를 보고 알아서 처리해줍니다. 👍
    dpi는 1인치 간격 안의 해상도를 뜻합니다. 그래서 위 그림의 크기는 600 x 450 pixels가 됩니다.
    저는 잘 안쓰지만, 옵션으로 facecolor와 transparency를 적용할 수 있습니다.

4.1 fig.savefig(outfnm,dpi=100,facecolor='0.8')

color에서 0.0에서 1.0 사이의 숫자를 문자열로 정의하면 회색을 나타내며, 0.0은 검정, 1.0은 흰색을 뜻합니다. 색깔에 대해서는 다음에 더 자세히 다뤄보도록 하겠습니다.

4.2 fig.savefig(outfnm,dpi=100,facecolor='0.8',transparent=True)

그림 개체가 투명해지니 뒷 배경의 회색이 다 드러나게 되었습니다.

4.3 만약 그림의 제목이 무지무지 긴 경우는 어떻게 될까요?
먼저 위 코드에 정의된 suptit를 바꿔보겠습니다.

suptit="TEST"; suptit2=""
for i in range(10):
    suptit2+=suptit+" {} ".format(i)
fig.suptitle(suptit2,fontsize=15)   # Title for the page


정의된 페이지 밖으로 삐져나간 글자는 잘려서 안보이고 있습니다.
이럴 때에는 이런 옵션을 적용시킬 수 있습니다.
fig.savefig(outfnm,dpi=100,bbox_inches='tight')



이상 Page Setup 항목을 마치고, 다음에는 Axes Setup에 대해 정리하겠습니다.

Sort:  

좋은 아침(?) 입니다. ^^

겹치는 게 참 많네요. ^^;

전 요새.. 파이선 공부중인데.. 시각화 쪽은 아니고 전 자동화 쪽에..^^; 업무 연관성이 그쪽에 있다보니.

파이선이 대세이긴 한듯 하네요...

워낙 다재다능 하잖아요..
계산이 좀 느린거 말고는 정말 편하죠.
그런데 같은 파이선이라고 해도 자동화라면 뭘 어떻게 하는지 저로선 전혀 모르겠네요. ㅋㅋ

빌드 자동화나 테스트 자동화.. 이런 쪽이죠.

간단한 알고리즘 수행? 같은 것도 있구요.

데이터 시각화 중요합니다~
저도 나중에 참고할께요.

네 나중을 위해 차근차근 넓혀가도록 하겠습니다.

요즘 파이선 대세죠 ㅎㅎ

익히기 쉬운 면에서는 정말 탁월한 것 같아요~

저도 스팀잇 봇을 한번 만들어보려고 공부중입니다 ㅎㅎ

1일 1회 포스팅!
1일 1회 짱짱맨 태그 사용!
^^ 즐거운 스티밋의 시작!