🌔

4일차 데이터 시각화

notion imagenotion image

목차

 

EDA

탐색적 자료 분석

  • 데이터를 분석하기 전에 그래프나 통계적인 방법으로 데이터를 직관적으로 바라보는 과정
  • 데이터를 있는 그대로 바라보는데 중점을 맞추어 데이터가 가지고 있는 의미를 다양한 각도로 바라보고 이해

EDA 목적

  • 데이터 수집 의사를 결정
  • 데이터 유형에 맞는 모델을 선택
  • 변수들 사이의 관계를 파악

Graph Visualization

Matplotlib를 이용한 시각화

  • plotly와 같은 최신 시각화 패키지에 비하면 투박하다고 생각될 수 있으나, 거의 모든 운영체제와 출력형식을 지원하고 있어 아직도 유용한 패키지 중 하나
  • 2003년 0.1 출시, 17년이된 패키지
 
  • % matplotlib inline : jupyter notebook 내에서 output을 보여줌
  • ! : 콘솔에서 사용가능한 명령어를 사용가능하게 해줌
  • matplotlib 기본 구성 : 그림(figure), 축(axes)
  • fig.savefig() : figure에 있는 이미지를 저장
import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline
x = np.linspace(0, 10, 100) fig = plt.figure() plt.plot(x, np.sin(x), '-') # 실선으로 sin그래프 그리기 plt.plot(x, np.cos(x), '--') # 파선으로 cos그래프 그리기 plt.plot(x, np.tan(x), '--^') # 파선에다가 삼각형선으로 tan그래프 그리기
Out[-]
[<matplotlib.lines.Line2D at 0x186c8e58f98>]
notion imagenotion image
 
fig.savefig('test.png')
# 버전 확인 !python --version
Out[-] Python 3.7.3
!dir
Out[-] C 드라이브의 볼륨에는 이름이 없습니다. 볼륨 일련 번호: CC5E-6766 C:\Users\leehojun\Google 드라이브\11_1. 콘텐츠 동영상 결과물\006. 데이터분석 강좌\04. 4일차\최종강의자료 디렉터리 2020-03-30 01:34 <DIR> . 2020-03-30 01:34 <DIR> .. 2020-03-30 01:25 <DIR> .ipynb_checkpoints 2020-03-30 01:34 34,368 004일차_Graph_Visualization.ipynb 2020-03-30 01:34 16,234 test.png 2개 파일 50,602 바이트 3개 디렉터리 17,973,571,584 바이트 남음
from IPython.display import Image Image('test.png') # 저장한 'test.png'를 불러오기
Out[-]
notion imagenotion image
 
fig.canvas.get_supported_filetypes() # figure가 지원하는 타입확인
Out[-] {'ps': 'Postscript', 'eps': 'Encapsulated Postscript', 'pdf': 'Portable Document Format', 'pgf': 'PGF code for LaTeX', 'png': 'Portable Network Graphics', 'raw': 'Raw RGBA bitmap', 'rgba': 'Raw RGBA bitmap', 'svg': 'Scalable Vector Graphics', 'svgz': 'Scalable Vector Graphics', 'jpg': 'Joint Photographic Experts Group', 'jpeg': 'Joint Photographic Experts Group', 'tif': 'Tagged Image File Format', 'tiff': 'Tagged Image File Format'}
fig = plt.figure() ax = plt.axes() # 위에 두 코드는 사용하지 않아도 작동됨 # 단, 저장할 때는 필요 plt.show()
Out[-]
notion imagenotion image
x = np.linspace(0, 10, 100) y = x ** 2 y_ = x ** 3 plt.plot(x, y, '--') plt.plot(x, y_) # 여러 개의 그래프를 동시에 출력하려면 plot을 하나 더 사용하면 됨 plt.show()
Out[-]
notion imagenotion image

선 색상과 스타일

  • plt.plot(x, y, color='red') -> red, green, blue 등 색상 이름
  • plt.plot(x, y, color='r') -> r, g, b, y, m(자홍), k(검정) 등 색상 이름
  • plt.plot(x, y, color='0.2') -> 회색조(0-1사이 값)
  • plt.plot(x, y, color='#ff0000') -> 16진수 색상 값
  • plt.plot(x, y, linestyle='solid') -> 실선('-')
  • plt.plot(x, y, linestyle='dashed') -> 파선('--')
  • plt.plot(x, y, linestyle='dashdot') -> 1점 쇄선('-.')
  • plt.plot(x, y, linestyle='dotted') -> 점선(':')
  • plt.plot(x, y, '--r') -> 빨간색 파선
 
value = pd.Series([1, 2, 3], [100, 200, 300]) # plt.plot(value, linestyle='dashed', color='blue') # 파선, 파란색 plt.plot(value, '--b')
Out[-]
notion imagenotion image
 
x = np.linspace(0, 10, 100) y = x ** 2 plt.plot(x, y, '--r') plt.show()
Out[-]
notion imagenotion image
 

경계 표현

  • 자동으로 표현
  • plt.xlim, plt.ylim으로 상세 조정 가능
  • plt.axis([x축 최솟값, x축 최댓값, y축 최솟값, y축 최댓값])로 한 번에 조정 가능 - axes와 다름! 비슷한 키워드 주의!
  • plt.axis('keyword') -> tight, equal(균등)
 
x = np.linspace(0, 10, 100) y = x ** 2 plt.plot(x, y, 'r') # plt.xlim(-1, 11) # x축 -1 ~ 11 # plt.ylim(-10, 110) # y축 -10 ~ 110 # plt.axis([-1, 11, -10, 110]) # x축 -1 ~ 11, y축 -10 ~ 110 # plt.axis('tight') # plt.axis('equal') plt.show()
Out[-]
notion imagenotion image
 

label과 legend

label : x축, y축의 값이 무슨 데이터인지 표시해 주는 방법
legend : 좌표축에 범례를 추가함
import numpy as np import matplotlib.pyplot as plt %matplotlib inline x = np.linspace(0, 10, 100) y = x ** 2 plt.plot(x, y, 'r') plt.xlabel('x') plt.ylabel('y') plt.show()
Out[-]
notion imagenotion image
x = np.linspace(0, 10, 100) y = x ** 2 y_ = x ** 3 plt.plot(x, y, 'r', label='line1') plt.plot(x, y_, 'g', label='line2') # plt.xlabel('x') # plt.ylabel('y') plt.legend() plt.show()
Out[-]
notion imagenotion image
 

  • 'best' 0
  • 'upper right' 1
  • 'upper left' 2
  • 'lower left' 3
  • 'lower right' 4
  • 'right' 5
  • 'center left' 6
  • 'center right' 7
  • 'lower center' 8
  • 'upper center' 9
  • 'center' 10
  • loc : 레전드의 위치
x = np.linspace(0, 10, 100) y = x ** 2 y_ = x ** 3 plt.plot(x, y, 'r', label='line1') plt.plot(x, y_, 'g', label='line2') # plt.xlabel('x') # plt.ylabel('y') plt.legend(loc=2) ''' 2 9 1 6 5,7 3 8 4 ''' plt.show()
Out[-]
notion imagenotion image
  • bbox : figure 밖에 legend위치하게 해주는 것
  • fancybox : 모서리를 깎아주는 것
x = np.linspace(0, 10, 100) y = x ** 2 y_ = x ** 3 plt.plot(x, y, 'r', label='line1') plt.plot(x, y_, 'g', label='line2') plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=2, fancybox=True, shadow=True) ''' 2 9 1 6 5,7 3 8 4 ''' plt.show()
Out[-]
notion imagenotion image

바운딩 박스 밖에서 위치 다루기

  • 왼쪽 하단이 0, 0
  • 오른쪽 하단이 1, 0
  • 왼쪽 상단이 0, 1
  • 오른쪽 상단이 1, 1
notion imagenotion image
 

Scatter(산점도)

  • 변수들의 관계, 밀집 위치를 점으로 표현하는 방법
  • 양의 상관관계, 음의 상관관계
  • 군집 : 점들의 모임
plt.scatter(20, 20, s=100, c='r', alpha=0.5) # (20,20), size가 100, 빨간색, 투명도 0.5인 점 생성 plt.show()
Out[-]
notion imagenotion image
plt.scatter([10, 20], [10, 20], s=100, c=['r', 'g'], alpha=0.5) plt.show()
Out[-]
notion imagenotion image
x = np.linspace(0, 10, 20) y = x ** 2 plt.scatter(x, y, s=100, c='b', alpha=0.5) plt.show()
Out[-]
notion imagenotion image
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 제곱이 안되므로 np를 사용해서 실행해야 함 y = x ** 2 plt.scatter(x, y, s=100, c='b', alpha=0.5) plt.show()
Out[-] --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-30-2c8a900ea56a> in <module> 1 x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ----> 2 y = x ** 2 3 4 plt.scatter(x, y, s=100, c='b', alpha=0.5) 5 plt.show() TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
x = np.random.rand(50) y = np.random.rand(50) colors = np.random.rand(50) size = 1000 * np.random.rand(50) plt.scatter(x, y, s=size, c=colors, alpha=0.5) plt.show()
Out[-]
notion imagenotion image
 

히스토그램

  • 히스토그램(histogram)은 표로 되어 있는 도수 분포를 정보 그림으로 나타낸 것. 더 간단하게 말하면, 도수분포표를 그래프로 나타낸 것
  • 막대그래프는 계급 즉 가로를 생각하지 않고 세로의 높이로만 나타냄(출처 : wikipedia)
np.random.rand(4, 2) # 0부터 1사이, 균일 분포, Matrix 생성 np.random.randint(10) # 0부터 9사이, 숫자 1개 생성 np.random.randint(10, 20, size=10) np.random.randint(10, 20, size=(3, 5)) np.random.randn(4, 2) # 가우시안 표준 정규분포, Matrix 생성 np.unique([1, 1, 1, 2, 2, 3]) # 중복된 값 제거 np.random.choice(10, 5, replace=False) # 3개만 선택, replace는 중복허락함
arr = [np.random.randint(10) for i in range(10)] arr
Out[-] [3, 1, 2, 5, 5, 5, 1, 2, 6, 8]
# plt.grid(True) plt.hist(arr) plt.show()
Out[-]
notion imagenotion image
arr = [np.random.randint(1, 7) for i in range(10)] plt.hist(arr) plt.show()
Out[-]
notion imagenotion image
arr = [np.random.randint(1, 7) for i in range(1000)] plt.hist(arr, bins=6, alpha=0.5) plt.show()
Out[-]
notion imagenotion image

Basic Attributes

  • alpha : 투명도
  • logy : Y축 Log scaling
  • kind : line, bar, barh, kde
  • subplots : 여러개의 plot 그리기
  • legend : subplot의 범례 지정
  • xlim, ylim : X축과 Y축의 경계(axis로 한번에 그릴 수 있음)
  • grid : 그리드 표현(True, False)
  • title : 그래프의 제목 지정
  • linewidth : 라인 넓이
  • color : 색
  • linestyle : 실선, 점선, 1점 쇄선 등
  • marker : 마커 지정
  • markerfacecolor : 마커 색
  • markersize : 마커 크기
 
x = np.linspace(0, 10, 10) y = x ** 2 plt.plot(x, y, 'k:', linewidth=3, marker='^', markersize=10, markerfacecolor='green') plt.show() x
Out[-]
notion imagenotion image
array([ 0. , 1.11111111, 2.22222222, 3.33333333, 4.44444444, 5.55555556, 6.66666667, 7.77777778, 8.88888889, 10. ])
for m in [ '+', ',', '.', '1', '2', '3', '4', 'o', 'x', '+', 'v', '^', '<', '>', 's', 'd', 'p']: plt.plot(np.random.randint(20), np.random.randint(20), m, markersize=10, label=f'marker={m}') plt.legend(loc='upper center', bbox_to_anchor=(1.2, 1.05), fancybox=True, shadow=True) plt.show()
Out[-]
 
notion imagenotion image
 

Pie Chart

labels = ['one', 'two', 'three', 'four'] sizes = [10, 20, 30, 40] plt.pie(sizes, labels=labels) plt.show() # 반시계방향으로 출력
Out[-]
notion imagenotion image
labels = ['one', 'two', 'three', 'four'] sizes = [10, 20, 30, 40] plt.pie(sizes, labels=labels, shadow=True, startangle=90) # startangle 90: 12시 방향에서 시작 plt.show()
Out[-]
notion imagenotion image
labels = ['one', 'two', 'three', 'four'] sizes = [10, 20, 60, 90] plt.pie(sizes, labels=labels, shadow=True, startangle=90) plt.show()
Out[-]
notion imagenotion image
labels = ['one', 'two', 'three', 'four'] sizes = [10, 20, 60, 90] explode = (0, 0.1, 0.2, 0) # 어떤 특정값을 pie chart에서 띄어서 보여주고 싶을 때 사용 plt.pie(sizes, labels=labels, shadow=True, startangle=90, explode=explode) plt.show()
Out[-]
notion imagenotion image
labels = ['one', 'two', 'three', 'four'] sizes = [10, 20, 60, 90] explode = (0, 0.1, 0.2, 0) plt.pie(sizes, labels=labels, shadow=True, startangle=90, explode=explode, autopct='%1.2f%%') # atuopct : % 출력 plt.show()
Out[-]
notion imagenotion image

Bar Chart

plt.bar(['one', 'two', 'three'], [10, 20, 30]) plt.show()
Out[-]
notion imagenotion image
plt.bar(['one', 'two', 'three'], [10, 20, 30]) plt.title('hello world', fontsize=15) plt.xlabel('Items', fontsize=15) plt.ylabel('Sales', fontsize=15) plt.show()
Out[-]
notion imagenotion image
# barh : 가로 막대 그래프 그리기 plt.barh(['one', 'two', 'three'], [10, 20, 30]) plt.title('hello world', fontsize=15) plt.xlabel('Items', fontsize=15) plt.ylabel('Sales', fontsize=15) plt.show()
Out[-]
notion imagenotion image
plt.bar(['one', 'two', 'three'], [10, 20, 30], color='g') plt.bar(['one', 'two', 'three'], [20, 40, 60], color='b', alpha=0.5, bottom=[10, 20, 30]) plt.title('hello world', fontsize=15) plt.xlabel('Items', fontsize=15) plt.ylabel('Sales', fontsize=15) plt.legend(['OneBarChart', 'TwoBarChart']) plt.show()
Out[-]
notion imagenotion image

subplot

x = np.linspace(0, 10, 20) y = x ** 2
plt.subplot(121) # row 1 col 2 중 첫번째에 출력 plt.plot(x, y, 'r') plt.subplot(122) # row 1 col 2 중 두번째에 출력 plt.plot(x, y, 'g') plt.show()
Out[-]
notion imagenotion image
plt.subplot(131) plt.plot(x, y, 'r') plt.subplot(132) plt.plot(x, y, 'g') plt.subplot(133) plt.plot(x, y, 'b') plt.show()
Out[-]
notion imagenotion image
plt.subplot(231) plt.plot(x, y, 'r') plt.subplot(232) plt.plot(x, y, 'g') plt.subplot(233) plt.plot(x, y, 'b') plt.subplot(234) plt.plot(x, y, 'r') plt.subplot(235) plt.plot(x, y, 'g') plt.subplot(236) plt.plot(x, y, 'b') plt.show()
Out[-]
notion imagenotion image
plt.subplot(1,2,1) # , 안쓴거랑 같은 효과 plt.plot(x, y, 'r') plt.subplot(1,2,2) plt.plot(x, y, 'g') plt.show()
Out[-]
notion imagenotion image
grid = plt.GridSpec(2, 3) # grid를 이용하여 전체 figure을 나눔 plt.subplot(grid[0, 0]) # gird[행, 열] plt.plot(x, y, 'r') plt.subplot(grid[0, 1:]) plt.plot(x, y, 'g') plt.subplot(grid[1, :2]) plt.plot(x, y, 'r') plt.subplot(grid[1, 2]) plt.plot(x, y, 'g') plt.show()
Out[-]
notion imagenotion image
plt.figure(figsize=(10, 3)) # size 조절 plt.plot(x, y, 'b') plt.show()
Out[-]
notion imagenotion image
plt.figure(figsize=(10, 3)) plt.plot(x, y, 'b') plt.text(1, 70, 'hello world') # (1, 70) 지점에 글씨 출력 plt.show()
Out[-]
notion imagenotion image
plt.figure(figsize=(10, 3)) plt.plot(x, y, 'b') plt.text(1, 70, f'$\mu=100, \sigma=15$') plt.show()
Out[-]
notion imagenotion image
plt.figure(figsize=(10, 3)) plt.plot(x, y, 'b') plt.annotate('Max Value', xy=(10, 100), xytext=(1, 70), arrowprops=dict(facecolor='black', shrink=0.05)) plt.show()
Out[-]
notion imagenotion image
 

기타 시각화 그래프(공식 홈페이지 튜토리얼 소개)

# 오차 막대 : 표준편차의 범위를 나타냄 x = np.linspace(0, 10, 20) y = x ** 2 dy = 10 plt.errorbar(x, y, yerr=dy, fmt='.k', ecolor='lightgray') plt.show()
Out[-]
notion imagenotion image
# labels 있는 그룹화된 bar 차트 import matplotlib import matplotlib.pyplot as plt import numpy as np labels = ['G1', 'G2', 'G3', 'G4', 'G5'] men_means = [20, 34, 30, 35, 27] women_means = [25, 32, 34, 20, 25] x = np.arange(len(labels)) # label 위치 width = 0.35 # bar의 넓이 fig, ax = plt.subplots() rects1 = ax.bar(x - width/2, men_means, width, label='Men') rects2 = ax.bar(x + width/2, women_means, width, label='Women') # label, 제목 및 사용자 정의 x축 눈금 label 등에 대학 텍스트 추가 ax.set_ylabel('Scores') ax.set_title('Scores by group and gender') ax.set_xticks(x) ax.set_xticklabels(labels) ax.legend() def autolabel(rects): # 그래프에 수치를 나타내주는 코드 """Attach a text label above each bar in *rects*, displaying its height.""" for rect in rects: height = rect.get_height() ax.annotate('{}'.format(height), xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0, 3), # 텍스트를 3칸 위로 띄우기 textcoords="offset points", ha='center', va='bottom') autolabel(rects1) autolabel(rects2) fig.tight_layout() plt.show()
Out[-]
notion imagenotion image
# Filled polygon import numpy as np import matplotlib.pyplot as plt def koch_snowflake(order, scale=10): """ Koch 곡선의 점 좌표 x, y의 두개 list를 return Arguments --------- order : int The recursion depth. scale : float Koch 곡선의 범위(기본 삼각형의 가장자리 길) """ def _koch_snowflake_complex(order): if order == 0: # 초기 삼각형 angles = np.array([0, 120, 240]) + 90 return scale / np.sqrt(3) * np.exp(np.deg2rad(angles) * 1j) else: ZR = 0.5 - 0.5j * np.sqrt(3) / 3 p1 = _koch_snowflake_complex(order - 1) # 시작점 p2 = np.roll(p1, shift=-1) # 마침점 dp = p2 - p1 # 연결 벡터 new_points = np.empty(len(p1) * 4, dtype=np.complex128) new_points[::4] = p1 new_points[1::4] = p1 + dp / 3 new_points[2::4] = p1 + dp * ZR new_points[3::4] = p1 + dp / 3 * 2 return new_points points = _koch_snowflake_complex(order) x, y = points.real, points.imag return x, y x, y = koch_snowflake(order=5) plt.figure(figsize=(8, 8)) plt.axis('equal') plt.fill(x, y) plt.show()
Out[-]
notion imagenotion image
# 히트맵(heatmaps) 만들기 # 상관도 분석할 때 가장 많이 쓰임 import numpy as np import matplotlib import matplotlib.pyplot as plt # sphinx_gallery_thumbnail_number = 2 vegetables = ["cucumber", "tomato", "lettuce", "asparagus", "potato", "wheat", "barley"] farmers = ["Farmer Joe", "Upland Bros.", "Smith Gardening", "Agrifun", "Organiculture", "BioGoods Ltd.", "Cornylee Corp."] harvest = np.array([[0.8, 2.4, 2.5, 3.9, 0.0, 4.0, 0.0], [2.4, 0.0, 4.0, 1.0, 2.7, 0.0, 0.0], [1.1, 2.4, 0.8, 4.3, 1.9, 4.4, 0.0], [0.6, 0.0, 0.3, 0.0, 3.1, 0.0, 0.0], [0.7, 1.7, 0.6, 2.6, 2.2, 6.2, 0.0], [1.3, 1.2, 0.0, 0.0, 0.0, 3.2, 5.1], [0.1, 2.0, 0.0, 1.4, 0.0, 1.9, 6.3]]) fig, ax = plt.subplots() im = ax.imshow(harvest) # 축에 표시되는 값을 수치로 넣기 (문자열을 정수 리스트로) ax.set_xticks(np.arange(len(farmers))) ax.set_yticks(np.arange(len(vegetables))) # 다시 이름으로 넣어주기 ax.set_xticklabels(farmers) ax.set_yticklabels(vegetables) # tick 라벨 각도를 돌리고 조정하기 plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor") # 수치 표시하기 for i in range(len(vegetables)): for j in range(len(farmers)): text = ax.text(j, i, harvest[i, j], ha="center", va="center", color="w") ax.set_title("Harvest of local farmers (in tons/year)") fig.tight_layout() plt.show()
Out[-]
notion imagenotion image
# 라인, 날짜 그리고 텍스트가 있는 타임라인 생성 import matplotlib.pyplot as plt import numpy as np import matplotlib.dates as mdates from datetime import datetime try: # Matplotlib 목록과 해당 날짜 가져오기 # 출처 : https://api.github.com/repos/matplotlib/matplotlib/releases import urllib.request import json url = 'https://api.github.com/repos/matplotlib/matplotlib/releases' url += '?per_page=100' data = json.loads(urllib.request.urlopen(url, timeout=.4).read().decode()) dates = [] names = [] for item in data: if 'rc' not in item['tag_name'] and 'b' not in item['tag_name']: dates.append(item['published_at'].split("T")[0]) names.append(item['tag_name']) # Convert date strings (e.g. 2014-10-18) to datetime dates = [datetime.strptime(d, "%Y-%m-%d") for d in dates] except Exception: # 위에 것이 실패할 경우, 예를 들어 인터넷 연결이 되지 않은 경우 # 대비책으로 다음 리스트를 사용해라 names = ['v2.2.4', 'v3.0.3', 'v3.0.2', 'v3.0.1', 'v3.0.0', 'v2.2.3', 'v2.2.2', 'v2.2.1', 'v2.2.0', 'v2.1.2', 'v2.1.1', 'v2.1.0', 'v2.0.2', 'v2.0.1', 'v2.0.0', 'v1.5.3', 'v1.5.2', 'v1.5.1', 'v1.5.0', 'v1.4.3', 'v1.4.2', 'v1.4.1', 'v1.4.0'] dates = ['2019-02-26', '2019-02-26', '2018-11-10', '2018-11-10', '2018-09-18', '2018-08-10', '2018-03-17', '2018-03-16', '2018-03-06', '2018-01-18', '2017-12-10', '2017-10-07', '2017-05-10', '2017-05-02', '2017-01-17', '2016-09-09', '2016-07-03', '2016-01-10', '2015-10-29', '2015-02-16', '2014-10-26', '2014-10-18', '2014-08-26'] # 날짜 문자열(ex. 2014-10-18)을 datetime으로 변환 dates = [datetime.strptime(d, "%Y-%m-%d") for d in dates] # 최적의 levels 선택 levels = np.tile([-5, 5, -3, 3, -1, 1], int(np.ceil(len(dates)/6)))[:len(dates)] # figure, plot, 날짜에 따라서 줄기 그림 그리기 fig, ax = plt.subplots(figsize=(8.8, 4), constrained_layout=True) ax.set(title="Matplotlib release dates") markerline, stemline, baseline = ax.stem(dates, levels, linefmt="C3-", basefmt="k-", use_line_collection=True) plt.setp(markerline, mec="k", mfc="w", zorder=3) # y 데이터를 0으로 교체하여 마커를 기준선으로 이동 markerline.set_ydata(np.zeros(len(dates))) # annotate lines vert = np.array(['top', 'bottom'])[(levels > 0).astype(int)] for d, l, r, va in zip(dates, levels, names, vert): ax.annotate(r, xy=(d, l), xytext=(-3, np.sign(l)*3), textcoords="offset points", va=va, ha="right") # 4개월 간격으로 x축 형식 지정 ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=4)) ax.get_xaxis().set_major_formatter(mdates.DateFormatter("%b %Y")) plt.setp(ax.get_xticklabels(), rotation=30, ha="right") # y축과 spine(좌표의 테두리를 굵게 표시하는 방법)를 제 ax.get_yaxis().set_visible(False) for spine in ["left", "top", "right"]: ax.spines[spine].set_visible(False) ax.margins(y=0.1) plt.show()
Out[-]
notion imagenotion image
# plot 나누기 import matplotlib.pyplot as plt import numpy as np import matplotlib.gridspec as gridspec fig = plt.figure(tight_layout=True) gs = gridspec.GridSpec(2, 2) ax = fig.add_subplot(gs[0, :]) ax.plot(np.arange(0, 1e6, 1000)) ax.set_ylabel('YLabel0') ax.set_xlabel('XLabel0') for i in range(2): ax = fig.add_subplot(gs[1, i]) ax.plot(np.arange(1., 0., -0.1) * 2000., np.arange(1., 0., -0.1)) ax.set_ylabel('YLabel1 %d' % i) ax.set_xlabel('XLabel1 %d' % i) if i == 0: for tick in ax.get_xticklabels(): tick.set_rotation(55) fig.align_labels() # fig.align_xlabels(); fig.align_ylabels() 와 같이 하기 plt.show()
Out[-]
notion imagenotion image
# 깨진 축 import matplotlib.pyplot as plt import numpy as np # [0, 0.2)사이에 np.random.rand(30)*.2 사용하여 만든 30개 데이터 pts = np.array([ 0.015, 0.166, 0.133, 0.159, 0.041, 0.024, 0.195, 0.039, 0.161, 0.018, 0.143, 0.056, 0.125, 0.096, 0.094, 0.051, 0.043, 0.021, 0.138, 0.075, 0.109, 0.195, 0.050, 0.074, 0.079, 0.155, 0.020, 0.010, 0.061, 0.008]) pts[[3, 14]] += .8 # 우리가 단순히 pts를 구성한다면, 우리는 이상치 때문에 대부분의 세부사항들을 잃게 됨. # 따라서 Y 축을 두 부분으로 'break'하거나 'cut-out'함 # 이상치에는 상단(ax)을, 대다수의 데이터에는 하단(ax2)을 사용 f, (ax, ax2) = plt.subplots(2, 1, sharex=True) # 두 축을 동일한 데이터로 plot ax.plot(pts) ax2.plot(pts) ax.set_ylim(.78, 1.) # 이상치만 ax2.set_ylim(0, .22) # 대부분의 데이터 # ax와 ax2 사이에 spine 숨기기 ax.spines['bottom'].set_visible(False) ax2.spines['top'].set_visible(False) ax.xaxis.tick_top() ax.tick_params(labeltop=False) # 맨 위에 눈금 label 표시 안 함 ax2.xaxis.tick_bottom() d = .015 # 축 좌표에서 사선을 만드는 방법 kwargs = dict(transform=ax.transAxes, color='k', clip_on=False) ax.plot((-d, +d), (-d, +d), **kwargs) # 왼쪽 상단 사선 ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) # 오른쪽 상단 사선 kwargs.update(transform=ax2.transAxes) # 밑의 축으로 전환 ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # 왼쪽 하단 사선 ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # 오른쪽 하단 사선 plt.show()
Out[-]
notion imagenotion image
# Bar of pie import matplotlib.pyplot as plt from matplotlib.patches import ConnectionPatch import numpy as np fig = plt.figure(figsize=(9, 5)) ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) fig.subplots_adjust(wspace=0) # pie chart ratios = [.27, .56, .17] labels = ['Approve', 'Disapprove', 'Undecided'] explode = [0.1, 0, 0] angle = -180 * ratios[0] ax1.pie(ratios, autopct='%1.1f%%', startangle=angle, labels=labels, explode=explode) # bar chart xpos = 0 bottom = 0 ratios = [.33, .54, .07, .06] width = .2 colors = [[.1, .3, .5], [.1, .3, .3], [.1, .3, .7], [.1, .3, .9]] for j in range(len(ratios)): height = ratios[j] ax2.bar(xpos, height, width, bottom=bottom, color=colors[j]) ypos = bottom + ax2.patches[j].get_height() / 2 bottom += height ax2.text(xpos, ypos, "%d%%" % (ax2.patches[j].get_height() * 100), ha='center') ax2.set_title('Age of approvers') ax2.legend(('50-65', 'Over 65', '35-49', 'Under 35')) ax2.axis('off') ax2.set_xlim(- 2.5 * width, 2.5 * width) # 두 plot 사이에 ConnectionPatch 사용해서 선 그리기 theta1, theta2 = ax1.patches[0].theta1, ax1.patches[0].theta2 center, r = ax1.patches[0].center, ax1.patches[0].r bar_height = sum([item.get_height() for item in ax2.patches]) # 상단 연결선 그리기 x = r * np.cos(np.pi / 180 * theta2) + center[0] y = np.sin(np.pi / 180 * theta2) + center[1] con = ConnectionPatch(xyA=(-width / 2, bar_height), coordsA=ax2.transData, xyB=(x, y), coordsB=ax1.transData) con.set_color([0, 0, 0]) con.set_linewidth(4) ax2.add_artist(con) # 하단 연결선 그리기 x = r * np.cos(np.pi / 180 * theta1) + center[0] y = np.sin(np.pi / 180 * theta1) + center[1] con = ConnectionPatch(xyA=(-width / 2, 0), coordsA=ax2.transData, xyB=(x, y), coordsB=ax1.transData) con.set_color([0, 0, 0]) ax2.add_artist(con) con.set_linewidth(4) plt.show()
Out[-]
notion imagenotion image
## Scatter plot on polar axis import numpy as np import matplotlib.pyplot as plt np.random.seed(19680801) # 영역 및 색상 계산 N = 150 r = 2 * np.random.rand(N) theta = 2 * np.pi * np.random.rand(N) area = 200 * r**2 colors = theta fig = plt.figure() ax = fig.add_subplot(111, projection='polar') c = ax.scatter(theta, r, c=colors, s=area, cmap='hsv', alpha=0.75)
Out[-]
notion imagenotion image
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation # 주의!! from mpl_toolkits import mplot3d np.random.seed(19680801) def gen_rand_line(length, dims=2): """ random walk algorithm을 사용하여 선 만들기. Parameters ---------- length : int The number of points of the line. dims : int The number of dimensions of the line. """ line_data = np.empty((dims, length)) line_data[:, 0] = np.random.rand(dims) for index in range(1, length): # 무작위 숫자를 0.1만큼 스케일링하므로 위치에 비해 움직임이 작음 # 0.5로 빼는것은 범위를 [-0.5, 0.5]로 변경하여 선이 뒤로 움직일 수 있게함 step = (np.random.rand(dims) - 0.5) * 0.1 line_data[:, index] = line_data[:, index - 1] + step return line_data def update_lines(num, dataLines, lines): for line, data in zip(lines, dataLines): line.set_data(data[0:2, :num]) line.set_3d_properties(data[2, :num]) return lines # figure에 3D축 붙이기 fig = plt.figure() ax = fig.add_subplot(projection="3d") # 무작위 3D 선 50개 data = [gen_rand_line(25, 3) for index in range(50)] # 50개 선 생성. # 빈 배열을 3D 버전의 plot으로 전달할 수 없음 lines = [ax.plot(dat[0, 0:1], dat[1, 0:1], dat[2, 0:1])[0] for dat in data] # 축 속성 설정 ax.set_xlim3d([0.0, 1.0]) ax.set_xlabel('X') ax.set_ylim3d([0.0, 1.0]) ax.set_ylabel('Y') ax.set_zlim3d([0.0, 1.0]) ax.set_zlabel('Z') ax.set_title('3D Test') # 애니메이션 개체 만들기 line_ani = animation.FuncAnimation( fig, update_lines, 25, fargs=(data, lines), interval=50) plt.show()
Out[-]
notion imagenotion image
import numpy as np import matplotlib.pyplot as plt from matplotlib import cm from mpl_toolkits.mplot3d import Axes3D X = np.arange(-5, 5, 0.25) Y = np.arange(-5, 5, 0.25) X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) fig = plt.figure() ax = Axes3D(fig) ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.viridis) plt.show()
Out[-]
notion imagenotion image
from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt from matplotlib import cm fig = plt.figure() ax = fig.gca(projection='3d') X, Y, Z = axes3d.get_test_data(0.05) # Plot the 3D surface ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3) cset = ax.contourf(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm) cset = ax.contourf(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm) cset = ax.contourf(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm) ax.set_xlim(-40, 40) ax.set_ylim(-40, 40) ax.set_zlim(-100, 100) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') plt.show()
Out[-]
notion imagenotion image
import numpy as np import matplotlib.pyplot as plt t = np.arange(0.01, 20.0, 0.01) # figure 생성 fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2) # log y axis ax1.semilogy(t, np.exp(-t / 5.0)) ax1.set(title='semilogy') ax1.grid() # log x axis ax2.semilogx(t, np.sin(2 * np.pi * t)) ax2.set(title='semilogx') ax2.grid() # log x and y axis ax3.loglog(t, 20 * np.exp(-t / 10.0), basex=2) ax3.set(title='loglog base 2 on x') ax3.grid() x = 10.0**np.linspace(0.0, 2.0, 20) y = x**2.0 ax4.set_xscale("log", nonposx='clip') ax4.set_yscale("log", nonposy='clip') ax4.set(title='Errorbars go negative') ax4.errorbar(x, y, xerr=0.1 * x, yerr=5.0 + 0.75 * y) ax4.set_ylim(bottom=0.1) fig.tight_layout() plt.show()
Out[-]
notion imagenotion image