[TS] 시계열 이상탐지 시각화

서쿠·2023년 11월 13일
1

today-snippets

목록 보기
2/5
post-thumbnail

오늘의 코드

시계열 전문가로서, 시계열 데이터분석가로서 다변량 시계열 데이터를 시각화하고 이를 살펴보는 작업은 매우 중요합니다. 이에 오늘은 제가 주로 연구/업무에 사용하는 이상탐지 시각화 코드를 정리하고자 합니다.

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.cmmatplotlib.pyplot의 컬러맵 모듈을 의미합니다. 컬러맵은 연속적인 색상의 범위를 제공하며, 다양한 데이터를 시각화할 때 유용하게 사용됩니다.
  • viridismatplotlib에서 제공하는 기본 컬러맵 중 하나입니다. 이 컬러맵은 밝은 노란색에서 시작하여, 밝은 녹색을 거쳐 어두운 파란색으로 끝나는 색상 범위를 가집니다.
  • 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

GridSpecmatplotlib에서 고급 그리드 레이아웃을 만드는 데 사용되는 클래스입니다. 이 클래스는 복잡한 차트 레이아웃을 생성하고 관리하는 데 유용하며, 일반적인 서브플롯 레이아웃보다 더 많은 유연성과 세밀한 제어를 제공합니다.

GridSpec의 주요 기능과 특징

  1. 세밀한 레이아웃 제어: GridSpec을 사용하면, 각 서브플롯의 크기와 위치를 행과 열 단위로 정확하게 지정할 수 있습니다. 이는 표준 subplots 함수를 사용하는 것보다 더 세밀한 제어를 가능하게 합니다.

  2. 비균일 서브플롯 크기: 서브플롯들이 모두 동일한 크기를 가질 필요가 없습니다. 예를 들어, 한 행에 큰 서브플롯 하나와 작은 서브플롯 두 개를 배치하는 것과 같이, 다양한 크기와 비율의 서브플롯을 생성할 수 있습니다.

  3. 행과 열의 조정: GridSpec을 사용하면, 행과 열의 수, 서브플롯 간의 간격(hspace, wspace), 그리고 플롯의 상대적인 너비와 높이를 조정할 수 있습니다.

GridSpec 사용 방법

GridSpec은 일반적으로 다음과 같은 단계로 사용됩니다:

  1. GridSpec 객체 생성: 먼저 matplotlib.gridspec.GridSpec 클래스로부터 객체를 생성합니다. 이 때 행과 열의 수를 지정합니다.

    import matplotlib.gridspec as gridspec
    gs = gridspec.GridSpec(nrows, ncols)
  2. Figure 객체 생성: matplotlibfigure 객체를 생성합니다. 이 객체는 모든 서브플롯을 포함합니다.

    fig = plt.figure()
  3. 서브플롯 추가: fig.add_subplot을 사용하여 각 서브플롯을 GridSpec에 따라 추가합니다. 여기서 서브플롯의 위치는 GridSpec 객체의 슬라이싱을 사용하여 지정합니다.

    ax1 = fig.add_subplot(gs[0, 0]) # 첫 번째 행, 첫 번째 열
    ax2 = fig.add_subplot(gs[1, :]) # 두 번째 행, 모든 열
  4. 서브플롯 커스터마이징: 이제 각 서브플롯(ax1, ax2, ...)에 대해 필요한 그래픽 작업(플롯, 레이블 추가 등)을 진행합니다.

  5. 렌더링 및 표시: 마지막으로 plt.show()를 호출하여 완성된 그림을 표시합니다.

GridSpec은 복잡한 레이아웃을 필요로 하는 고급 그래픽 작업에 매우 유용하며, matplotlib의 강력한 시각화 기능 중 하나입니다.

참고

🍥 제목이 그래프를 침범했다고요? 다음과 같이 해보세요.
제목이 그래프에 침범하는 문제는 matplotlib에서 종종 발생하는 문제입니다. 이 문제를 해결하기 위해 몇 가지 접근 방법을 사용할 수 있습니다:

  1. suptitley 매개변수 조정: fig.suptitle 메소드에는 전체 그림 제목의 위치를 조정하는 y 매개변수가 있습니다. 이 매개변수의 값을 증가시켜 제목을 높이 배치할 수 있습니다.

    fig.suptitle('Feature Values Over Time With Anomalies (Unique Colors)', fontsize=16, y=1.05)
  2. 서브플롯과의 여백 조정: subplots_adjust 메소드를 사용하여 서브플롯과의 상단 여백을 조정할 수 있습니다. 이를 통해 제목과 서브플롯 사이의 공간을 확보할 수 있습니다.

    plt.subplots_adjust(top=0.85)
  3. tight_layout의 매개변수 조정: tight_layout 메소드는 서브플롯의 레이아웃을 자동으로 조정하지만, 때때로 이로 인해 제목이 서브플롯과 겹칠 수 있습니다. pad 매개변수를 조정하여 이 문제를 해결할 수 있습니다.

    plt.tight_layout(pad=3)
  4. Figure 크기 조정: Figure의 크기를 늘려서 서브플롯과 제목 간의 공간을 확보할 수도 있습니다. 이는 figure 함수에서 figsize 매개변수를 조정함으로써 가능합니다.

    fig = plt.figure(figsize=(12, 24))  # 너비와 높이를 적절히 조정

이러한 방법들을 조합하여 사용하면, 제목이 그래프에 침범하는 문제를 해결할 수 있습니다. 그래프의 레이아웃과 서브플롯의 수에 따라 적절한 방법을 선택하고 조정해야 합니다.

profile
Always be passionate ✨

0개의 댓글