728x90
728x170
matplotlib API
- matplotlib API 에는 matplotlib.pyplot 을 적용하는 pylot API가 있다.
- 또한 pyplot.subplots 로 하나의 Figure 및 하나 이상의 Axes 객체를 이용해 작업하는 객체 지향 API가 있다.
- matplotlib API Reference : https://matplotlib.org/stable/api/
그래프 그리기
- 그래프는 선, 그림, 텍스트 등의 요소들로 구성되어 있다.
- 이러한 요소들을 figure에 있는 axes에 추가하면 그래프를 그릴 수 있다.
- 대표적으로 plot() 함수를 이용해 그래프를 그릴 수 있으며, plot() 함수는 임의의 수인 인수들을 융통성 있게 취할 수 있다.
- 다음 예제에서 plot() 함수는 x축에 [1, 2, 3, 4] 값을, y축에 [1, 4, 9, 16] 값을 갖는 그래프를 그린다.
plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
plt.show()
그래프 스타일 꾸미기
- 다음 예제의 plot() 함수에는 x, y 쌍의 인수에 색상과 선 타입을 지정하는 옵션인 세 번째 인수가 있다.
- 세 번째 인수의 r은 색상, o는 선 타입을 지정한다.
- 기본 타입은 파란 실선인 b- 이다.
- axis() 함수로 x와 y축 범위를 정한다.
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], 'ro')
plt.axis([0, 6, 0, 20]) # x축 범위 : 0~6, y축 범위 : 0~20
plt.show()
- axis() 함수의 매개 변수 옵션에 다음과 같은 문자열 값을 사용해 선을 꾸밀 수 있다.
값 | 기능 |
'on' | - 축 선과 라벨들을 나타낸다. - True 와 같다. |
'off' | - 축 선과 라벨들을 숨긴다. - False 와 같다. |
'equal' | 축 범위를 변경함으로써 크기를 동등하게 설정한다. |
'scaled' | 그래프 박스의 차원을 변경함으로써 크기를 조정한다. |
'tight' | 모든 데이터를 보여줄 수 있도록 범위를 크게 설정한다. |
'auto' | - 자동으로 크기를 조정한다. - 플롯 박스를 데이터로 채운다. |
'image' | 데이터 범위와 동등한 축 범위로 'scaled' |
'square' | 사각형, 'scaled'와 비슷하나 초기에는 xmas-xmin=ymax-ymin 을 강제한다. |
- axis() 함수는 리스트 [xmin, xmax, ymin, ymax] 를 인수로 취한다.
- 또한 axis() 함수에 눈에 보이는 axes 영역인 뷰포트를 설정해야 한다.
- matplotlib 에서 리스트로 작업하는 데 제한을 받을 경우 수치를 처리할 때 문제가 발생하므로 일반적으로 넘파이 배열을 사용한다.
- 모든 시퀀스는 내부에서 넘파이 배열로 변환된다.
- 다음은 배열을 입력하고 하나의 명령어로 여러 선 스타일을 설정하면서 몇 개의 선을 그리는 예제이다.
- r-- 은 빨간 점선, bs는 파란 사각형 마커인 선, g^ 는 초록색 삼각형 마커인 선을 그린다.
t = np.arange(0, 5., 0.2)
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()
더보기
- plot() 함수에 x, y 및 fmt를 3번씩 차례로 전달해 3개의 선을 그린다.
- matplotlib은 data 키워드 인수를 가지는 객체를 제공한다.
- 따라서 변수가 문자열로 이루어진 그래프를 생성할 수 있고, 이를 figure로 표시할 수 있다.
- 다음 예제는 scatter() 함수의 data 인수로 입력할 dat를 생성하고, dat의 요소인 c의 절댓값에 100을 곱한 후 그 값을 다시 c 요소에 할당한다.
- 이때 dat은 딕셔너리형이다.
>>> dat = {'a': np.arange(10), 'b': np.random.randint(0, 50, 10), 'c': np.random.randn(10)}
>>> dat['c'] = np.abs(dat['c'])*100
>>> dat
{'a': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
'b': array([39, 49, 43, 32, 15, 2, 23, 32, 36, 28]),
'c': array([116.61531656, 205.03892221, 16.74288845, 98.96938681,
210.5605442 , 30.12249541, 62.53530478, 94.63565118,
106.88251258, 4.70903256])}
- 산점도를 그리는 scatter() 함수는 data 키워드를 인수로 취할 수 있다.
- data 인수를 입력하면 x, y, s, color, c, linewidths, edgecolors 인수들은 data[] 로 대체된다.
plt.scatter('a', 'b', c='b', s='c', data=dat)
plt.xlabel('axis x')
plt.ylabel('axis y')
plt.show()
더보기
- 앞 결과 그래프에서 작은 원 10개를 볼 수 있는데, 이 원들은 키 a와 b의 배열 요솟값 10개 쌍을 좌표로 나타낸 것이다.
- 키워드 c='b' 값에 따라 색상이, 키워드 s='c' 값에 따라 마커 크기가 결정되었다.
범주형 변수로 서브 플롯 생성
- matplotlib 은 범주형 변수를 직접 그래프로 전달할 수 있다.
- 다음은 변수 names와 values를 함수로 전달해 여러 그래프를 출력하는 예제이다.
names = ['group_a', 'group_b', 'group_c']
values = [1, 10, 100]
- 너비 9인치, 높이 3인치인 새로운 figure를 생성한다.
>>> plt.figure(figsize=(9, 3))
<Figure size 900x300 with 0 Axes>
- 많은 figure를 생성하는 경우 pyplot.close() 함수로 사용하지 않는 figure를 닫는다.
- pyplot.close() 함수를 이용하면 pyplot 이 메모리를 비울 수 있다.
- pyplot.close() 로 메모리를 비우면 연산 속도가 빨라진다.
- 서브 플롯을 생성하는 방법은 2가지가 있다.
- subplot() 함수를 이용하는 방법
- add_subplot() 함수를 이용하는 방법
- 다음은 1행 3열로 이루어진 서브 플롯을 생성하는 예제이다.
- 먼저 subplot() 함수를 이용해 첫 번째 열의 Subplot 객체와 막대 그래프를 생성한다.
- plt.subplot(131) 을 실행한 결과와 plt.figure(figsize=(9, 3)).add_subplot(131) 을 실행한 결과는 동일하다.
>>> plt.subplot(131) # plt.figure(figsize=(9, 3)).add_subplot(131)
<AxesSubplot:>
>>> plt.bar(names, values)
<BarContainer object of 3 artists>
- 다음으로 1행 3열로 이루어진 서브 플롯들 중, 두 번째 열의 Subplot 객체를 생성하고 산점도를 그린다.
- 세 번째 열로 plot() 함수의 fmt 기본값이 'b-'인 Subplot 객체를 생성하고, 제목이 중앙에 위치한 그래프를 나타낸다.
>>> plt.subplot(132)
<AxesSubplot:>
>>> plt.scatter(names, values)
<matplotlib.collections.PathCollection object at 0x00000164234238B0>
>>> plt.subplot(133)
<AxesSubplot:>
>>> plt.plot(names, values)
[<matplotlib.lines.Line2D object at 0x00000164234815A0>]
>>> plt.suptitle('Categorical Plotting')
Text(0.5, 0.98, 'Categorical Plotting')
>>> plt.show()
Figure 객체로 서브 플롯 생성
- subplots() 함수로 서브 플롯 4개를 생성할 수 있다.
- 다음 예제에서 fig 와 ax 로 2개 변수를 지정하는 결과 그래프와, sp 1개 변수만 지정하는 결과 그래프는 동일하다.
- fig 로 4개의 서브 플롯을 그리며, ax는 4개의 서브 플롯을 요소로 가지는 ndarray 이다.
fig, ax = plt.subplots(2, 2)
plt.show()
sp = plt.subplots(2, 2)
plt.show()
- fig, ax 그리고 sp 를 각각 실행하여 확인해본다.
- 하나의 변수로 처리된 sp는 fig 객체와 ax 객체를 튜플형으로 포함하고 있음을 확인할 수 있다.
- fig는 4개의 Axes 로 구성된 Figure 객체이고, ax는 4개의 AxesSubplot 객체이다.
fig
>>> ax
array([[<AxesSubplot:>, <AxesSubplot:>],
[<AxesSubplot:>, <AxesSubplot:>]], dtype=object)
>>> sp
(<Figure size 432x288 with 4 Axes>,
array([[<AxesSubplot:>, <AxesSubplot:>],
[<AxesSubplot:>, <AxesSubplot:>]], dtype=object))
- fig, ax 및 sp의 타입을 확인한다.
- sp 는 실행된 fig 와 ax 객체를 포함하는 튜플이다.
>>> type(fig)
matplotlib.figure.Figure
>>> type(ax)
numpy.ndarray
>>> type(sp)
tuple
- 이번에는 add_subplot() 함수를 적용해 Subplot 객체를 생성한다.
- fig1은 Figure 객체이고 Axes 가 없으므로 실행해도 빈 figure가 나타난다.
- 따라서 빈 figure에 2행, 2열인 2x2 배열 형태로 배치되는 Subplot 객체 ax1, ax2, ax3, ax4를 생성한다.
- add_subplot(2, 2, 1) 은 왼쪽 상단의 첫 번째 서브 플롯을 생성하라는 의미이다.
- add_subplot(2, 2, 4) 는 오른쪽 하단의 네 번째 서브 플롯을 생성하라는 의미이다.
>>> fig1 = plt.figure()
<Figure size 432x288 with 0 Axes>
>>> fig1
<Figure size 432x288 with 0 Axes>
>>> ax1 = fig1.add_subplot(2, 2, 1)
>>> ax2 = fig1.add_subplot(2, 2, 2)
>>> ax3 = fig1.add_subplot(2, 2, 3)
>>> ax4 = fig1.add_subplot(2, 2, 4)
>>> plt.show()
라벨, 범례, 주석 추가
- 라벨, 범례, 주석은 그래프를 해석하고 이해할 수 있는 정보를 나타내는 matplotlib의 유용한 기능이다.
- 라벨은 데이터의 이름이나 특징을 알 수 있게 한다.
- 범례는 그래프 안에서 간략한 표기로 데이터 그룹 간 차이를 나타내는 등 그래프를 이해할 수 있게 한다.
- 주석은 데이터를 이해할 수 있도록 돕는다.
add_subplot()과 add_axes() 함수로 그래프를 그리고 라벨 붙이기
- add_subplot() 함수로 출력한 그래프와 add_axes() 함수로 출력한 그래프는 차이가 있다.
- add_subplot() 함수는 전체 figure를 배열의 그리드로 구분한다.
- add_axes() 함수는 figure 좌측 하단을 0으로 하여 메소드 인수로 x, y 기준점을 잡고, 그 기준점에서 너비와 높이를 계산하여 그래프를 그린다.
- 다음 예제의 ax2는 배열 3x4에서 3번째에 자리를 잡는다.
- ax3은 기준점 (0.5, 0.1)에서 너비 0.4, 높이 0.3의 범위로 이루어진 직사각형 axes 그래프를 그린다.
fig = plt.figure()
ax1 = fig.add_subplot(341)
ax2 = fig.add_subplot(343)
ax3 = fig.add_axes([0.5, 0.1, 0.4, 0.3])
ax4 = fig.add_axes([0.8, 0.3, 0.17, 0.5])
ax1.set_title('ax1')
ax2.set_title('ax2')
ax3.set_title('ax3')
ax3.set_xlabel('x-axis')
ax4.set_title('ax4')
ax4.set_ylabel('y-axis')
plt.show()
- 그림에 전체 크기를 기본값으로 설정하지 않고, 사용자가 원하는 크기로 설정하고 싶다면 다음 코드를 추가한다.
plt.rcParams['figure.figsize'] = (3, 3) # 그림의 가로와 세로 비율을 3:3 으로 조정한다.
- 다음 예제에서는 axes 객체를 생성하고 히스토그램을 그리고 x축과 y축에 라벨을 설정한다.
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.set_ylabel('amplitude')
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2 * np.pi * t)
line = ax1.plot(t, s, lw=2)
np.random.seed(77)
ax2 = fig.add_axes([0.2, 0.1, 0.6, 0.3])
n, bin, patch = ax2.hist(np.random.randn(50), 5)
ax2.set_title('histogram')
plt.show()
더보기
- add_subplot(2, 1, 1) 의 첫 번째 숫자 2는 2행, 두 번째 숫자인 1은 1열을 의미하고, 세 번째 숫자 1은 인덱스로 생성된 서브 플롯 2개 중 첫 번째 서브 플롯을 의미한다.
- lw 는 linewidth의 약자로 선 너비를 뜻한다.
- 예제의 np.random.seed(77) 은 시드 값이 77이라는 의미이며, 이후 np.random.randn 메소드에 의해 난수 50개가 발생한다.
- seed(77)이 적용된 상태에서 전체 코드를 재실행해 np.random.randn(50) 으로 난수를 발생시켜도 이전에 발생한 난수와 같은 값을 가진다.
- 코드를 재실행할 때 seed() 메소드를 실행하지 않거나 77이 아닌 다른 시드 값을 갖는 seed() 메소드를 실행하면 전과 다른 50개 난수 값이 생성된다.
- 또한 seed() 메소드를 실행하지 않고, 코드 전체를 재실행하면 실행할 때마다 히스토그램 모양이 바뀐다.
- 이처럼 seed() 메소드를 실행하지 않으면 매번 난수 값이 달라져 디버깅이 어렵다.
- seed(77) 을 실행하는 이유는, 컴퓨터 시스템에서 77인 난수 세트를 재사용해야 할 경우를 대비하는 것이다.
- 인공지능에서는 이러한 세트를 검증 세트(Validation Set)라는 블록으로 사용하기도 한다.
스타일 시트와 rcParams로 matplotlib 실행하기
- matplotlib 의 스타일 시트(Style Sheet)는 산점도, 이미지, 막대 그래프, 패치, 선 그래프 및 히스토그램을 표현할 때 유용하다.
- 레이아웃 스타일을 정의하는 스타일 시트는 웹 프로그래밍 언어인 HTML에 적용하는 CSS(Cascading Style Sheet)처럼 matplotlib 그래프에도 적용할 수 있다.
- matplotlib 으로 그래프를 그릴 때 기본값 설정을 이용할 수 있지만, 사용자가 원하는 정교한 그래프를 표현하기 위해서는 matplotlib 속성을 커스터마이징해 실행한다.
- 일반적으로 matplotlib 을 구성하기 시작할 때 읽히는 matplotlibrc 파일에서 기본값을 설정하고 변경할 수 있는데, 이것을 rc 설정 또는 rc 매개 변수라고 한다.
- 따라서 matplotlib 에서 그림 크기, 선 너비, 색상 및 스타일, axes, axis, 그리드, 텍스트 및 폰트 속성 등을 변경할 수 있다.
- URL이나 경로를 style.use('<path>/<style-name>.mplstyle') 호출에 명시하지 않으면 matplotlib 은 다른 위치에 있는 matplotlibrc 를 찾는다.
- matplotlibrc 의 경로는 다음과 같이 확인한다.
>>> import matplotlib as mpl
>>> mpl.matplotlib_fname()
'C:\\Users\\USERNAME\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python310\\site-packages\\matplotlib\\mpl-data\\matplotlibrc'
- rc 설정은 파이썬 스크립트나 파이썬 셀에서 변경할 수 있다.
- 모든 rc 설정은 matplotlib.rcParams 라 불리는 딕셔너리형 변수에 저장된다.
- rcParams 는 다음과 같이 직접 변경할 수 있다.
>>> mpl.rcParams['lines.linewidth'] = 2
>>> mpl.rcParams['lines.linestyle'] = '--'
- matplotlib 에는 사전에 정의된 많은 스타일이 있다.
- 예를 들어 ggplot 이라는 스타일은 다음과 같이 적용할 수 있으며, 사용 가능한 스타일 리스트도 확인할 수 있다.
- 그러나 이 스타일을 사용하면 인쇄 품질이 저하된다는 단점이 있다.
>>> import matplotlib.pyplot as plt
>>> from matplotlib import rcParams
>>> plt.style.use('ggplot') # ggplot 스타일 사용
>>> print(plt.style.available) # 사용 가능한 스타일 리스트 확인
['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']
matplotlib.pyplot.legend 함수로 범례 설정하기
- legend() 함수는 축에 범례를 설정한다.
- 다음의 3가지 방법으로 legend() 함수를 호출할 수 있다.
legend()
legend(labels)
legend(handles, labels)
호출 방법 ① : legend()
- 함수에 인수를 전달하지 않을 때 legend 요소를 자동으로 설정하는 방법
- legend() 함수를 이용해 범례를 설정하기 전에 아티스트를 이용해 라벨을 결정한다.
- 이 라벨들은 아티스트를 생성할 때 설정되거나 아티스트에서 set_label() 메소드를 호출해 설정할 수 있다.
- 다음 예제에서는 아티스트에 속한 ax.plot() 함수의 인수인 label을 범례로 사용한다.
- 라벨의 범례 크기를 14로 설정하고, 그래프 배경을 점선 그리드로 설정했으며 눈금 라벨의 크기를 14로 설정했다.
fig, ax = plt.subplots()
ax.plot([1, 2, 3], label = 'label in creating artist')
params = {'legend.fontsize' : 14}
plt.rcParams.update(params)
plt.rcParams['axes.grid'] = True
plt.rc('grid', linestyle='--')
plt.grid(True)
plt.rcParams['xtick.labelsize'] = 14
plt.rcParams['ytick.labelsize'] = 14
ax.legend()
plt.show()
- 다음은 set_label() 메소드를 적용해 호출하는 예제이다.
- line, 은 matplotlib.lines.Line2D 타입이다.
- line, 을 line 으로 코딩하면 오류가 발생하며, 이때 line 은 리스트형으로 서로 다른 타입이다.
fig, ax = plt.subplots()
line, = ax.plot([1, 2, 3])
line.set_label('label by calling method')
ax.legend()
plt.show()
호출 방법 ② : legend(labels)
- 현재 그래프 요소에 라벨을 설정하는 방법
- axes 에 이미 존재하는 선에 대한 범례를 만들기 위해 범례에 설정할 문자열을 포함하는 함수를 다음과 같이 호출한다.
fig, ax = plt.subplots()
ax.plot([1, 2, 3])
ax.legend(['calling with strings'])
plt.show()
호출 방법 ③ : legend(handles, labels)
- legend() 함수에 요소들을 명확히 정의하는 방법
- legend((line1, line2, line3), ('label1', 'label2', 'label3')) 과 같은 형식으로 입력한다.
- 다음 코드에서 line 이 리스트형인 점에 주목한다.
line = []
linestyle = ['-', '--', ':', '-.']
x = np.linspace(0, 1, 100)
fig, ax = plt.subplots()
for i in range(4):
line += ax.plot(x, np.sin(2*np.pi*x+i), linestyle[i])
ax.legend(line[:4], ['line1', 'line2', 'line3', 'line4'])
plt.show()
- 다음은 4개의 AxesSubplot 객체 중, 원하는 AxesSubplot 객체에 범례를 설정하는 예제이다.
- 예제에서는 2행 2열로 총 4개의 서브 플롯을 설정한 후, 첫 번째 2개 행에는 선 그래프를, 두 번째 2개 행에는 산점도를 그린다.
x = np.linspace(0, 1, 30)
y1 = np.random.randn(30)
y2 = np.random.randn(30)
fig, ax = plt.subplots(2, 2)
ax[0][0].plot(x, y1)
ax[0][1].plot(x, y2, 'r-')
ax[1][0].scatter(x, y1, s=np.linspace(1, 20, num=30))
ax[1][1].scatter(x, y2, s=np.random.randint(20, size=30))
ax[1][0].legend(['AxesSubplot 3'])
plt.show()
- legend() 함수를 적용할 때, 리스트를 인수로 넘기거나 plot() 함수에 매개 변수 label 을 적용하고 legend() 함수를 호출할 수 있다.
- 먼저 legend() 함수에 리스트를 인수로 전달하는 예를 살펴본다.
x = np.linspace(0, 1, 50)
y = np.random.randn(50)
plt.plot(x, y)
plt.legend(['Line A'])
plt.show()
- 다음은 plot() 함수에 매개 변수로 label 을 적용하고 legend() 함수를 호출하는 예제이다.
x = np.linspace(0, 1, 50)
y1 = np.random.randn(50)
y2 = np.random.randn(50)
plt.plot(x, y1, 'r--', label='Line A')
plt.plot(x, y2, '-', label='Line B')
plt.legend()
plt.show()
범례 위치 정하기
- 키워드 인수 loc 로 범례 위치를 설정할 수 있다.
- legend() 함수에 입력하는 loc 인수는 문자열 또는 실수(float) 쌍의 형태이다.
- rcParams['legend.loc'] 에서 axes 에 rcParms['legend.loc'] = 'best' 로 위치를 설정하면 가장 적절한 위치에 범례가 자리 잡는다.
- figure 의 기본 범례 위치는 upper right 이다.
- 범례에 입력하는 문자열 upper left, upper right, lower left, lower right 는 axes/figure에 해당하는 모퉁이에 범례를 위치시킨다.
- upper center, lower center, center left, center right 는 해당하는 테두리 중심에, center 는 중앙에 범례를 위치시킨다.
- 다음 표처럼 숫자를 이용해 문자열 위치를 설정할 수도 있다.
위치 문자열 | 위치 코드 |
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 |
fig, ax = plt.subplots(2, 1, figsize=(5, 3))
x = np.linspace(0, 10, 12)
y1 = np.random.randint(10, size=12)
y2 = np.random.randint(10, size=12)
y3 = np.arange(12)
y4 = np.random.randint(10, size=12)
lab = ['Line A', 'Line B', 'Line C', 'Line D']
ax[0].plot(x, y1, 'g-')
ax[0].plot(x, y2, '--')
ax[1].plot(x, y3, 'r.')
ax[1].plot(x, y4, 'b:')
ax[0].legend(labels=lab[:2], loc='upper right')
ax[1].legend(labels=lab[2:], loc=2)
plt.show()
주석 달기
- text() 함수를 사용하면 Axes의 임의 위치에 텍스트를 위치시킬 수 있다.
- annotate() 함수는 matplotlib.pyplot 모듈 안에 포함된다.
- annotate() 매소드는 matplotlib.axes.Axes 클래스에 포함되며, 주석(Annotation)을 쉽게 만들 수 있는 기능들을 제공한다.
- 주석을 만들 때 xy 인수로 표현하는 화살표 머리 위치, xytext 인수로 표현하는 텍스트 주석의 위치를 고려해야 한다.
- facecolor 는 화살표 색상을, shrink 는 화살표 길이를 나타내는 매개 변수이다.
fig, ax = plt.subplots()
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=2)
ax.annotate('accent point', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='red', shrink=0.05),)
ax.set_ylim(-2, 2)
plt.show()
- xycoords 인수에 다음과 같은 좌표 문자열을 사용할 수 있다.
지원되는 값 | 내용 |
'figure points' | figure의 왼쪽 하단부터의 지점(points) |
'figure pixels' | figure의 왼쪽 하단부터의 픽셀(pixels) |
'figue fraction' | figure의 왼쪽 하단부터의 부분(fraction) |
'axes points' | axes의 왼쪽 하단 구석으로부터의 지점 |
'axes pixels' | axes의 왼쪽 하단 구석으로부터의 픽셀 |
'axes fraction' | axes의 왼쪽 하단부터의 부분 |
'data' | 주석이 달리는 객체의 좌표 시스템을 사용 (기본값) |
'polar' | native 'data' 좌표가 아니면 (theta, r) |
fig, ax = plt.subplots()
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=2)
ax.set_ylim(-2, 2)
ax.annotate('accent point', fontsize=15, xy=(3, 1), xycoords='data', xytext=(5, 1.5),
textcoords='data', arrowprops=dict(facecolor='blue', shrink=1.5),
horizontalalignment='right', verticalalignment='top',)
plt.show()
- xycoords 인수는 다음과 같은 문자열 값을 가질 수 있다.
xycoords 값 | 내용 |
'offset points' | xy 값으로부터 points의 오프셋 |
'offset pixels' | xy 값으로부터 pixels의 오프셋 |
- textcoords 는 xytext 가 주어진 좌표계이며, 기본값은 xycoords 의 값이다.
- 다음은 textcoords 에 'offset points' 값이 적용되는 예제이다.
fig, ax = plt.subplots()
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=2)
ax.set_ylim(-2, 2)
ax.annotate('point offset from data', fontsize=15, xy=(3, 1), xycoords='data', xytext=(-15, 25),
textcoords='offset points', arrowprops=dict(facecolor='black', shrink=1.25, headwidth=10),
horizontalalignment='right', verticalalignment='top',)
plt.show()
- 화살표 속성을 정의하는 매개 변수 arrowprops 가 arrowstyle 키를 포함하지 않으면 다음 표와 같은 키들을 입력할 수 있다.
- headwidth=10 을 적용하면 위의 예제와 같은 결과가 나타난다.
키 | 내용 |
width | points의 화살의 너비 |
headwidth | points의 화살 머리의 base 너비 |
headlength | points의 화살 머리의 길이 |
shrink | 양쪽 끝에서부터 줄어들 총 길이의 비율 |
? | matplotlib.patches.FancyArrowPatch에 대한 어떤 key |
- 매개 변수 arrowprops 가 arrowstyle 키를 포함하면 위의 표에 나와 있는 키는 사용할 수 없고, 다음 표와 같이 허용된 arrowstyle 값을 입력할 수 있다.
값 | 속성 |
'-' | None |
'->' | head_length=0.4,head_width=0.2 |
'-[' | widthB=1.0,lengthB=0.2,angleB=None |
'|-|' | widthA=1.0,widthB=1.0 |
'-|>' | head_length=0.4,head_width=0.2 |
'<-' | head_length=0.4,head_width=0.2 |
'<->' | head_length=0.4,head_width=0.2 |
'<|-' | head_length=0.4,head_width=0.2 |
'<|-|>' | head_length=0.4,head_width=0.2 |
'fancy' | head_length=0.4,head_width=0.4,tail_width=0.4 |
'simple' | head_length=0.5,head_width=0.5,tail_width=0.2 |
'wedge' | tail_width=0.3,shrink_factor=0.5 |
참고 : https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.annotate.html
- 다음은 arrowstyle 에 양방향 화살표인 <-> 을 적용하는 예제이다.
fig, ax = plt.subplots()
plt.plot(np.arange(10), np.arange(10))
ax.annotate('here', xy=(-3, -3), xytext=(0, 0), arrowprops=dict(arrowstyle='<->', linewidth=3.5), )
plt.xlim(-10, 10)
plt.ylim(-10, 10)
plt.show()
- 다음 예제에서는 annotate() 메소드에 여러 매개 변수를 적용해 주석을 설정한다.
- 화살표 속성을 적용하려면 arrowprops 매개 변수를 사용한다.
- 주석에 속성을 적용하려면 bbox 매개 변수를 사용한다.
- 연산 결과를 그림 파일로 저장하려면 matplotlib.pyplot_savefig 를 적용한다.
fig, ax = plt.subplots()
t = np.arange(-1.0, 1.0, 0.01)
s = np.multiply(t, t**2)
ax.plot(t, s)
ap = dict(arrowstyle='->', color='red', linewidth=3, mutation_scale=20)
bb = dict(facecolor='orange', alpha=0.3, edgecolor='red', boxstyle='square', pad=0.5)
ax.annotate('coordinate system of object annotating', fontsize=14, xy=(0, 0),
xycoords='data', xytext=(-0.8, 0.4), arrowprops=ap)
ax.annotate('data scientist', xy=(0.0, -0.75), xytext=(-0.25, -0.5), color='green', size=20, bbox=bb)
ax.set_ylim(-1.5, 1.5)
plt.savefig('annotate.png', dpi=300) # 연산 결과를 그림 파일로 저장
plt.show()
텍스트 추가
텍스트 생성 명령어
- pyplot 인터페이스와 객체 지향 API에서 텍스트를 생성하는 데 사용하는 명령어들
pyplot API | 객체 지향 API | 내용 |
text | text | Axes의 임의 위치에 텍스트를 추가한다. |
annotate | annotate | Axes이 임의 위치에 옵션 arrow가 있는 주석을 추가한다. |
xlabel | set_xlabel | Axes의 x축에 라벨을 추가한다. |
ylabel | set_ylabel | Axes의 y축에 라벨을 추가한다. |
title | set_title | Axes에 제목을 추가한다. |
figtext | text | Figure의 임의 위치에 텍스트를 추가한다. |
suptitle | suptitle | Figure에 제목을 추가한다. |
- 다음 예제에서는 텍스트 생성 명령어를 사용하기 위해 AxesSubplot 객체인 ax를 생성한다.
fig = plt.figure()
ax = fig.add_subplot(111)
ax.text(0.6, 0.4, 'colored text', color='green', verticalalignment='top', horizontalalignment='left', fontsize=15)
ax.text(2, 4.5, 'boxed italics text', style='italic', fontsize=15, bbox={'facecolor': 'orange', 'alpha': 0.5, 'pad': 10})
ax.plot([3], [2], 'o')
ax.annotate('This Point', xy=(3, 2), xytext=(4.5, 3), color='blue', fontsize=12, arrowprops=dict(facecolor='red', shrink=0.1))
ax.axis([0, 6, 0, 6])
plt.show()
더보기
- 첫 번째 text 명령은 생성된 ax 객체의 x=0.6, y=0.4 좌표에 녹색이며 글자 크기가 15인 colored-text 주석을 추가한다.
- 두 번째 text 명령은 x=2, y=4.5 좌표에 텍스트를 추가하며, 투명도 0.5인 오렌지색 박스 안쪽 여백 10으로 설정된 위치에 이탤릭체 텍스트를 위치시킨다.
- plot() 함수는 x=3 ,y=2 좌표에 원을 그린다.
- annotate() 함수는 x=4.5, y=3 좌표에 글자 크기 12인 파란색 주석 'This Point' 를 추가하고 이 지점에서 x=3, y=2 위치까지 빨간색 화살표를 그린다.
- 끝으로 axis() 함수의 매개 변수 xmin=0, xmax=6, ymin=0, ymax=6 은 축의 범위를 설정한다.
- 이때 2개 text 명령에서 좌표 (0.6, 0.4)와 (2, 4, 5) 스케일 범위가 달라 결과에 표시되지 않기 때문에 이를 방지하기 위해 축의 범위를 늘려 axis() 함수를 설정한 점에 주목한다.
matplotlib.axis 모듈
- matplotlib 모듈의 서브 모듈인 axis 모듈은 눈금과 x, y축에 대한 클래스들을 제공한다.
- Artist 모듈의 구성 및 상속 계통도는 다음과 같다.
- Axis 객체의 Axis, XAxis, YAxis 클래스와 사용할 수 있는 매개 변수는 다음과 같다.
클래스 | matplotlib.axis.Axis(axes, pickradius=15) → XAxis와 YAxis에 대한 기본 클래스 matplotlib.axis.XAxis(axes, pickradius=15) matplotlib.axis.YAxis(axes, pickradius=15) |
매개 변수 | axes : 생성된 Axis가 속하는 Axes pickradius : float, containment tests에 적용, Axis.contains 참조 |
- Axis 클래스의 속성들
- Axis 객체인 matplotlib.axis.Ticker 클래스는 눈금 위치와 형식을 정의하는 객체를 포함하는 컨테이너이다.
- matplotlib.axis.Ticker 클래스의 속성은 다음과 같다.
- 다음은 Tick 객체인 Tick 클래스를 나타낸 것이다.
- 다음은 Tick 클래스의 속성을 나타낸 것이다.
- Tick 객체인 XTick, YTick 클래스의 기능은 다음과 같다.
눈금 위치와 형식 지정하기
- matplotlib.ticker 모듈은 눈금 위치와 형식을 지정하는 클래스들을 포함한다.
- Axis 클래스의 로케이터(Locator)는 주 눈금과 보조 눈금의 위치와 형식을 정하기 위해 사용한다.
- Locator 클래스는 모든 눈금 위치를 설정하는 기본 클래스이다.
- Locator 객체는 데이터 범위에 기반한 뷰 범위를 자동으로 조정 및 관리하고 눈금 위치를 관리한다.
- 다음은 matplotlib.ticker.Locator 클래스의 서브 클래스를 나타낸 것이다.
서브 클래스 | 정의 |
AutoLocator | 기본으로 MaxNLocator, AutoLocator는 대부분의 그래프에서 기본값인 눈금 로케이터(Locator) |
MaxNLocator | 모듈이 최대 수의 범위까지 자동으로 눈금 결정 |
LinearLocator | 최소부터 최대까지 동등한 간격의 눈금 |
LogLocator | 최소부터 최대까지 로그 간격의 눈금 |
MultipleLocator | 눈금과 범위가 정수나 실수의 기본 배수 |
FixedLocator | 눈금 위치가 고정됨. |
IndexLocator | 인덱스에 대한 로케이터 |
NullLocator | 눈금이 없음. |
SymmetricalLogLocator | - symlog norm으로 사용하기 위한 로케이터 - 범위 밖의 부분에서는 LogLocator과 같이 작용하고 범위 내에 있다면 0을 더함. |
LogitLocator | logit scaling에 대한 로케이터 |
OldAutoLocator | MultipleLocator 를 선택하고 자동으로 눈금 위치를 설정하기 위해 동적으로 재할당 |
AutoMinorLocator | - 축이 선형적이고 주 눈금이 일정한 간격일 때 보조 눈금에 대한 로케이터 - 주 눈금을 기본값인 4 또는 5 간격으로 분할하거나 특정 수 간격으로 분할 |
- 눈금 형식은 Formatter 클래스의 서브 클래스에서 설정할 수 있다.
- Formatter 는 단일 눈금 값에서 사용하고, 축에 문자열을 적용한다.
- 다음은 matplotlib.ticker.Formatter 의 서브 클래스를 나타낸다.
서브 클래스 | 정의 |
NullFormatter | No labels on the ticks. |
FixedFormatter | Set the strings manually for the labels. |
FuncFormatter | User defined function sets the labels. |
StrMethodFormatter | Use string format method. |
FormatStrFormatter | Use an old-style sprintf format string. |
ScalarFormatter | Default formatter for scalars: autopick the format string. |
LogFormatter | Formatter for log axes. |
LogFormatterExponent | Format values for log axis using exponent = log_base(value). |
LogFormatterMathtext | Format values for log axis using exponent = log_base(value) using Math text. |
LogFormatterSciNotation | Format values for log axis using scientific notation. |
LogitFormatter | Probability formatter. |
EngFormatter | Format labels in engineering notation. |
PercentFormatter | Format labels as a percentage. |
눈금과 눈금 라벨
- Axes 는 축의 라벨을 나타내는 방법을 나타내는 정보인 matplotlib.axis 객체를 포함하며, 이 객체는 ax.xaxis 와 ax.yaxis 객체를 포함한다.
- Axis 객체는 주 는금과 보조 눈금을 포함하고, 이 눈금들의 위치를 결정하는 데 사용하는 matplotlib.xaxis 객체의 set_major_locator 와 set_minor_locator 메소드를 포함한다.
- 또한 눈금 라벨을 설정하는 데 사용하는 matplotlib.xaxis.set_major_formatter 와 matplotlib.xaxis.set_minor_formatter 메소드를 포함한다.
- 로케이터와 포매터의 기본값을 사용하면 눈금 값과 눈금 라벨을 간단히 설정할 수 있다.
- 다음 예제는 x1에 0~5까지 범위를 설정하고 그 값들을 변수로 가지는 y1에서 눈금을 설정한다.
- 이때 매개 변수 ticks 시퀀스에 눈금 위치를 설정하는 matplotlib.axis.Xaxis.set_ticks(self, ticks, minor=False) 메소드를 적용한다.
- 매개 변수 ticks 는 실수 시퀀스이며, minor 는 불리언이다.
- 다음 예제에서 subplots() 메소드의 인수 tight_layout 을 False 로 적용해 차이를 확인해보자.
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
ax[0].plot(x1, y1)
ax[1].plot(x1, y1)
ax[1].xaxis.set_ticks(np.arange(0., 8.1, 2.))
plt.show()
- ax, ax[1], ax[1].xaxis의 타입을 확인한다.
- ax[1].xaxis는 matplotlib.axis.XAxis 객체임을 확인할 수 있다.
>>> type(ax)
numpy.ndarray
>>> type(ax[1])
matplotlib.axes._subplots.AxesSubplot
>>> type(ax[1].xaxis)
matplotlib.axis.XAxis
- 다음 예제는 그래프의 크기가 같도록 설정한다.
- set_ticklabels 메소드를 이용해 눈금 라벨의 텍스트 값을 설정하는데, tickla 는 텍스트 값들의 모음인 리스트이다.
- 예제의 ax[1].set_xlim(ax[0].get_xlim()) 에서 set_xlim() 은 x축 뷰 범위를 설정하며 인수에 입력하는 첫 번째 서브 플롯인 get_xlim() 은 ax[0]에서 x축 범위를 가져와 반환한다.
- 결과를 보면 ax[1] 그래프가 첫 번째 서브 플롯인 ax[0]의 x축 뷰 범위에 맞춰진 것을 확인할 수 있다.
fig, ax = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
ax[0].plot(x1, y1)
ax[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
tickla = ['%1.2f' % tick for tick in ticks]
ax[1].xaxis.set_ticks(ticks)
ax[1].xaxis.set_ticklabels(tickla)
ax[1].set_xlim(ax[0].get_xlim())
plt.show()
- 기본값이 아닌 로케이터와 포메터를 사용해 눈금 위치와 라벨을 설정하려면 각 축에 Formatter 객체와 Locator 객체를 설정하여 변경하면 된다.
- 다음 예제에서 fomt 에 의해 눈금 수치를 소수점 한 자릿수로 표시하고 FixedLocator 타입이 되는 것을 확인할 수 있다.
fig, ax = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
ax[0].plot(x1, y1)
ax[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
fomt = matplotlib.ticker.FormatStrFormatter('%1.1f')
loc = matplotlib.ticker.FixedLocator(ticks)
ax[1].xaxis.set_major_locator(loc)
ax[1].xaxis.set_major_formatter(fomt)
plt.show()
기타 그래프
막대 그래프
- bar() 와 barh() 함수를 사용해 막대 그래프를 만들 수 있다.
- 다음은 bar() 함수를 적용해 오차 막대(Error Bar)가 있는 막대 그래프를 그리는 예제이다.
- 예제에서는 매개 변수 bottom 을 사용해 bar1과 bar2, 2개 그래프를 1개로 나타내고 yerr 매개 변수를 사용해 오차 막대를 나타낸다.
- 또한 주석과 범례를 추가하고 눈금을 표시한다.
girl_weight = (30, 25, 29, 27, 22, 35)
boy_weight = (33, 37, 28, 25, 20, 23)
girl_err = (3, 2, 1, 2, 4, 1)
boy_err = (1, 2, 3, 2, 3, 1)
num = np.arange(6)
width = 0.40
bar1 = plt.bar(num, girl_weight, width, yerr=girl_err)
bar2 = plt.bar(num, boy_weight, width, bottom=girl_weight, yerr=boy_err)
plt.title('Sample Weight of girls and boys', fontsize=14)
plt.ylabel('Student Weight', fontsize=14)
plt.xticks(num, ('S1', 'S2', 'S3', 'S4', 'S5', 'S6'))
plt.yticks(np.arange(0, 81, 5))
plt.legend((bar1, bar2), ('Girl', 'Boy'))
plt.show()
- 다음은 barh() 함수를 이용해 간단한 수평 막대그래프를 그리는 예제이다.
- set_yticklabels() 함수를 이용해 학생 이름을 수직 라벨로 설정한다.
- invert_yaxis() 는 y축 라벨의 순서를 바꾸는 함수이다.
fig, ax = plt.subplots()
student = ('Haena', 'Yuna', 'Naeun', 'Bumsuk', 'Suho')
y_coord = np.arange(len(student))
weight = np.array([50, 57, 55, 80, 88])
weight_error = np.random.randn(len(student))
ax.barh(y=y_coord, width=weight, xerr=weight_error, align='center')
ax.set_yticks(y_coord)
ax.set_yticklabels(student)
ax.invert_yaxis()
ax.set_xlabel('student weight', fontsize=14)
ax.set_title('How much do students weigh?', fontsize=14)
plt.show()
- 다음은 bar() 함수와 barh() 함수에 적용할 수 있는 매개 변수들을 나타낸다.
매개 변수 | 설명 |
color | 스칼라 또는 유사 배열, 선택적 매개 변수, 막대 표면(faces) 색상 |
edgecolor | 스칼라 또는 유사 배열, 선택적 매개 변수, 막대 가장자리(edges) 색상 |
linewidth | 스칼라 또는 유사 배열, 선택적 매개 변수, 막대 가장자리 너비, 0이면 가장자리를 그리지 않음. |
tick_label | 문자열 또는 유사 배열, 선택적 매개 변수, 막대의 눈금 라벨, 기본값은 None(기본 수치 라벨 사용) |
xerr, yerr | shape(N,) 또는 shape(2, N)의 스칼라 또는 유사 배열, 선택적 매개 변수, None이 아니면 막대 끝부분에 수평/수직 오차 막대를 더함. 오류 값들은 데이터에 상대적인 +/- 크기 - 스칼라 : 모든 막대에 대한 대칭적 +/- 값들 - shape(N,) : 각각의 막대에 대한 대칭적 +/- 값들 - shape(2, N) : 각각의 막대에 대한 개별적인 -와 + 값들, 첫 번째 행은 하위 오류를 포함하고 두 번째 행은 상위 오류를 포함. - None : 오차 막대가 없음. (기본값) |
ecolor | 스칼라 또는 유사 배열, 선택적 매개 변수, 기본값은 black, 오차 막대의 선 색상 |
capsize | 스칼라, 선택적 매개 변수, points로 된 오차 막대 caps의 길이, 기본값은 None, 이것은 rcParams["errorbar.capsize"]의 값, 즉 rcParams 모듈 속성의 값 |
error_kw | 딕셔너리, 선택적 매개 변수, errorbar() 메소드로 전달할 딕셔너리형의 kwargs, 여기서 정의된 ecolor 또는 capsize 값들은 독립적인 kwargs 보다 우선함. |
log | 불리언, 선택적 매개 변수, 기본값은 False, True이면 y축을 로그 스케일이 되도록 설정 |
orientation | ['vertical', 'horizontal'], 선택적 매개 변수, 내부 사용만을 위한 용도, 수평 막대 그래프를 그리려면 barh 사용, 기본값은 vertical |
- 다른 옵션을 사용할 수 있는 사각형 속성인 kwargs 는 다음과 같다.
속성 | 내용 |
agg_filter | a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array |
alpha | scalar or None |
angle | unknown |
animated | bool |
antialiased or aa | bool or None |
bounds | (left, bottom, width, height) |
capstyle | CapStyle or {'butt', 'projecting', 'round'} |
clip_box | Bbox |
clip_on | bool |
clip_path | Patch or (Path, Transform) or None |
color | color |
edgecolor or ec | color or None |
facecolor or fc | color or None |
figure | Figure |
fill | bool |
gid | str |
hatch | {'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'} |
height | unknown |
in_layout | bool |
joinstyle | JoinStyle or {'miter', 'round', 'bevel'} |
label | object |
linestyle or ls | {'-', '--', '-.', ':', '', (offset, on-off-seq), ...} |
linewidth or lw | float or None |
path_effects | AbstractPathEffect |
picker | None or bool or float or callable |
rasterized | bool |
sketch_params | (scale: float, length: float, randomness: float) |
snap | bool or None |
transform | Transform |
url | str |
visible | bool |
width | unknown |
x | unknown |
xy | (float, float) |
y | unknown |
zorder | float |
원 그래프
- pie() 함수는 원그래프(Pie Chart)를 생성한다.
- 원 중심에서 한 개 이상의 쐐기(Wedges)를 확장하면서 면적 백분율의 자동 라벨과 음영 효과를 포함한다.
- 여기서 쐐기는 치즈나 케이크 조각 모양의 V자 부분을 의미한다.
- 여기서 쐐기는 치즈나 케이크 조각 모양의 V자 부분을 의미한다.
- 다음 예제에서 explode 인수의 epd 중, 두 번째 0.1 값은 두 번째 라벨인 Grape 쐐기가 원에서 빼어지는 간격이다.
- autopct 는 쐐기 내부에서 수치로 표현되는 라벨의 형식이다.
- ax.axis('equal') 은 x축과 y축 비율이 동등함을 의미한다.
lbl = 'Apple', 'Grape', 'Pear', 'Lemon'
size = [35, 30, 25, 10]
epd = (0, 0.1, 0, 0)
fig, ax = plt.subplots()
ax.pie(size, textprops={'fontsize': 14}, explode=epd, labels=lbl, autopct='%1.1f%%',
shadow=True, startangle=45)
ax.axis('equal')
plt.show()
728x90
그리드형(광고전용)
'In-depth Study > matplotlib' 카테고리의 다른 글
[matplotlib] matplotlib 기본 (0) | 2022.06.02 |
---|---|
[matplotlib] 맷플롯립(matplotlib) 개요 (0) | 2022.06.01 |