TOP
본문 바로가기
[파이썬 Projects]/<파이썬 웹개발>

[파이썬] Streamlit 웹 개발 - 4: 차트

by 기록자_Recordian 2025. 3. 18.
728x90
반응형
이전 내용
 

[파이썬] [파이썬] Streamlit으로 웹 페이지 만들기 - 3

이전 내용  [파이썬] Streamlit으로 웹 페이지 만들기 - 2이전 내용 [파이썬] Streamlit 으로 웹페이지 만들기 - 1Streamlit Streamlit은 Python으로 빠르고 간편하게 웹 애플리케이션을 만들 수 있는 도구이

puppy-foot-it.tistory.com


Chart 생성하기 -1
: Bar Chart

 

st.pyplot 를 통해 다양한 차트를 생성할 수 있다.

 

* matplotlib의 pyplot에서 한글 깨짐 및 - (마이너스) 설정도 간단하게 할 수 있다.

import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# 한글 설정
plt.rcParams["font.family"] = "Malgun Gothic"
plt.rcParams['axes.unicode_minus'] = False

# DataFrame 생성
data = pd.DataFrame({
    '이름': ['영식', '철수', '영희'],
    '나이': [22, 31, 25],
    '몸무게': [75.5, 80.2, 55.1]
})
st.dataframe(data, use_container_width=True)

fig, ax = plt.subplots()
ax.bar(data['이름'], data['나이'])
st.pyplot(fig)

barplot = sns.barplot(x='이름', y='나이', data=data, ax=ax, palette='Set2')

fig = barplot.get_figure()
st.pyplot(fig)

 


2: Line Chart

 

라인 차트를 생성하기 위해, 연도별 매출액이 담긴 가상의 데이터를 만들어 데이터프레임을 생성해 본다.

매출액은 10,000부터 50,000까지 5,000 단위로 생성 후 리스트에 담고,

연도는 2000년부터 2025년까지 2년 단위로 생성 후 리스트에 담는다. (천 단위 구분 기호를 제거하기 위해 문자열-str 처리 )

 

그리고 두 개의 데이터를 가지고 데이터프레임을 생성하는 데,

매출액의 경우 매출액 리스트 중 연도 갯수만큼 아무거나 뽑도록(random.choice) 하였다.

 

st.line_chart 함수에 해당 데이터프레임을 넣고, 년도를 인덱스로 지정하였다.

# DataFrame 생성
sales = list(range(10_000, 50_000, 5000))
years = [str(i) for i in range(2000, 2026, 2)] # 천 단위 구분 기호 제거
data_2 = pd.DataFrame({
    '년도': years, # 2000년부터 2025년까지 2년 단위
    '매출액': [random.choice(sales) for _ in years]
})
st.dataframe(data_2, use_container_width=True)
st.line_chart(data=data_2.set_index('년도'))


3: Pie Chart

 

파이 차트는 matplotlib의 pie 함수를 불러와 생성할 수 있다.

먼저 판매량 리스트가 담긴 sales_amount 변수, 그리고 그 판매량을 합친 total_sales 변수를 생성하고,

시장 점유율을 구하기 위해 반복문을 이용하여 market_share 변수에 저장하였다.

 

그리고 이를 데이터프레임을 생성하기 위해 넣는다. (시장점유율은 소수점 2자리까지만 뜨도록 설정)

 

plt.pie 함수를 불러와서 값과 레이블을 지정하고, 기타 변수를 지정한 뒤 범례를 추가해 준다.

st.title('주요 신발 브랜드 시장 점유율(%)')
sales_amount = [50, 80, 23, 109, 42]
total_sales = sum(sales_amount)
market_share = [(i / total_sales) * 100 for i in sales_amount]  # 시장 점유율 계산

data_3 = pd.DataFrame({
    'brand' : ['나이키', '아디다스', '퓨마', '뉴발란스', '리복'],
    'sales_amount(M)' : sales_amount,
    'market_share(%)' :  [f"{value:.2f}" for value in market_share], # 소수점 두자리 수로 변경
})
st.dataframe(data_3, use_container_width=True)
# 파이 차트 생성
plt.figure(figsize=(8, 6))  # 차트 크기 설정
plt.pie(data_3['market_share(%)'], labels=data_3['brand'], autopct='%1.1f%%', startangle=90)

plt.axis('equal')  # 비율이 동일하게 유지되도록 설정

# 범례 추가
plt.legend(data_3['brand'], title="brand", loc="upper right") 

# Streamlit에 파이 차트 출력
st.pyplot(plt)

 


각 차트를 탭으로 나눠 출력하기

 

해당 세 개의 차트를 각 탭에 별도로 넣기 위해 코드를 일부 보완했고, 이게 전체 코드이다.

* 한글 깨짐 설정의 경우, 두 가지 방법을 넣어놨는 데, 개인적으로 이전에 써오던 첫 번째 방법보다 두 번째 방법(matplotlib의 rcParams로 설정)이 훨~씬 간단하기 때문에 비교 상 넣어본다.

import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from matplotlib import font_manager, rc
import platform
import random


# 한글 깨짐 해결 - 1
# path = "c:/Windows/Fonts/malgun.ttf"

# if platform.system() == 'Windows':
#     font_name = font_manager.FontProperties(fname=path).get_name()
#     rc('font', family=font_name)
#     plt.rcParams['axes.unicode_minus'] = False
# else:
#     print("한글 폰트 불러오기 실패")

# 한글 설정 - 2
plt.rcParams["font.family"] = "Malgun Gothic"
plt.rcParams['axes.unicode_minus'] = False

# 탭 생성
tab1, tab2, tab3 = st.tabs(['bar', 'line', 'pie'])

with tab1:
    # DataFrame 생성
    data_1 = pd.DataFrame({
        '이름': ['영식', '철수', '영희'],
        '나이': [22, 31, 25],
        '몸무게': [75.5, 80.2, 55.1]
    })
    st.dataframe(data_1, use_container_width=True)

    fig, ax = plt.subplots()
    ax.bar(data_1['이름'], data_1['나이'])
    st.pyplot(fig)

    barplot = sns.barplot(x='이름', y='나이', data=data_1, ax=ax, palette='Set2')

    fig = barplot.get_figure()
    st.pyplot(fig)

with tab2: # 선 차트
    # DataFrame 생성
    sales = list(range(10_000, 50_000, 5000))
    years = [str(i) for i in range(2000, 2026, 2)] # 천 단위 구분 기호 제거
    data_2 = pd.DataFrame({
        '년도': years, # 2000년부터 2025년까지 2년 단위
        '매출액': [random.choice(sales) for _ in years]
    })
    st.dataframe(data_2, use_container_width=True)
    st.line_chart(data=data_2.set_index('년도'))

with tab3: # 파이 차트
    st.title('주요 신발 브랜드 시장 점유율(%)')
    sales_amount = [50, 80, 23, 109, 42]
    total_sales = sum(sales_amount)
    market_share = [(i / total_sales) * 100 for i in sales_amount]  # 시장 점유율 계산

    data_3 = pd.DataFrame({
        'brand' : ['나이키', '아디다스', '퓨마', '뉴발란스', '리복'],
        'sales_amount(M)' : sales_amount,
        'market_share(%)' :  [f"{value:.2f}" for value in market_share], # 소수점 두자리 수로 변경
    })
    st.dataframe(data_3, use_container_width=True)
    # 파이 차트 생성
    plt.figure(figsize=(8, 6))  # 차트 크기 설정
    plt.pie(data_3['market_share(%)'], labels=data_3['brand'], autopct='%1.1f%%', startangle=90)
    
    plt.axis('equal')  # 비율이 동일하게 유지되도록 설정

    # 범례 추가
    plt.legend(data_3['brand'], title="brand", loc="upper right") 

    # Streamlit에 파이 차트 출력
    st.pyplot(plt)

 

이를 Streamlit 화면에서 확인해 보면

 


국내 주식 차트 가져오기
StockListing

 

StockListing 함수를 사용하면 주가 정보를 가져올 수 있다.

import streamlit as st
import FinanceDataReader as fdr
import datetime
import pandas as pd

 

FinanceDataReader 라이브러리 설치 필요

pip install -U finance-datareader

 

# 한국거래소 상장종목 전체 가져오기 
df = fdr.StockListing("KRX")

# 한국거래소 상장종목 일부 출력해보기
st.write(df.head())


주가 조회하는 기능 추가하기
: 조회일자, 종목

 

◆ 데이터 (날짜, 종목)를 입력받을 수 있는 칸 만들기

date_input 함수와 text_input 함수를 사용하여 각각 조회일자, 주식 종목을 입력받는 기능을 추가한다.

date = st.date_input(
    '조회 시작일 선택',
    datetime.datetime(2022,1,1)
)

code = st.text_input(
    '종목코드',
    value='',
    placeholder='종목 코드를 입력해 주세요'
)

 

◆ 데이터 불러와 시각화해 주는 기능 추가하기

현재 상태로는 날짜와 코드를 넣어도 아무런 변화가 없다.

그렇기 때문에 날짜와 코드를 입력받았을 때 해당 데이터를 표시할 수 있는 기능을 추가해 준다.

이 코드는 날짜와 코드를 입력받으면, 해당 정보를 토대로 종가를 가져와서 Line Chart를 생성해 준다.

if code and date: # code와 date에 값이 있으면(True)
    df = fdr.DataReader(code, date)
    # 날짜를 기준으로 종가를 가져옴
    data = df.sort_index(ascending=True).loc[:, 'Close']
    st.line_chart(data) # 라인차트 생성

▶ 차트를 마우스 휠로 돌리면 자동으로 조회 기간이 줄었다 늘었다하며 그 기간에 맞게 차트가 바뀐다.

 

▶ 차트 옆 점 세개를 클릭하면 다양한 옵션이 나온다.


레이아웃 꾸며보기
: 사이드바, 탭 나누기, expander 추가하기

 

한 페이지에 나오던 주가 데이터프레임과 차트를 탭으로 나눠 탭1에는 차트, 탭2에는 데이터프레임이 나오도록 바꾸고, 사이드바를 추가하여 사이드바에서 날짜와 종목을 조회할 수 있도록 수정한다.

또한, expander 함수를 추가하여 내용을 접고 펼칠 수 있는 영역을 생성하고, 안에는 주가와 관련된 내용을 추가해 준다.

* 데이터가 자동으로 표시되어 있어야 하므로, 종목코드(code) 변수의 매개변수 value에는 삼성전자 코드(005930)을 기본값으로 넣어 놓는다.

import streamlit as st
import FinanceDataReader as fdr
import datetime
import pandas as pd
     
# 한국거래소 상장종목 전체 가져오기 
df = fdr.StockListing("KRX")

# 사이드바: 화면 왼쪽의 영역을 나누어 사용
with st.sidebar:
    # 종목 조회 레이아웃 추가
    date = st.date_input(
        '조회 시작일 선택',
        datetime.datetime(2022,1,1)
)
    code = st.text_input(
    '종목코드',
    value='005930', # 기본값: 삼성전자
    placeholder='종목 코드를 입력해 주세요'
)

# 탭 생성하기
tab1, tab2 = st.tabs(['차트', '데이터'])

with tab1:
    if code and date: # code와 date에 값이 있으면(True)
        df = fdr.DataReader(code, date)
        # 날짜를 기준으로 종가를 가져옴
        data = df.sort_index(ascending=True).loc[:, 'Close']
        st.line_chart(data) # 라인차트 생성

with tab2:
    if code and date: # code와 date에 값이 있으면(True)
        df = fdr.DataReader(code, date)
        # 한국거래소 상장종목 일부 출력해보기
        st.write(df.head())

    with st.expander('칼럼 설명'):
            st.markdown('''
            - Open: 시가
            - High: 고가
            - Low: 저가
            - Close: 종가
            - Volumn: 거래량
            - Adj Close: 수정 종가
            ''')

 

 


다음 내용

 

[파이썬] Streamlit 웹 개발 - 5: 로또 번호 생성 페이지

이전 내용 [파이썬] Streamlit 으로 웹 페이지 만들기 - 4이전 내용 [파이썬] [파이썬] Streamlit으로 웹 페이지 만들기 - 3이전 내용  [파이썬] Streamlit으로 웹 페이지 만들기 - 2이전 내용 [파이썬] Stre

puppy-foot-it.tistory.com


[참고]

https://wikidocs.net/172650

 

 

728x90
반응형