Akashic Records

[추가자료] 9.3 데이터 시각화 Matplotlib - RandomWalk(무작위 이동) 본문

Python for Beginners

[추가자료] 9.3 데이터 시각화 Matplotlib - RandomWalk(무작위 이동)

Andrew's Akashic Records 2024. 6. 11. 17:23
728x90

from random import choice

class RandomWalk:
    """랜덤 워크를 만드는 클래스"""

    def __init__(self, num_points=5000):
        """속성을 초기화합니다."""
        self.num_points = num_points

        # 이동은 (0,0)에서 시작합니다.
        self.x_values = [0]
        self.y_values = [0]

    def fill_walk(self):
        """"랜덤 워크의 각 포인트를 계산합니다"""

        # 설정한 이동 수에 도달할 때까지 움직임을 반복합니다
        while len(self.x_values) < self.num_points: # 1
            # 방향과 거리를 정합니다
            x_direction = choice([1, -1]) # 2
            x_distance = choice([0, 1, 2, 3, 4])
            x_step = x_direction * x_distance # 3

            y_direction = choice([1, -1])
            y_distance = choice([0, 1, 2, 3, 4])
            y_step = y_direction * y_distance # 4

            # 움직임이 없는 결정은 버립니다
            if x_step == 0 and y_step == 0: # 5
                continue

            # 새 위치를 계산합니다
            x = self.x_values[-1] + x_step # 6
            y = self.y_values[-1] + y_step

            self.x_values.append(x)
            self.y_values.append(y)

"""
 1에서는 __ init __ ()에서 설정한 이동 수만큼 반복하는 루프를 만듭니다. 
 fill_walk()는 네 가지 랜덤한 결정을 모사하는 형태로 동작합니다. 
 좌우 방향을 정하고, 그 방향으로 얼마나 갈지 정합니다. 
 상하 방향을 정하고, 그 방향으로 얼마나 갈지 정합니다.
 
 2에서는 choice([1, -1])를 사용해 x_direction의 값을 결정합니다. 
 1은 오른쪽, -1은 왼쪽입니다. 
 다음 행의 choice([0, 1, 2, 3, 4])는 좌우 방향으로 이동할 거리를 선택합니다. 
 
 거리는 x_distance에 할당합니다. 여기서 0을 허용하는 이유는 
 완전한 수직 이동도 허용하기 위해서입니다.
 
 3, 4에서는 같은 방식으로 x, y 방향과 해당 거리를 결정합니다. 
 x_step의 값이 양수이면 오른쪽, 음수이면 왼쪽, 0이면 수직으로 이동합니다. 
 마찬가지로 y_step의 값이 양수이면 위로, 음수이면 아래로, 0이면 수평으로 움직입니다. 
 x_step과 y_step이 모두 0이면 움직임이 없는 것이고, 
 이런 경우 루프의 처음으로 돌아가 다음 움직임을 계산합니다(5).
 
 6에서는 x_values의 마지막 값에 x_step을 더해 다음 x 값을 결정하고, y도 마찬지다. 
 새 포인트의 좌표를 x_values와 y_values에 추가합니다.
"""

 

import matplotlib.pyplot as plt

from random_walk import RandomWalk

def draw_chart():
    while True:
        # 랜점 워크를 생성합니다.
        rw = RandomWalk(50_000)
        rw.fill_walk()

        # 랜던 워크의 포인트를 그립니다.

        plt.style.use('classic')

        # figsize는 그래프 크기를 인치로 나타내는 튜플입니다.
        # 화면 해상도는 100dpi로 가정되어 있어 직접 지정해준다.
        fig, ax = plt.subplots(figsize=(10,6), dpi=128)
        point_numbers = range(rw.num_points)
        #시작점과 끝점을 강조합니다.
        ax.scatter(0, 0, c='green', edgecolor='none', s=100)
        ax.scatter(
            rw.x_values[-1],
            rw.y_values[-1],
            c='red',
            edgecolor='none',
            s=100)

        ax.scatter(
            rw.x_values,
            rw.y_values,
            c=point_numbers,
            cmap=plt.cm.Blues,
            edgecolor='none',
            s=11)
        #ax.scatter(rw.x_values, rw.y_values, s=15)

        # 두축을 같은 비율로 설정한다.
        #ax.set_aspect('equal')

        # 축을 체거 합니다.
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)

        plt.show()

        keep_running = input("Make another walk? (y/n): ")

        if keep_running == 'n':
            break


if __name__ == '__main__':
    draw_chart()

 

이 파이썬 코드는 RandomWalk라는 클래스를 사용하여 랜덤 워크(무작위로 이동 경로를 생성하는 시뮬레이션)를 시각화하는 과정을 설명합니다. 코드는 크게 두 부분으로 나뉩니다: 랜덤 워크를 정의하는 RandomWalk 클래스와 랜덤 워크를 시각화하는 draw_chart 함수입니다. 각 부분에 대해 자세히 설명하겠습니다.

1. RandomWalk 클래스

  • 클래스 초기화 (__init__):
    이 메소드는 num_points라는 매개변수를 받아 인스턴스가 생성될 때 초기화합니다. 기본값으로 5000개의 점을 설정하며, 이는 랜덤 워크에서 생성될 점의 총 개수입니다. 초기 위치는 원점(0, 0)으로 설정됩니다.
  • 워크 채우기 (fill_walk):
    fill_walk 메소드는 실제로 랜덤 워크를 생성합니다. 워크는 x축과 y축 방향의 결정을 반복하여 이루어집니다:
    • 방향과 거리 선택: choice([1, -1])은 1(오른쪽 혹은 위쪽) 또는 -1(왼쪽 혹은 아래쪽)을 랜덤으로 선택합니다. choice([0, 1, 2, 3, 4])는 이동할 거리를 결정합니다. 이 값은 해당 방향의 곱으로 실제 단계를 계산합니다.
    • 이동 계산: 계산된 x_stepy_step이 모두 0이면 이동을 하지 않고 넘어갑니다. 이는 코드가 움직임 없는 상태를 제외하는 조건입니다.
    • 새 위치 계산: 이전 위치에 x_step, y_step을 더하여 새 위치를 결정하고, 이를 x_valuesy_values 리스트에 추가합니다.

2. draw_chart 함수

  • 랜덤 워크 인스턴스 생성 및 채우기:
    RandomWalk 인스턴스를 생성하고, fill_walk()를 호출하여 랜덤 워크 데이터를 생성합니다.
  • 시각화 설정:
    • 스타일 설정: plt.style.use('classic')은 Matplotlib의 클래식 스타일을 사용합니다.
    • 그래프 크기와 해상도 설정: figsizedpi를 사용하여 그래프의 크기와 해상도를 설정합니다.
  • 데이터 플로팅:
    • 시작점과 끝점 강조: 시작점은 녹색, 끝점은 적색으로 큰 점으로 표시합니다.
    • 랜덤 워크 그리기: ax.scatter()를 사용하여 x값과 y값을 색상 맵과 함께 플롯합니다. 점의 크기는 11로 설정됩니다.
  • 축 설정:
    • 비율 설정 (주석 처리됨): ax.set_aspect('equal')은 x축과 y축의 스케일을 동일하게 설정할 수 있습니다.
    • 축 숨기기: ax.get_xaxis().set_visible(False)ax.get_yaxis().set_visible(False)를 사용하여 축 레이블을 숨깁니다.
  • 반복 실행 여부 확인:
    사용자에게 추가적인 랜덤 워크 생성 여부를 묻고, 'n'을 입력받으면 반복을 종료합니다.
728x90
Comments