HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🚣
제주 하간디 - 데이터분석 1부-2권
/
🌔
4일차 데이터 시각화
🌔

4일차 데이터 시각화

notion image

목차

목차EDA탐색적 자료 분석EDA 목적Graph VisualizationMatplotlib를 이용한 시각화선 색상과 스타일경계 표현label과 legend바운딩 박스 밖에서 위치 다루기Scatter(산점도)히스토그램Basic AttributesPie ChartBar Chartsubplot기타 시각화 그래프(공식 홈페이지 튜토리얼 소개)
 

EDA

탐색적 자료 분석

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

EDA 목적

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

Graph Visualization

Matplotlib를 이용한 시각화

  • plotly와 같은 최신 시각화 패키지에 비하면 투박하다고 생각될 수 있으나, 거의 모든 운영체제와 출력형식을 지원하고 있어 아직도 유용한 패키지 중 하나
  • 2003년 0.1 출시, 17년이된 패키지
  • https://github.com/matplotlib/matplotlib
  • https://matplotlib.org/
 
  • % 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 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 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 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 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 image
 
x = np.linspace(0, 10, 100) y = x ** 2 plt.plot(x, y, '--r') plt.show()
Out[-]
notion 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 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 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 image
 

https://matplotlib.org/tutorials/intermediate/legend_guide.html
  • '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 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 image

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

  • 왼쪽 하단이 0, 0
  • 오른쪽 하단이 1, 0
  • 왼쪽 상단이 0, 1
  • 오른쪽 상단이 1, 1
notion image
출처 : https://stackoverflow.com/questions/4700614/how-to-put-the-legend-out-of-the-plot
 

Scatter(산점도)

  • 변수들의 관계, 밀집 위치를 점으로 표현하는 방법
  • 양의 상관관계, 음의 상관관계
  • 군집 : 점들의 모임
plt.scatter(20, 20, s=100, c='r', alpha=0.5) # (20,20), size가 100, 빨간색, 투명도 0.5인 점 생성 plt.show()
Out[-]
notion image
plt.scatter([10, 20], [10, 20], s=100, c=['r', 'g'], alpha=0.5) plt.show()
Out[-]
notion 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 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 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 image
arr = [np.random.randint(1, 7) for i in range(10)] plt.hist(arr) plt.show()
Out[-]
notion image
arr = [np.random.randint(1, 7) for i in range(1000)] plt.hist(arr, bins=6, alpha=0.5) plt.show()
Out[-]
notion 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 : 마커 크기
  • 그 외 Attribute : https://matplotlib.org/3.1.1/tutorials/introductory/pyplot.html
 
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 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 image
 

Pie Chart

labels = ['one', 'two', 'three', 'four'] sizes = [10, 20, 30, 40] plt.pie(sizes, labels=labels) plt.show() # 반시계방향으로 출력
Out[-]
notion 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 image
labels = ['one', 'two', 'three', 'four'] sizes = [10, 20, 60, 90] plt.pie(sizes, labels=labels, shadow=True, startangle=90) plt.show()
Out[-]
notion 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 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 image

Bar Chart

plt.bar(['one', 'two', 'three'], [10, 20, 30]) plt.show()
Out[-]
notion 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 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 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 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 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 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 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 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 image
plt.figure(figsize=(10, 3)) # size 조절 plt.plot(x, y, 'b') plt.show()
Out[-]
notion image
plt.figure(figsize=(10, 3)) plt.plot(x, y, 'b') plt.text(1, 70, 'hello world') # (1, 70) 지점에 글씨 출력 plt.show()
Out[-]
notion image
plt.figure(figsize=(10, 3)) plt.plot(x, y, 'b') plt.text(1, 70, f'$\mu=100, \sigma=15$') plt.show()
Out[-]
notion 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 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 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 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 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 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 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 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 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 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 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 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 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 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 image