5.4 시각화

모든 종류의 데이터 작업에서 중요한 과제는 관찰자의 관심 질문에 따른 답변 데이터를 제시하는 방법이다. 빅데이터의 경우에는 그 양, 종류, 또는 속도 때문에 이것이 특히 중요하다. 대량의 데이터는 데이터 의미를 추출하는 관찰자의 능력을 압도할 수 있는 잠재력을 갖는다. 모든 미국 시민의 투표 데이터는 어떻게 정치 학자의 필요에 맞게 묘사되어야 하는가? 어떻게 종에 대한 게놈의 모든 데이터로부터 흥미로운 생물학적 질문에 대한 대답을 찾아야 하는가? 어떻게 로맨틱한 시인의 작품을 문학 분석을 위해 사용할 수 있는가? 데이터 형태가 가장 다른 방법에 의해 전달 될 수 있기 때문에 매우 다양한 종류의 데이터는 도전이다. 의미있는 방식으로 다른 표현을 통합하는 것은 어렵다. 예를 들어 건강 관련 정보는 가족의 역사, 게놈 데이터, 의료 테스트 결과, 운동 패턴에 대한 설명, 다이어트 및 영양 기록, 스트레스 요인의 목록이 포함되어 있다. 어떻게 한 개인의 모든 건강 정보를 의사들이 사용할 수 있게 표시 할 수 있는가? 빠른 속도의 데이터는 그 변화가 너무 잦아 관심 있거나 중요한 부분이 손실 될 수 있다. 예를 들어, 의미 있는 추세를 주식 분석가가 볼 수 있도록 하기 위해 어떻게 시장 데이터를 묘사할 수 있을까? 어떻게 교통 엔지니어가 교통 체증을 피하기 위해 더 나은 방법을 결정할 수 있도록 도시 도로 시스템에서 차량의 움직임에 대한 데이터를 나타낼 수 있는가?

 

데이터 시각화는 종종 복잡한 데이터를 표시 할 수 있는 유용한 방법이다. "그림은 천 단어만큼 가치가 있다"라는 속담에는 인간의 시각 시스템의 힘이 반영되어 있다. 시각적 형태로 데이터를 제시하는 것은 패턴을 찾거나 특별한 경우를 감지하는 시각 시스템의 능력을 활용할 수 있게 해준다. 좋은 시각화 방법을 찾는 것은 물론 쉽지 않다. 그림 게임 “Where’s Waldo”를 보면 흥미로운 특징을 숨기는 시각화가 얼마나 만들기 쉬운지 보여준다.

 

2, 3 차원 데이터를 시각화하는 방법은 매우 다양하다. 다음은 여기서 사용될 툴에 의해 생산될 수 있는 시각화에 대한 예이다 (matplotlib 갤러리 http://matplotlib.org/gallery.html). 복잡하고 강력한 시각화를 구축 할 수 있는 지식과 기술을 개발하는 것은 그 자체로 하나의 연구 분야이다. 그러나 시각화의 몇 가지 기본적인 형태는 빅데이터의 "첫 단계" 탐구에 매우 유용하다. 이러한 기본 형태는 다음과 같다.

  • 선 그래프 :시간에 따른 데이터 변경 (예를 들어, 주식 가격의 거래 일 동안 추세).
  • 히스토그램 : 카테고리 세트를 통해 분포를 나타남 (예를 들어, Richter 규모 여섯 단위의 각 달에 얼마나 많은 지진이 있었는지).
  • 지도 플롯 : 지리적 공간에 걸쳐 분포를 나타남 (예를 들어, 지난달에 지진이 발생한 장소들).
  • 2D 플롯 : 두 가지 요인 사이의 상관관계 (예를 들어, 지진의 위치와 위도 또는 경도의 관계)

 

데이터 시각화의 다른 예로써 매일 보는 것들도 있다 : 날씨지도, 허리케인 트랙, 선거지도.

 

데이터를 시각화하는 방법을 설명하기 위해 matplotlib를 사용할 것이다. Matplotlib는 널리 사용되며, 파이썬에서 시각화에 대한 많은 다른 종류를 생성 할 수 있는 기능을 제공한다. 위의 matplotlib 갤러리에서 시각화의 다양한 예를 보았을 것이다. 하지만 다양한 기능을 제공하기 위해 희생시킨 부분도 있다. 단순함이다. 다행히도 matplotlib는 많은 일반적인 경우에 최소 또는 합리적인 노력으로도 결과를 낼 수 있도록 설계되었다. 추가로, matplotlib을 바탕으로 하는 지리상의 플롯에 대한 라이브러리도 살펴볼 것이다.

 

5.4.1 일부 추가 파이썬(Phthon) 기능

Matplotlib은 파이썬(Python) 커뮤니티에서 최고로 인정받고 있는 시각화 툴킷(toolkit)이다. matplotlib을 사용하려면 파이썬의 몇 가지 추가적 측면을 탐구해야한다. 강조할 파이썬의 두 가지 측면은 다음과 같다 :

  • 패키지와 모듈 : 이러한 기능은 배포 및 사용을 위한 유용한 단위로 코드의 큰 틀을 구성하는 데 도움이 된다.
  • 함수 매개 변수와 반환 값 :모든 함수 파라미터는 호출자에 의해 정의 될 하나 이상의 결과를 반환하는 함수를 처리 할 필요가 있다. 이러한 기능은 일반적인 경우에 대처하는 것을 돕는다.

 

Matplotlib을 사용할 수 있도록 도와주는 것과는 별개로, 이러한 추가 기능을 익히는 것은 파이썬에 대한 지식을 심화시켜준다. 또한, matplotlib를 통해 대규모의 소프트웨어 시스템 프로그래밍과 그것이 구성되는 방법에 대한 몇 가지 아이디어를 제공한다.

 

모듈과 패키지

Matplotlib같은 대형 소프트웨어 라이브러리는 애플리케이션을 만들 때 재사용할 수 있도록 수십 혹은 수백 가지 기능을 가질 수 있다. 하지만 많은 경우에 애플리케이션에서 이러한 기능들 중 일부만 필요하게 된다. 배포와 재사용의 용이성을 위하여 파이썬에서는 보통 같이 사용될만한 함수들을 하나의 그룹으로 묶어서 관리한다. 파이썬에서 이러한 함수의 그룹을 모듈(modules)이라고 한다. (재)사용할 수 있는 모듈의 기능을 파이썬에서 import하는 예는 이미 살펴보았다. 여러 모듈은 자체가 더 큰 집합으로 다시 그룹화 될 수 있다. 파이썬에서 이러한 더 큰 컬렉션은 패키지(package)이다.

 

Matplotlib는 다수의 모듈을 포함하는 패키지이다. 이러한 모듈 중 하나가 pyplot 모듈이다. pyplot 모듈은 2D 그래프와 차트를 구성하는 것과 관련된 많은 기능을 가지고 있다. pyplot 모듈의 기능에는 plot, show, title, xlabel, ylabel 등이 있다. 나중에 이 기능들을 사용할 것이다.

 

파이썬에서 패키지 또는 모듈에서 함수 이름이 사용되는 방식을 "점 표기법"라고 한다. 이 표기법에서 plot 함수에 대한 전체 이름은 다음과 같다 :

matplotlib.pyplot.show

 

그러나, 파이썬은 모듈의 "닉네임"을 사용할 수 있는 방법을 제공한다. 한 모델의 여러 함수들을 사용할 경우 이러한 import 형식이 유용하다. 이 예에서와 같이 닉네임은 import 문에서 정의한다 :

import matplotlib.pyplot as plt
# 함수를 별명으로 사용

plt.plot(...)    # plot 데이터
plt.title(...)   # 제목 추가
plot.show(...)   # 윈도우에 데이터 표시

 

여기서 plt는 matplotlib.pyplot 모듈이 프로그램에 정의 된 "닉네임"이다.

 

모듈로부터 단일 (또는 몇 개의) 기능(들)을 사용할 수 있는 경우에만 그 기능(들)을 가져올 수 있다. 예를 들어, 지리적 plots을 생성하기 위한 코드를 포함하는 mpl_toolkits라는 이름의 패키지를 보자. basemap이라 불리는 모듈 패키지는 Basemap(모듈 이름과 함수 이름의 대소문자의 차이에 주의)의 함수 중 하나이다. 코드 예제에서 볼 수 있듯이 오직 Basemap 함수만이 필요하다.

from mpl_toolkits.basemap import Basemap
# Basemap 함수 사용

map = Basemap(...)   #데이터를 plot 할 수 있는 지리적 맵을 생성

 

...import...로 부터 mpl_toolkits.basemap 모듈의 다른 함수를 제외한 Basemap 함수에 대해서만 접근을 제공한다는 것을 기억하는 것이 중요하다.

 

함수에 대해

범용 함수는 많은 파라미터를 갖는 경우가 있다. 예를 들어, scatter plots를 생성하는 matplotlib.pyplot.scatter 함수는 14개의 파라미터를 갖는다. 많은 수의 매개변수가 scatter plot(즉, plot 데이터 포인트의 컬러, plot 데이터 점을 나타내기 위해 사용되는 상징, 점을 연결하는 라인의 폭 등)을 프로그래머가 더 세밀히 제어 할 수 있게 해준다.

 

범용 함수 파라미터는 많은 일반적인 경우에 요구되는 것보다 더 많은 제어를 제공한다. 프로그래머의 작업을 쉽게 하기 위해 파이썬에서는 함수를 정의할 때 매개 변수에 기본 값을 지정할 수 있다. 다음의 matplotlib.pyplot.scatter 함수의 정의에서 기본 값의 사용을 볼 수 있다.

matplotlib.pyplot.scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, 
                          vmax=None, alpha=None, linewidths=None, verts=None, hold=None, **kwargs)

이 예에서, 파라미터 x 및 y는 기본 값이 없다; 즉, 필수이다. 기본 값이 있는 다른 파라미터들은 선택 사항이다. 매개 변수에 값이 지정되지 않은 경우 함수는 기본 값 (20)을 사용하도록 정의되어 있다. 매개 변수 marker에 값이 제공되지 않은 경우도 마찬가지로 함수는 ‘o’의 기본 값을 사용한다.

 

None 값은 함수 호출에 이 매개 변수를 지정하지 않으면 함수에서 이 매개 변수의 값을 사용하는 기능이 무시된다는 것을 의미한다.

 

예를 들어, 파라미터 linewidths=None은 linewidth가 지정되지 않은 경우 scatter plot가 선으로 데이터 포인트들을 연결하지 않음을 의미한다(점들을 연결하려면 선의 두께가 요구되기 때문).

 

기본 매개 변수가 있는 함수를 호출하는 것은 그 기본 값을 오버라이드(override) 할 매개 변수만 제공하면 된다는 것을 의미한다. 물론, 필요한 모든 매개 변수(기본 값이 없는 것)는 제공되어야 한다. 기본 값을 오버라이드하는 경우 구문 pname=pthis는 이름이 pname인 매개 변수가 값 pthis를 갖도록 지정하는 데 사용된다. 다음은 scatter 함수를 호출하는 몇 가지 예들이다.

import matplotlib.pyplot as plt

# scatter plot에 대한 데이터를 정의

lat  = [ ... ]     # x값에 대한 데이터
long = [ ... ]     # y값에 대한 데이터

plt.scatter(lat, long)                    # 1번 호출
plt.scatter(lat, long, marker='+')        # 2번 호출
plt.scatter(lat, long, c='r')             # 3번 호출
plt.scatter(lat, long, marker='+' c='r')  # 4번 호출
plt.scatter(lat, long, linewidths=2)      # 5번 호출

 

이 예에서 다섯 scatter 함수 호출 모두 필수 파라미터를 제공한다.

각 호출의 의미 :

  • 1번 호출 : 모든 비 필수 매개 변수에 기본 값을 사용한다.
  • 2번 호출 : marker를 기본 값 대신 '+'를 사용하고 모든 다른 비 필수 매개 변수는 기본 값을 사용한다.
  • 3번 호출 : c를 기본 값 대신 ‘r’을 사용하고 모든 다른 비 필수 매개 변수는 기본 값을 사용한다.
  • 4번 호출 : marker 는 '+', c ‘r’을 사용하고 모든 다른 비 필수 매개 변수는 기본 값을 사용한다.
  • 5번 호출 : linewidths의 값을 2로 변경하고 모든 다른 비 필수 매개 변수는 기본 값을 사용한다.

 

요약하면, 필수 매개 변수 뒤로 선택적 매개 변수들을 pname=pthis 구문을 사용하여 임의의 순서로 제공하면 된다.

 

범용으로 사용되는 함수의 두 번째 특징은 하나 이상의 값을 반환 할 수 있다는 것이다. 예를 들어, 우리는 화씨(Fahrenheit) 온도를 동등한 섭씨(Celsius) 온도로 변환하는 함수를 보았다. 또한, 화씨(Fahrenheit) 온도를 해당 켈빈(Kelvin) 온도로 변환하는 함수도 보았다. 두 개의 함수를 갖는 것보다는 동시에 첫 번째로 섭씨 온도와 두 번째로 켈빈 온도 값을 반환하는 함수를 정의 할 수 있다. 다음과 같이 이러한 종류의 변환 함수를 정의하고 사용할 수 있다 :

def convert(temp):
     celsius = (temp - 32)/1.8
     kelvin  = ((temp + 459.67)*5) / 9
     return celsius, kelvin

Ftemp = 76   #화씨 온도

Ctemp , Ktemp = convert(Ftemp)

 

위 예에서 return 문이 첫 번째 섭씨 온도와 두 번째 켈빈 온도 두 개의 값을 반환하는 것을 볼 수 있다. 또한, convert 함수 호출의 결과로 좌측 두 변수의 값이 업데이트 된다.

 

5.4.2 Matplotlib 예시

일부 기본적인 matplotlib 시각화를 개발할 것이다. 이 예는 matplotlib의 작동 방식을 맛보기 위한 것이다. 당신의 프로젝트를 위해서는 의심의 여지없이 matplotlib을 더 깊이 탐구해야 한다.

 

이 예는 US Geological Survey(미국 지질 조사소)에 의해 제공된 세계 지진 이벤트 데이터 스트림으로부터 수집 된 데이터를 사용한다. 데모 목적에 사용될 작은 세트를 생성하기 위해 한 달 치 자료를 추렸다. 데이터 세트는 140회의 지진에 대한 정보가 포함되어 있다. 각 데이터 스트림은 세 가지 항목으로 감소시켰다 :

  • 크기 : 각 지진의 진도 목록
  • 위도 : 각 지진의 지리적 위도의 목록
  • 경도 : 각 지진의 지리적 경도의 목록

 

샘플링 된 데이터 세트는 다음과 같다 :


magnitudes = [
                              1.98, 1.8, 1.8, 1.7, 3.1, 2.0, 1.8, 0.6, 2.8, 0.5,
                             2.51, 3.51, 1.4, 2.6, 2.5, 2.4, 2.9, 2.6, 2.8, 2.5,
                                                           ... ]

latitudes = [
                             39.6835 , 60.5828 , 47.4227 , 38.8175 , 19.1345 ,
                              19.4377 , 60.0217 , 38.7978 , 19.1364 , 38.8148 ,
                                                            ... ]

longitudes = [
                              -119.8202 , -151.0144 , -120.1962 , -122.8042 , 
                             -66.4852 , -155.2545 , -152.0147 , -122.741 , -66.476 , -122.8202 ,
                                                            ... ] 

 

지진이 3쌍(magnitudes[i], latitudes[i], longitudes[i])으로 기술되도록 리스트가 구성되었다. 예를 들어, 진도 1.98의 지진은 위도 39.6835, 경도 –119.8202에서, 진도 3.1의 지진은 위도 19.1345, 경도 –66.4852에서 발생했다.

 

목록은 시간 순에 따라 구성되어 있다: 리스트 내의 최초의 지진이 가장 최근, 목록의 마지막 지진이 가장 과거에 발생하였다.

 

전체 샘플링 된 데이터 세트는 다운로드할 수 있는 예제 파일에 포함되어있다.

 

선 그래프

공통된 데이터 분석 주제는 시간과 데이터에 관계가 있는지 여부이다. 지진의 경우 어떤 패턴이 있는지 확인해볼 수 있다. 예를 들어, 시간이 지남에 따라 지진의 진도가 상승하거나 감소하는지 알 수 있다. 선 그래프의 횡축 (x 축)은 시간, 종축 (y 축)은 지진의 크기(진도)이다. 또 다른 주제는 데이터 값과 평균값의 관계이다.

 

다음 코드는 지진의 크기(진도)를 선 그래프로 생성하기 위해 matplotlib를 사용한다. 보기 편하도록 연속적인 데이터 포인트는 선으로 이어져있다. 진도의 평균값을 나타내는 선도 그려진다.

 


# 선그래프 예시

import earthquakes

# AttributeError 나올 시 'import earthquakes' 대신 'from earthquakes import earthquakes' 사용
import matplotlib.pyplot as plt


# magnitudes를 담아둘 리스트 생성
magnitudes = []                              

quakes = earthquakes.get_report("week", "all")


# magnitude를 리스트에 저장
for quake in quakes['earthquakes']:
    magnitudes.append(quake['magnitude']) 


# 평균 크기 계산
avMagnitude = sum(magnitudes)/len(magnitudes)

 

# 진도를 선 그래프로 그린다
plt.plot(magnitudes)

 

# 평균 크기에 대한 선을 추가 : # 선 (len(magnitudes), #avMagnitude)로부터 #(0,avMagnitude)
plt.plot([0, len(magnitudes)] , [avMagnitude, avMagnitude])

 

# 축과 그림 레이블
plt.xlabel('Time')

plt.ylabel('Magnitude')

plt.title('History of Magnitudes')

 

# 히스토그램 표시
plt.show()

 

일반적으로 pyplot 함수는 시각화를 위해 사용된다. 시각화 결과는 별도의 창에 표시된다. 여러 시각화를 순서대로 볼 수 있도록 파이썬 프로그램은 창이 닫힐 때까지 기다린다.

 

위의 코드에서 import 문은 matplotlib.pyplot 모듈에 대한 닉네임을 제공하는 데 사용된다. 내장 sumlen 함수는 평균 크기를 계산하는 데 사용된다. 시각화는 다음의 단계로 구성된다 :

  • plot 함수는 진도의 목록을 사용하여 선 plot을 만들기 위해 사용된다.
  • plot 함수는 Y축에 평균값을 나타내는 직선을 그리기 위해 그 종단점을 정의하는 두 개의 데이터 포인트와 함께 다시 사용된다.
  • xlable과 ylable 함수는 각각의 축에 텍스트 레이블을 추가한다.
  • 전체 디스플레이에도 제목을 부여한다.

 

시각화가 구축된 후에는 show 함수를 이용하여 별도의 창에 이를 표시할 수 있다. 이 시각화 윈도우가 닫힐 때까지 프로그램은 이 시점에서 일시 정지된다. 마지막으로, clf 함수는 matplotlib이 시각화하여 표현하기 위해 사용된 내부 구조를 지운다.

 

선 그래프 코드에 의해 생성 된 시각화는 다음과 같다.

5-29

그림 5-29. 선 그래프 시각화

 

이 시각화는 세 가지를 보여준다.

  • 시간이 지남에 따라 진도에 명백한 패턴은 없음
  • 평균값으로부터 진도가 상당한 변화가 있음
  • 최고 크기의 지진은 드물음

 

이것은 간단한 시각화도 가치가 있음을 보여준다.

 

matplotlib에 의해 표시되는 창은 왼쪽 하단에 컨트롤을 가지고 있다. 컨트롤 위에 커서를 올리면 해당 컨트롤에 대한 간략한 설명을 제공한다. 세 가지 컨트롤이 시각화하는데 유용하다 :

  • 가장 오른쪽 컨트롤은 다양한 표준 형태 중 하나를 사용하여 시각화를 저장한다.
  • 오른쪽에서 두 번째 컨트롤은 줌 컨트롤이다. 이 컨트롤을 누르면 "+" 기호로 커서가 바뀐다. 이 상태에서 직사각형을 선택하면 화면은 이 지역을 확대 할 것이다.
  • 오른쪽에서 세 번째 컨트롤은 pan-zoom 컨트롤이다. 이 컨트롤을 누르면 더블 화살표 기호로 커서가 바뀐다. 마우스 왼쪽 버튼으로 화면을 이동할 수 있다. 마우스 오른쪽 버튼으로 가로/세로로 화면을 확대/축소할 수 있다.
  • 가장 왼쪽의 컨트롤은 원래 상태로 시각화를 초기화한다.

 

선 그래프 코드를 실행하고 이러한 컨트롤을 시험해보라.

 

연습문제: 평균값 선의 위아래로 표준 편차 선도 표시되도록 선형 차트 프로그램에 기능을 추가해보라.

참고: NumPy모듈은 숫자들의 표준 편차를 계산하는 std 함수를 가지고 있다. 코드와 그 결과의 .png 이미지를 제출해보라.

 

히스토그램

라인 차트는 크기에 상당한 변동이 있음을 보여준다. 그러나 크기의 분포는 이 차트에서 보기 어렵다. 히스토그램은 데이터의 분포를 간단히 시각화해준다. 아래에 있는 코드에서 matplotlib의 hist 함수는 진도에 대한 분포를 시각화하는데 사용된다.

 



# 히스토그램 예시
import earthquakes

# AttributeError 나올 시 'import earthquakes' 대신 'from earthquakes import earthquakes' 사용
import matplotlib.pyplot as plt

 
# magnitudes를 담아둘 리스트 생성
magnitudes = []
          
      
quakes = earthquakes.get_report("week", "all")


for quake in quakes['earthquakes']:
    magnitudes.append(quake['magnitude'])
    

# 진도의 Plot 히스토그램
plt.hist(magnitudes, bins=[0,1,2,3,4,5,6,7])

 

# 축 라벨
plt.xlabel('Magnitudes')

plt.ylabel('Occurrences')

plt.title('Histogram of Magnitudes')

 

# 표시 히스토그램
plt.show()

 
# 다음 그래프를 그리기 전에 지우기
plt.clf()

# 다음 그래프를 그리기 전에 지우기
# plt.clf()

 

히스토그램 코드의 대부분은 앞의 예에서 설명했다. 예에서 새로운 것은 hist 함수이다. hist 함수를 호출한 첫 번째 매개 변수는 크기의 목록이며, 두 번째 매개 변수는 매개 변수 이름 bins이다. bins 매개변수는 분포를 위해 종류를 지정하여 호출할 수 있다. 지진(Earthquake)의 크기는 Richter 규모 측정한다. 데이터 세트에서 가장 큰 값은 6과 7 사이 인 것을 선 그래프에서 볼 수 있다. 히스토그램 호출에 주어진 bins 값은 데이터들이 0-1, 1-2, ..., 6-7로 그룹화 되도록 지정한다.

 

프로그램 예시에서 생성 된 히스토그램은 다음 같다.

 5-30

그림 5-30. 히스토그램 시각화

이 시각화를 보면 :

  • 진도는 크기 2 이하에 대부분이 편중되어 있음
  • 5-6 항목에는 지진이 없음(적어도 데이터에는)
  • 가장 심각한 지진 (카테고리 6에 해당)은 드물음

 

위 그림을 통해 진도의 성격에 대해 어느 정도 알게 되었다. 그러나 지진의 발생 위치에 대해서는 아는 것이 없다. 다음으로 이것을 해볼 것이다.

 

연습문제 : bins 인수를 제거하고 차이를 관찰해라. bins인수가 없으면 히스토그램 함수가 카테고리의 수와 그 경계를 결정한다.

연습문제 : pyplot.hist에 대한 설명서를 참조하라. 히스토그램 예제 프로그램에서 누적 분포 함수를 형성하도록 수정해보라.

 

Scatter Plot

데이터 세트에 대하여 흔히 궁금해 하는 것은 두 항목이 어떤 방식으로 서로 관련되었는지의 여부이다. 이 예제의 경우에서는 지진의 위도와 경도 사이에 관계가 있는지를 아는 것이다. 즉, 지진이 발생하는 위치가 무작위적인지, 혹은 지진이 발생할 확률이 높은 지역이 있는지에 대한 것이다.

 

두 데이터 사이의 상관관계를 설명하기 위해 scatter plot이 사용될 수 있다. 데이터 세트 중 하나는 수평축 (x 축)에 대한 좌표로 처리되고 또 다른 데이터 세트는 수직축 (y 축)에 대한 좌표로 처리된다. x[i]는 하나의 데이터 세트이고 y[i]는 이 데이터 세트에 대응하는 다른 데이터 세트일 때 (x[i], y[i]) 위치에 점이 찍힌다.

 

scatter plot 상의 점들이 임의적이라면 두 데이터 세트 사이에 관련이 없다는 것을 의미한다. 점들에 클러스터 또는 패턴이 나타난다면 상관관계가 있다는 시각적인 증거이다. 통계적 방법으로 이러한 상관관계가 우연인지 여부를 검증해야 한다.

 

다음은 지진의 경도와 위도에 대한 scatter plot를 생성하는 예제이다. 전체 코드는 여기에서 다운로드 할 수 있다.

import earthquakes

# AttributeError 나올 시 'import earthquakes' 대신 'from earthquakes import earthquakes' 사용
import matplotlib.pyplot as plt

import matplotlib.pyplot as plt

 
# 실제 데이터에서 샘플링된 지진의 위도와 경도 데이터 모을 공간
location = []

latitudes = []

longitudes = []

# 데이터 불러오기
quakes = earthquakes.get_report("week", "all")


for quake in quakes['earthquakes']:
    latitudes.append(quake['location']['latitude'])
    longitudes.append(quake['location']['longitude'])

    
# 2D 좌표에 지진 위치의 scatter plot를 생성

# 지진의 발생 위치(longitude[i], latitude[i])에 빨간색 '+'기호 생성
plt.scatter(longitudes, latitudes, c='r', marker='+')

 

# 축 라벨
plt.xlabel('Longitude')

plt.ylabel('Latitude')

plt.title('Earthquake Occurrences')

plt.show()

 

# 다음 그래프를 그리기 전에 지우기
#plt.clf()

 

scatter plot 예제에서 대부분 코드는 이전의 예에서 봐서 익숙할 것이다. 새로운 요소는 scatter plot을 생성하기 위한 pyplot.scatter 함수의 사용이다. 이 경우 두 개의 필수 매개 변수는 각 지진의 경도와 위도 데이터의 목록이다. 2 가지 선택적 매개변수도 사용 가능하다. c라는 이름의 매개 변수는 사용자가 plot 포인트에 무슨 색깔을 사용할지 지정할 수 있다. 붉은 색은 글자 ‘r’로 표시된다. 두 번째 선택적 매개 변수인 marker는 사용자가 그린 점에 사용할 상징을 지정할 수 있다. 이 경우에는 '+'기호가 사용된다.

 

예제 프로그램에 의해 생성 된 scatter plot 시각화는 다음과 같다. 이는 데이터에 클러스터가 있음을 시각적으로 명백히 보여준다. 이것은 샘플 데이터에서 지진이 다른 곳보다 더 많이 발생하는 곳이 있음을 의미한다.

 5-31

그림 5-31. Scatter Plot 시각화

 

matplotlib 화면 창에서 pan-zoom을 사용하면 지진의 클러스터링이 얼마나 한 곳에 집중되어 있는지 볼 수 있다. 다음 그림은 왼쪽 상단 모서리에 있는 지진 클러스터를 확대하여 보여준다.

 5-32

그림 5-32. Scatter Plot의 시각화 클러스터의 확대도

 

확대한 그림에서 위도 60과 65도 사이, 그리고 경도 –160과 –140사이 지역에서 지진의 상당수가 발생하는 것을 볼 수 있다. 지진의 다른 클러스터도 유사한 방식으로 탐색할 수 있다.

 

그러나 scatter plot만 봐서는 이러한 클러스터와 지진의 크기 사이에 어떤 관계가 있는지는 말할 수 없다. 이 클러스터는 빈번하지만 약한 지진만 포함하고 강한 지진은 다른 지역에서 발생하는가? 혹은 강한 지진들도 이 클러스터에서 발생하는가? 이 질문에 대답하기 위해서는 데이터의 추가적인 분석이 필요하다.

 

연습문제 : 경도 60과 65도 사이, 그리고 위도 -160과 –140도 사이 지역에서 발생한 지진만 표시되도록 데이터 세트를 필터링하라. 그리고 이 지진들의 진도 분포를 그려 보라. 어떤 결론을 도출 할 수 있는가? 코드, 시각화 결과 .PNG 파일, 그리고 분석 결과를 제출하라.

 

위의 scatter plot는 지구상에 지진이 발생하는 위치는 명확하게 표시하지 않는다. 우리가 본 클러스터에서 이런 정보는 특히 흥미로울 것이다. 지도 plots를 사용하면 이를 확인해볼 수 있다.

 

막대차트

막대 차트는 다른 종류의 데이터를 비교하는 데 사용된다.


# 막대 차트 예시

# 평균 계산 함수
import numpy
from earthquakes import earthquakes


import matplotlib.pyplot as plt

magnitudes1 = []
magnitudes2 = []
magnitudes3 = []
#magnitudes4 = []
          

# 실제 데이터 스트림에서 샘플링 지진의 진도
# month는 data에 없음                   
quakes1 = earthquakes.get_report("hour", "all")
quakes2 = earthquakes.get_report("day", "all")
quakes3 = earthquakes.get_report("week", "all")
#quakes4 = earthquakes.get_report("month", "all")


for quake in quakes1['earthquakes']:
    magnitudes1.append(quake['magnitude']) #, dtype=numpy.float64
    
for quake in quakes2['earthquakes']:
    magnitudes2.append(quake['magnitude'])
    
for quake in quakes3['earthquakes']:
    magnitudes3.append(quake['magnitude'])
    
#for quake in quakes4['earthquakes']:
#    magnitudes4.append(quake['magnitude'])


avg_magnitudes1 = numpy.mean(magnitudes1)
avg_magnitudes2 = numpy.mean(magnitudes2)
avg_magnitudes3 = numpy.mean(magnitudes3)
#avg_magnitudes4 = numpy.mean(magnitudes4)

 
labels = ['hourly', 'daily', 'weekly', 'monthly']

# 막대바의 x 위치를 계산해야한다

# range는 특정 길이의 목록을 생성하는 데 사용

# len은 주어진 리스트의 길이를 계산하는 데 사용

# 이 둘이 합쳐서 다음 목록을 생성 : [0, 1, 2, 3]

x_positions = range(len(labels))
 

# 진도의 Plot 히스토그램

# 수평 막대차트를 생성하는 plt.barh 함수도 있다 plt.bar(x_positions, avg_magnitudes)

# 막대 차트의 X 축 라벨

# 이 함수는 또한 Y 축에 라벨을 추가할때도 사용할 수 있다

plt.xticks(x_positions, labels)


plt.bar([0,1,2], [avg_magnitudes1, avg_magnitudes2, avg_magnitudes3])
 

# 축 라벨

plt.xlabel('Average Magnitudes')

plt.ylabel('Time Period')

plt.title('Comparison of Average Magnitudes in Different Time Periods')

 

# 막대 차트 표시

plt.show()

# 다음 그래프를 그리기 전에 지우기

plt.clf()

 

지도 Plot

종종 지리적 지도의 형태로 데이터를 시각화할 필요가 있다. 현재 우리의 경우 전 세계 또는 국가에서 지진이 발생한 위치를 표시하기 위해 전 세계 또는 국가 지도에 데이터를 표시해야 한다. 지리적 매핑이 유용한 경우는 많다. 지리적 지도와 시각화는 유권자 데이터, 역학 데이터, 기상 데이터, 인구 데이터, 천연 자원 데이터 등을 표시 할 수 있는 좋은 방법이다.

 

위도와 경도는 구형의 지구에서 한 지점을 특정한다. 이 지점에 대한 2차원적 시각화를 만드는 것은 약간 까다롭다. 오렌지에 펜으로 점을 찍는 것을 상상해 보라. 2차원 지도를 만드는 것은 오렌지의 껍질을 벗겨 이를 평면에 펼치는 것과 같다. 오렌지의 표면에서 점을 쉽게 알아볼 수 있도록 이를 수행할 수 있는 방법이 무엇인지 고민해야한다. 때때로 더 균일한 표면을 형성하도록 껍질을 늘리면 패턴을 찾기 쉬워진다. 그러나 이는 점 사이의 거리를 왜곡한다. 지도를 만드는 제작자들은 평평한 2 차원 상에 3차원 구형을 투영할 다수의 다른 방법을 고안했다. 지도 투영에 대한 자세한 내용은 여기를 참조하라(http://en.wikipedia.org/wiki/Map_projection). 아래 예제는 1892 년에 이를 개발한 Ernst Hammer의 이름을 딴 Hammer 투영법을 사용한다. Hammer 투영은 다음과 같다 :

5-33 

그림 5-33. Hammer 투영

 

아래 예제는 Basemap 함수를 사용하여 투영을 수행한다. 이 함수는 mpl_toolkits 패키지에 포함되어 있다. 이 패키지는 matplotilib를 바탕으로 만들어졌으며, 다양한 응용 분야에서 사용될 수 있도록 이를 확장한다.

basemap 모듈은 Basemap 함수(모듈 이름과 함수 명 사이의 대소문자 차이를 주목)를 포함한다. Basemap 함수는 Hammer 투영과 같은 다양한 투영 기능을 구현한다. 가능한 투영 기능의 목록은 Basemap 문서에 설명되어 있다.

데이터를 지리적으로 시각화하는 주요 단계는 다음과 같다 :

  1. Basemap을 사용하여 투영을 정의
  2. 위도와 경도 좌표를 투영도 상의 좌표로 전환
  3. matplotlib.scatter 함수를 사용하여 지도상에 변환된 좌표를 plot

 

이 세 단계는 아래 코드에 주석으로 표시되어 있다. 전체 코드는 여기에서 다운로드 할 수 있다.

#Hammer 투영을 사용한 지도 plot

import matplotlib.pyplot as plt

from mpl_toolkits.basemap import Basemap

 

# 실제 데이터 스트림에서 샘플링된 지진 발생지의 위도와 경도

# 지진 i는 (latitude[i], longitude[i])에서 발생

latitudes = [

                              39.6835 , 60.5828 , 47.4227 , 38.8175 , 19.1345 ,

                              19.4377 , 60.0217 , 38.7978 , 19.1364 , 38.8148 ,

                              ... ]

 

longitudes = [

                              -119.8202 , -151.0144 , -120.1962 , -122.8042 ,                                   -66.4852 , -155.2545 , -152.0147 , -122.741 ,                                     -66.476 , -122.8202 ,

                              ...]

 

# Hammer (eliptical, equal-area) 투영으로 세계지도 만들기

# 경도 180도를 중심으로 (즉, 시각화상의 경도 0도는 지구상의 경도 180도)

map = Basemap(projection='hammer',lon_0=180) # Step 1

 

# 대륙의 윤곽 그리기

map.drawcoastlines()

 

# 위도와 경도를 세계지도상 좌표로 변환

x, y = map(longitudes,latitudes) # Step 2

 

# 세계지도 상에 위치를 매핑

map.scatter(x, y) # 3 단계

plt.title('Locations of earthquakes')

plt.show()

 

plt.clf()

 

Basemap 함수가 투영을 수행하는 방법(1 단계)에 대한 정보가 담긴 map을 반환하는 것에 주목하라. 이 map에 두 가지 매개 변수(투영할 위도와 경도)를 전달하여(단계 2) 두 값(투영도 상의 좌표)을 반환받는다. 이렇게 투영된 좌표는 scatter plot 함수 (단계 3)에 대한 입력으로 사용된다. 시각화가 이해되기 쉽도록 drawcoastlines함수를 사용하여 대륙을 표시한다. 이것이 시각화 결과이다.

 5-34

그림 5-34. 세계지도에 그려진 지진 데이터 (Hammer 투영)

 

지구의 시각화는 앞서 본 지진의 두 개의 클러스터가 California(캘리포니아)와 Alaska(알래스카)의 해안에 있는 것을 알 수 있다. 일반적으로는, 지진의 대부분이 환태평양 지역에 있는 것을 알 수 있다. 상세한 지진의 분포를 연구하려면 훨씬 더 광범위한 데이터가 필요할 것이다.

 

5.4.2 더 나아가기

이 간략한 설명은 빙산의 일각에 불과하다. 이것은 단지 matplotlib의 일반적인 사용법에 대한 간단한 오리엔테이션을 제공하기 위한 것이다. matplotlib가 할 수 있는 것은 훨씬 더 많다. 프로젝트에서는 당연히 matplotlib의 고급 기능 중 일부를 사용하게 될 것이다. 웹에서도 많은 도움을 받을 수 있다. 이 튜토리얼에서부터 시작하면 좋을 것이다(http://pythonprogramming.net/matplotlib-graphing-series/). 이 외에도 좋은 자료는 많다. matplotlib 문서(http://matplotlib.org/api/pyplot_api.html)도 많은 도움이 될 것이다.

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*