본문 바로가기

카테고리 없음

[프로젝트명 : 미정] 그래프 시각화

728x90
반응형

이전 포스팅에서는 Docker를 활용하여 Kafka로 데이터를 수집하고, mysql에 데이터를 저장하는 것 까지 수행하였다. 이번 포스팅에서는 수집한 데이터들에 대해서 시각화를 나타내기 위해서 수행한 내용들에 대해서 기록하고자 한다.

 

2024.08.31 - [Toy Project] - [프로젝트명 : 미정] ETL 구축하기 - ① 데이터 수집

2024.09.02 - [Toy Project] - [프로젝트명 : 미정] ETL 구축하기 - ② 데이터 수집

2024.09.02 - [Toy Project] - [프로젝트명 : 미정] ETL 구축하기 - ③ Docker 환경 구축


1. 네트워크 분석

우선, 주식 종목 데이터를 보고서 생각했었던 것은 그래프와 같이 노트와 엣지 형태로 시각화를 나타낼 수 있겠다고 생각을 하였었기 때문에 한번 적용해보았다.

 

 

 

[코드]

# 테마정보데이터, 세부종목 데이터 merge
merged_df = pd.merge(theme_details_df, theme_info_df, left_on='테마 idx', right_on='idx')

G = nx.Graph()

for _, row in merged_df.iterrows():
    stock = row['종목명']
    theme = row['Theme_name']
    
    G.add_edge(stock, theme)

pos = nx.spring_layout(G)

theme_nodes = list(merged_df['Theme_name'].unique())
stock_nodes = list(merged_df['종목명'].unique())

node_colors = ['lightgreen' if node in theme_nodes else 'skyblue' for node in G.nodes()]

plt.figure(figsize=(12, 12))
nx.draw(G, pos, with_labels=True, node_color=node_colors, node_size=1000, edge_color='gray', font_size=8)
plt.title('Stock-Theme Relationship Graph')
plt.show()

 

위와 같이 표현했을 때, 몇가지 문제가 있었다.

 

1. 그래프 속 데이터가 깨지는 문제 발생

2. 데이터가 너무 밀집되어 있어 제대로 파악하기가 쉽지 않음.

3. 분석하는데 너무 많은 시간이 소요됨.

 

따라서, 다른 방식으로 시각화 하는 방법을 찾아야 했다.

 

2. 트리맵

다음으로 시도한 내용은 트리맵을 통해서 표현하는 방법이었다. 우선 plotly 라이브러리에서의 트리맵은 양의 지수에 대해서 트리맵을 구성하기 때문에 등락비율에 대해서 절대값을 표현하여 시각화를 시도하였는데, 그러다 보니, 절대값이 큰 음의값을 갖는 테마가 먼저 위치하는 문제가 있었다.

그래서 상승 / 하락 등락비율 구분하여 따로 트리맵을 구성하고 한번에 표현하도록 구성하였다.

당일 테마 등락비율에 따른 트리맵

 

import pandas as pd
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.graph_objects as go

# 파일 경로 설정 (상대 경로 사용)
file_path = './Data_Records/20240829/테마정보수집.xlsx'

# 데이터 불러오기
theme_info_df = pd.read_excel(file_path)

# 'Up/Down' 컬럼에서 % 기호를 제거하고 숫자로 변환
theme_info_df['Up/Down'] = theme_info_df['Up/Down'].str.replace('%', '').astype(float)

# 양수 테마와 음수 테마로 분리
positive_themes = theme_info_df[theme_info_df['Up/Down'] > 0].copy()
negative_themes = theme_info_df[theme_info_df['Up/Down'] < 0].copy()

# 음수 테마의 크기를 절대값으로 변환하여 트리맵에 사용
negative_themes['size'] = negative_themes['Up/Down'].abs()

# 서브플롯 생성 (1행 2열) - 트리맵을 지원하는 서브플롯으로 설정
fig = make_subplots(rows=1, cols=2, 
                    subplot_titles=("양수 테마", "음수 테마"),
                    specs=[[{"type": "treemap"}, {"type": "treemap"}]])

# 1. 양수 테마 트리맵
fig.add_trace(go.Treemap(labels=positive_themes['Theme_name'], 
                         parents=[""] * len(positive_themes), 
                         values=positive_themes['Up/Down'], 
                         marker=dict(colors=positive_themes['Up/Down'], 
                                     colorscale='Blues')),
              row=1, col=1)

# 2. 음수 테마 트리맵 (크기는 절대값으로)
fig.add_trace(go.Treemap(labels=negative_themes['Theme_name'], 
                         parents=[""] * len(negative_themes), 
                         values=negative_themes['size'], 
                         marker=dict(colors=negative_themes['Up/Down'], 
                                     colorscale='Reds')),
              row=1, col=2)

# 서브플롯 레이아웃 업데이트
fig.update_layout(title_text="양수 및 음수 테마별 등락비율 트리맵", 
                  showlegend=False, 
                  height=600)

# 그래프 시각화
fig.show()

 

앞서 그래프 형태로 표현된 것 보다는 보기는 좀 더 편한 것 같다.

 

 

728x90
반응형