[TS] ์๊ณ์ด ์ด์ํ์ง ์๊ฐํ
์๋ณธ ๊ฒ์๊ธ: https://velog.io/@euisuk-chung/TS-์๊ณ์ด-์ด์ํ์ง-์๊ฐํ
์ค๋์ ์ฝ๋
์๊ณ์ด ์ ๋ฌธ๊ฐ๋ก์, ์๊ณ์ด ๋ฐ์ดํฐ๋ถ์๊ฐ๋ก์ ๋ค๋ณ๋ ์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ์๊ฐํํ๊ณ ์ด๋ฅผ ์ดํด๋ณด๋ ์์
์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ด์ ์ค๋์ ์ ๊ฐ ์ฃผ๋ก ์ฐ๊ตฌ/์
๋ฌด์ ์ฌ์ฉํ๋ ์ด์ํ์ง ์๊ฐํ ์ฝ๋๋ฅผ ์ ๋ฆฌํ๊ณ ์ ํฉ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
def plot_mul_ad(df, df_w_result, model_name='IForest'):
# Define a color palette with enough colors
colors = plt.cm.viridis(np.linspace(0, 1, df.shape[1]))
# Create a figure with GridSpec
fig = plt.figure(figsize=(12, 2 * df.shape[1])) # Adjust the figure size
gs = gridspec.GridSpec(df.shape[1], 1, fig, 0, 0, 1, 1, hspace=0.5)
for i, (col, color) in enumerate(zip(df.columns, colors)):
ax = fig.add_subplot(gs[i, 0])
ax.plot(df.index.values, df[col].values, label=col, color=color)
# Mark anomalies with red dots
anomalies = df[df_w_result[f'{model_name}'] == -1]
ax.scatter(anomalies.index, anomalies[col], color='red', label='Anomaly', zorder=5)
ax.set_ylabel(col)
ax.legend()
# Set common labels
plt.xlabel('Time (Index)')
plt.xticks(rotation=45)
fig.suptitle('Feature Values Over Time With Anomalies (Unique Colors)', fontsize=16, y=1.05)
plt.show()
์ฃผ์๊ธฐ๋ฅ1. cm.viridis
matplotlib์์ plt.cm.viridis(np.linspace(0, 1, df.shape[1])) ์ฝ๋๋ viridis ์ปฌ๋ฌ๋งต์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ํ๋ ์(df)์ ์ด ์์ ๋ฐ๋ผ ์์ ๋ฐฐ์ด์ ์์ฑํ๋ ๋ฐฉ๋ฒ์
๋๋ค. ์ด ์ฝ๋๋ฅผ ๋ถํดํ์ฌ ๊ฐ ๋ถ๋ถ์ ์๋ฏธ๋ฅผ ์ดํดํด ๋ณด๊ฒ ์ต๋๋ค.
1. plt.cm.viridis
plt.cm์matplotlib.pyplot์ ์ปฌ๋ฌ๋งต ๋ชจ๋์ ์๋ฏธํฉ๋๋ค. ์ปฌ๋ฌ๋งต์ ์ฐ์์ ์ธ ์์์ ๋ฒ์๋ฅผ ์ ๊ณตํ๋ฉฐ, ๋ค์ํ ๋ฐ์ดํฐ๋ฅผ ์๊ฐํํ ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค.viridis๋matplotlib์์ ์ ๊ณตํ๋ ๊ธฐ๋ณธ ์ปฌ๋ฌ๋งต ์ค ํ๋์ ๋๋ค. ์ด ์ปฌ๋ฌ๋งต์ ๋ฐ์ ๋ ธ๋์์์ ์์ํ์ฌ, ๋ฐ์ ๋ น์์ ๊ฑฐ์ณ ์ด๋์ด ํ๋์์ผ๋ก ๋๋๋ ์์ ๋ฒ์๋ฅผ ๊ฐ์ง๋๋ค.viridis์ปฌ๋ฌ๋งต์ ๋์ ๊ฐ๋ ์ฑ๊ณผ ์๋งน ์ ๊ทผ์ฑ์ ์ํด ์ค๊ณ๋์์ผ๋ฉฐ, ๋ฐ์ดํฐ์ ์ธ๋ฐํ ๋ถ๋ถ๊น์ง ๊ตฌ๋ณํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์ด์ ธ ์์ต๋๋ค.
2. np.linspace(0, 1, df.shape[1])
np.linspace๋ NumPy ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ์๋ก, ์ง์ ๋ ๋ฒ์ ๋ด์์ ๊ท ๋ฑํ ๊ฐ๊ฒฉ์ ์ซ์๋ค์ ์์ฑํฉ๋๋ค.- ์ด ๊ฒฝ์ฐ
np.linspace(0, 1, df.shape[1])๋ 0๊ณผ 1 ์ฌ์ด์ ๊ฐ์df.shape[1](๋ฐ์ดํฐ ํ๋ ์์ ์ด ์)๋งํผ ๊ท ๋ฑํ๊ฒ ๋ถํ ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ์ด์ ๋ํด ๊ณ ์ ํ ์์์ ํ ๋นํ ์ ์๋ ๊ฐ์ ๋ฐฐ์ด์ด ์์ฑ๋ฉ๋๋ค.
๊ฒฐํฉ๋ ์ฌ์ฉ
์ด ์ฝ๋์ ๊ฒฐํฉ๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ ํ๋ ์์ ๊ฐ ์ด์ ๋ํด ๊ณ ์ ํ๊ณ ๊ตฌ๋ณ ๊ฐ๋ฅํ ์์์ ํ ๋นํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. viridis ์ปฌ๋ฌ๋งต์ np.linspace๋ฅผ ์ ์ฉํจ์ผ๋ก์จ, ๋ฐ์ดํฐ ํ๋ ์์ ๊ฐ ์ด์ ํด๋นํ๋ ๊ณ ์ ํ ์์์ ์ป์ ์ ์์ต๋๋ค. ์ด๋ ๋ณต์กํ ๋ฐ์ดํฐ ์ธํธ๋ฅผ ์๊ฐํํ ๋ ์ ์ฉํ๋ฉฐ, ๊ฐ ์ด์ด๋ ๋ฐ์ดํฐ ์๋ฆฌ์ฆ๋ฅผ ์ฝ๊ฒ ๊ตฌ๋ณํ ์ ์๋๋ก ๋์์ค๋๋ค.
์ฃผ์๊ธฐ๋ฅ2. GridSpec
GridSpec์ matplotlib์์ ๊ณ ๊ธ ๊ทธ๋ฆฌ๋ ๋ ์ด์์์ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋๋ ํด๋์ค์
๋๋ค. ์ด ํด๋์ค๋ ๋ณต์กํ ์ฐจํธ ๋ ์ด์์์ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐ ์ ์ฉํ๋ฉฐ, ์ผ๋ฐ์ ์ธ ์๋ธํ๋กฏ ๋ ์ด์์๋ณด๋ค ๋ ๋ง์ ์ ์ฐ์ฑ๊ณผ ์ธ๋ฐํ ์ ์ด๋ฅผ ์ ๊ณตํฉ๋๋ค.
GridSpec์ ์ฃผ์ ๊ธฐ๋ฅ๊ณผ ํน์ง
- ์ธ๋ฐํ ๋ ์ด์์ ์ ์ด:
GridSpec์ ์ฌ์ฉํ๋ฉด, ๊ฐ ์๋ธํ๋กฏ์ ํฌ๊ธฐ์ ์์น๋ฅผ ํ๊ณผ ์ด ๋จ์๋ก ์ ํํ๊ฒ ์ง์ ํ ์ ์์ต๋๋ค. ์ด๋ ํ์คsubplotsํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋ ์ธ๋ฐํ ์ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. - ๋น๊ท ์ผ ์๋ธํ๋กฏ ํฌ๊ธฐ: ์๋ธํ๋กฏ๋ค์ด ๋ชจ๋ ๋์ผํ ํฌ๊ธฐ๋ฅผ ๊ฐ์ง ํ์๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํ ํ์ ํฐ ์๋ธํ๋กฏ ํ๋์ ์์ ์๋ธํ๋กฏ ๋ ๊ฐ๋ฅผ ๋ฐฐ์นํ๋ ๊ฒ๊ณผ ๊ฐ์ด, ๋ค์ํ ํฌ๊ธฐ์ ๋น์จ์ ์๋ธํ๋กฏ์ ์์ฑํ ์ ์์ต๋๋ค.
- ํ๊ณผ ์ด์ ์กฐ์ :
GridSpec์ ์ฌ์ฉํ๋ฉด, ํ๊ณผ ์ด์ ์, ์๋ธํ๋กฏ ๊ฐ์ ๊ฐ๊ฒฉ(hspace, wspace), ๊ทธ๋ฆฌ๊ณ ํ๋กฏ์ ์๋์ ์ธ ๋๋น์ ๋์ด๋ฅผ ์กฐ์ ํ ์ ์์ต๋๋ค.
GridSpec ์ฌ์ฉ ๋ฐฉ๋ฒ
GridSpec์ ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋จ๊ณ๋ก ์ฌ์ฉ๋ฉ๋๋ค:
-
GridSpec ๊ฐ์ฒด ์์ฑ: ๋จผ์
matplotlib.gridspec.GridSpecํด๋์ค๋ก๋ถํฐ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ์ด ๋ ํ๊ณผ ์ด์ ์๋ฅผ ์ง์ ํฉ๋๋ค.1 2
import matplotlib.gridspec as gridspec gs = gridspec.GridSpec(nrows, ncols)
-
Figure ๊ฐ์ฒด ์์ฑ:
matplotlib์figure๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ์ด ๊ฐ์ฒด๋ ๋ชจ๋ ์๋ธํ๋กฏ์ ํฌํจํฉ๋๋ค.1
fig = plt.figure()
-
์๋ธํ๋กฏ ์ถ๊ฐ:
fig.add_subplot์ ์ฌ์ฉํ์ฌ ๊ฐ ์๋ธํ๋กฏ์GridSpec์ ๋ฐ๋ผ ์ถ๊ฐํฉ๋๋ค. ์ฌ๊ธฐ์ ์๋ธํ๋กฏ์ ์์น๋GridSpec๊ฐ์ฒด์ ์ฌ๋ผ์ด์ฑ์ ์ฌ์ฉํ์ฌ ์ง์ ํฉ๋๋ค.1 2
ax1 = fig.add_subplot(gs[0, 0]) # ์ฒซ ๋ฒ์งธ ํ, ์ฒซ ๋ฒ์งธ ์ด ax2 = fig.add_subplot(gs[1, :]) # ๋ ๋ฒ์งธ ํ, ๋ชจ๋ ์ด
- ์๋ธํ๋กฏ ์ปค์คํฐ๋ง์ด์ง: ์ด์ ๊ฐ ์๋ธํ๋กฏ(
ax1,ax2, โฆ)์ ๋ํด ํ์ํ ๊ทธ๋ํฝ ์์ (ํ๋กฏ, ๋ ์ด๋ธ ์ถ๊ฐ ๋ฑ)์ ์งํํฉ๋๋ค. - ๋ ๋๋ง ๋ฐ ํ์: ๋ง์ง๋ง์ผ๋ก
plt.show()๋ฅผ ํธ์ถํ์ฌ ์์ฑ๋ ๊ทธ๋ฆผ์ ํ์ํฉ๋๋ค.
GridSpec์ ๋ณต์กํ ๋ ์ด์์์ ํ์๋ก ํ๋ ๊ณ ๊ธ ๊ทธ๋ํฝ ์์
์ ๋งค์ฐ ์ ์ฉํ๋ฉฐ, matplotlib์ ๊ฐ๋ ฅํ ์๊ฐํ ๊ธฐ๋ฅ ์ค ํ๋์
๋๋ค.
์ฐธ๊ณ
๐ฅ ์ ๋ชฉ์ด ๊ทธ๋ํ๋ฅผ ์นจ๋ฒํ๋ค๊ณ ์? ๋ค์๊ณผ ๊ฐ์ด ํด๋ณด์ธ์.
์ ๋ชฉ์ด ๊ทธ๋ํ์ ์นจ๋ฒํ๋ ๋ฌธ์ ๋ matplotlib์์ ์ข
์ข
๋ฐ์ํ๋ ๋ฌธ์ ์
๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
-
suptitle์y๋งค๊ฐ๋ณ์ ์กฐ์ :fig.suptitle๋ฉ์๋์๋ ์ ์ฒด ๊ทธ๋ฆผ ์ ๋ชฉ์ ์์น๋ฅผ ์กฐ์ ํ๋y๋งค๊ฐ๋ณ์๊ฐ ์์ต๋๋ค. ์ด ๋งค๊ฐ๋ณ์์ ๊ฐ์ ์ฆ๊ฐ์์ผ ์ ๋ชฉ์ ๋์ด ๋ฐฐ์นํ ์ ์์ต๋๋ค.1
fig.suptitle('Feature Values Over Time With Anomalies (Unique Colors)', fontsize=16, y=1.05) -
์๋ธํ๋กฏ๊ณผ์ ์ฌ๋ฐฑ ์กฐ์ :
subplots_adjust๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์๋ธํ๋กฏ๊ณผ์ ์๋จ ์ฌ๋ฐฑ์ ์กฐ์ ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ ๋ชฉ๊ณผ ์๋ธํ๋กฏ ์ฌ์ด์ ๊ณต๊ฐ์ ํ๋ณดํ ์ ์์ต๋๋ค.1
plt.subplots_adjust(top=0.85)
-
tight_layout์ ๋งค๊ฐ๋ณ์ ์กฐ์ :tight_layout๋ฉ์๋๋ ์๋ธํ๋กฏ์ ๋ ์ด์์์ ์๋์ผ๋ก ์กฐ์ ํ์ง๋ง, ๋๋๋ก ์ด๋ก ์ธํด ์ ๋ชฉ์ด ์๋ธํ๋กฏ๊ณผ ๊ฒน์น ์ ์์ต๋๋ค.pad๋งค๊ฐ๋ณ์๋ฅผ ์กฐ์ ํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.1
plt.tight_layout(pad=3)
-
Figure ํฌ๊ธฐ ์กฐ์ : Figure์ ํฌ๊ธฐ๋ฅผ ๋๋ ค์ ์๋ธํ๋กฏ๊ณผ ์ ๋ชฉ ๊ฐ์ ๊ณต๊ฐ์ ํ๋ณดํ ์๋ ์์ต๋๋ค. ์ด๋
figureํจ์์์figsize๋งค๊ฐ๋ณ์๋ฅผ ์กฐ์ ํจ์ผ๋ก์จ ๊ฐ๋ฅํฉ๋๋ค.1
fig = plt.figure(figsize=(12, 24)) # ๋๋น์ ๋์ด๋ฅผ ์ ์ ํ ์กฐ์
์ด๋ฌํ ๋ฐฉ๋ฒ๋ค์ ์กฐํฉํ์ฌ ์ฌ์ฉํ๋ฉด, ์ ๋ชฉ์ด ๊ทธ๋ํ์ ์นจ๋ฒํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๊ทธ๋ํ์ ๋ ์ด์์๊ณผ ์๋ธํ๋กฏ์ ์์ ๋ฐ๋ผ ์ ์ ํ ๋ฐฉ๋ฒ์ ์ ํํ๊ณ ์กฐ์ ํด์ผ ํฉ๋๋ค.