On the journey of

[AWS 사전공인교육] Streamlit 활용하기 (2) 본문

Experiences & Study/AWS

[AWS 사전공인교육] Streamlit 활용하기 (2)

dlrpskdi 2023. 10. 7. 23:47

요 이틀간...갑자기 조회수가 치솟아서 좀 무섭다 ,,, 뭘...검색하고 오는 거지...? 여튼 AWS Streamlit 활용교육 기록 2차 :)


9. 위젯

9.1. st.checkbox – 체크박스

import streamlit as st 
## Checkbox 
if st.checkbox("Show/Hide"):
st.write("체크박스가 선택되었습니다.")

9.2 라디오버튼

import streamlit as st
## Radio button
status = st.radio("Select status.", ("Active", "Inactive"))
if status == "Active":
 st.success("활성화 되었습니다.")
else:
 st.warning("비활성화 되었습니다.")

9.3. st.selectbox : 드랍다운 선택

import streamlit as st
## Select Box
occupation = st.selectbox("직군을 선택하세요.", [
 "Backend Developer",
 "Frontend Developer",
 "ML Engineer",
 "Engineer",
 "Database Administrator",
 "Scientist",
 "Data Analyst",
 "Security Engineer"
])
st.write(" 직군은 ", occupation, " 입니다.")

9.4. st.multiselect - 드랍다운 다중 선택

import streamlit as st
## MultiSelect
location = st.multiselect("선호하는 유투브 채널을 선택하세요.",
	(
 "운동",
 "IT 기기",
 "브이로그",
 "먹방",
 "반려동물",
 "맛집 리뷰"
	 )
)
st.write(len(location), "가지를 선택했습니다.")

9.5 슬라이더

import streamlit as st
## Slider
level = st.slider("레벨을 선택하세요.", 1, 5)

9.6 st button - 버튼

import streamlit as st
## Buttons
if st.button("About"):
 st.text("Streamlit 을 이용한 튜토리얼입니다.")

9.7 텍스트 입력

import streamlit as st
# Text Input
first_name = st.text_input("Enter Your First Name", "Type Here ...")
if st.button("Submit", key='first_name'):
 result = first_name.title()
 st.success(result)
# Text Area
message = st.text_area("메세지를 입력하세요.", "Type Here ...")
if st.button("Submit", key='message'):
 result = message.title()
 st.success(result)

9.8 날짜와 시간 입력

## Date Input
import streamlit as st
import datetime
today = st.date_input("날짜를 선택하세요.", datetime.datetime.now())
the_time = st.time_input("시간을 입력하세요.", datetime.time())

9.9. 코드와 JSON 출력

* with st.echo(): 이하의 코드는 코드블럭으로 출력된다.

## Display Raw Code — one line
st.subheader("Display one-line code")
st.code("import numpy as np")
# Display Raw Code — snippet
st.subheader("Display code snippet")
with st.echo():
 # 여기서부터 아래의 코드를 출력하는 것
 import pandas as pd
 df = pd.DataFrame()
## Display JSON
st.subheader("Display JSON")
st.json({"name" : "민수", "gender": "male", "Age": 29})

9.9.1. 사이드바 st.sidebar에서도 대부분의 위젯을 지원하므로, 다양하게 사이드바를 구성할 수 있다.

* 단, st.echo, st.spinner, st.write제외!

import streamlit as st
## Sidebars
st.sidebar.header("사이드바 메뉴")
st.sidebar.selectbox("메뉴를 선택하세요.",
 ["데이터",
 "EDA",
 "코드"])

9.10. 차트 그리기

Streamlit은 자체 내장된 기본적인 차트 외 matplotlib, plot.ly, altair, vega_ilte, bokeh, deck_gl, pydeck, graph_viz 등 다양한 시각 화 패키지를 지원한다. 그 예시를 보자. 

## Plotting
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
st.subheader("Matplotlib 으로 차트 그리기")

# GitHub 에서 아이리스 데이터 다운로드
url = "https://raw.githubusercontent.com/uiuc-cse/data-fa14/ghpages/data/iris.csv"
iris_df = pd.read_csv(url)
## Plotting
st.subheader("Matplotlib 으로 차트 그리기")
fig, ax = plt.subplots()
ax = iris_df[iris_df['species']=='virginica']['petal_length'].hist()
st.pyplot(fig)

 

9.11 Layout

import streamlit as st
st.title("Registeration form")
first, last = st.columns(2)
first.text_input("First Name")
last.text_input("Last Name")
email, mob = st.columns([3,1])
email.text_input("Email ID")
mob.text_input("Mob Number")
user, pw, pw2 = st.columns(3)
user.text_input("Username")
pw.text_input("Password", type="password")
pw2.text_input("Retype your password", type="password")
ch, bl, sub = st.columns(3)
ch.checkbox("I Agree")
sub.button("Submit")

10. 캐싱 : 데이터를 임시 저장 영역인 캐시에 저장하여 데이터 검색을 가속화하는 기술

import streamlit as st
import pandas as pd
import time
@st.cache_data
def fetch_and_clean_data(url):
 data = pd.read_csv(url)
 return data
DATA_URL_1 = "https://raw.githubusercontent.com/uiuc-cse/datafa14/gh-pages/data/iris.csv"
DATA_URL_2 = "https://raw.githubusercontent.com/mwaskom/seaborndata/master/raw/titanic.csv"
# 시작 시간 기록
start_time = time.time()
d1 = fetch_and_clean_data(DATA_URL_1)
# 종료 시간 기록
end_time = time.time()
# 실행 시간 계산
execution_time = end_time - start_time
# 실행 시간 출력
st.write(f"총 실행 시간: {execution_time:.6f} 초")
st.write(d1.head())
# 시작 시간 기록
start_time = time.time()
d2 = fetch_and_clean_data(DATA_URL_1)
# Does not execute the function. Instead, returns its previously 
computed
end_time = time.time()
# 실행 시간 계산
execution_time = end_time - start_time
# 실행 시간 출력
st.write(f"총 실행 시간: {execution_time:.6f} 초")
st.write(d2.head())
# 시작 시간 기록
start_time = time.time()
d3 = fetch_and_clean_data(DATA_URL_2)
# This is a different URL, so the function executes.
# 종료 시간 기록
end_time = time.time()
# 실행 시간 계산
execution_time = end_time - start_time
# 실행 시간 출력
st.write(f"총 실행 시간: {execution_time:.6f} 초")
st.write(d3.head())

11. 세션(Session state ; 사용자가 웹 애플리케이션과 상호작용하는 기간)

import streamlit as st
st.title('Counter Example')

if 'count' not in st.session_state:
st.session_state.count = 0
# Create a button which will increment the counter
increment = st.button('Increment')
if increment:
 st.session_state.count += 1
# A button to decrement the counter
decrement = st.button('Decrement')
if decrement:
 st.session_state.count -= 1
st.write('Count = ', st.session_state.count)

실제 활용 예시로 넘어가보자. IRIS 데이터를 업로드하여 시각화해 보는 걸로!

12. 파일 업로드

import streamlit as st
uploaded_files = st.file_uploader("Choose a CSV file", 
accept_multiple_files=True)
for uploaded_file in uploaded_files:
 bytes_data = uploaded_file.read()
 st.write("filename:", uploaded_file.name)
 st.write(bytes_data)

13.데이터 프로파일링(파일 업로드하여 읽어오고, 기초통계량을 내본다)

import platform
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
plt.rcParams['axes.unicode_minus'] = False
if platform.system() == 'Linux':
 rc('font', family='NanumGothic')
 
# 스트림릿 앱 생성
st.title("streamlit 맛보기")
# 파일 업로드 위젯
uploaded_file = st.file_uploader("데이터 파일 업로드", type=["csv", 
"xlsx"])
if uploaded_file is not None:
 # 업로드한 파일을 DataFrame 으로 변환
 df = pd.read_csv(uploaded_file) 
 ## 엑셀 파일일 경우 pd.read_excel 
사용
 
 # 데이터 프로파일링
 st.header("데이터 미리보기")
 st.write(df.head())
 st.header("기본 정보")
 st.write("행 수:", df.shape[0])
 st.write("열 수:", df.shape[1])
 st.header("누락된 값")
 missing_data = df.isnull().sum()
 st.write(missing_data)
 st.header("중복된 행 수")
 duplicated_rows = df.duplicated().sum()
 st.write(duplicated_rows)
 st.header("수치형 데이터 기술 통계량")
 numerical_stats = df.describe()
 st.write(numerical_stats)
 st.header("이상치 탐지 (상자 그림)")
 plt.figure(figsize=(10, 6))
 plt.boxplot(df.select_dtypes(include=['number']).values)
 plt.xticks(range(1, len(df.columns) + 1), df.columns, 
rotation=45)
 plt.title("Outlier detection (box plot)")
 st.pyplot(plt)
 st.header("데이터 분포 시각화")
 column_to_plot = st.selectbox("열 선택", df.columns)
 plt.figure(figsize=(10, 6))
 plt.hist(df[column_to_plot], bins=20, edgecolor='k')
 plt.xlabel(column_to_plot)
 plt.ylabel("빈도")
 plt.title(f"{column_to_plot} Data Distribution")
 st.pyplot(plt)

14. IRIS 데이터 시각화

import streamlit as st
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
st.set_option('deprecation.showPyplotGlobalUse', False)

# 아이리스 데이터셋 불러오기
@st.cache_data
def load_data():
# GitHub 에서 아이리스 데이터 다운로드
 url = "https://raw.githubusercontent.com/uiuc-cse/data-fa14/ghpages/data/iris.csv"
 iris_df = pd.read_csv(url)
 return iris_df
iris_data = load_data()

여기선 set_option을 통한 환경설정이 가장 중요한 코드였다 ! 

#스트림릿 앱 제목 설정
st.title('아이리스 데이터 시각화')
# 데이터프레임 출력
st.subheader('아이리스 데이터셋')
st.write(iris_data)
# 품종별 특성 분포 시각화
st.subheader('품종별 특성 분포')
for feature in iris_data.columns[:-1]:
 plt.figure(figsize=(8, 6))
 sns.boxplot(x='species', y=feature, data=iris_data)
 plt.title(f'{feature} Distribution')
 plt.xlabel('species')
 plt.ylabel(feature)
 st.pyplot()

# 특성 간 상관 관계 시각화
st.subheader('특성 간 상관 관계')
correlation_matrix = iris_data.corr()
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
st.pyplot()

# 품종별 특성 산점도 시각화
st.subheader('품종별 특성 산점도')
sns.pairplot(iris_data, hue='species', diag_kind='kde')
st.pyplot()

set_option을 통해 설정했던  PyplotGlobalUse 경고는 스트림릿 앱에서 Matplotlib 의 그림(figure)을 스트림릿에 전달할 때 발생하는 경고로, 안 뜨게 하고 싶으면 위 코드처럼 작성해도 되지만 아래와 같이 작성해도 무방하다. 

import streamlit as st
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 아이리스 데이터셋 불러오기
@st.cache_data
def load_data():

# GitHub 에서 아이리스 데이터 다운로드
 url = "https://raw.githubusercontent.com/uiuc-cse/data-fa14/ghpages/data/iris.csv"
 iris_df = pd.read_csv(url)
 return iris_df
iris_data = load_data()
# 스트림릿 앱 제목 설정
st.title('아이리스 데이터 시각화')
# 데이터프레임 출력
st.subheader('아이리스 데이터셋')
st.write(iris_data)
# 품종별 특성 분포 시각화
st.subheader('품종별 특성 분포')
for feature in iris_data.columns[:-1]:
 plt.figure(figsize=(8, 6))
 sns.boxplot(x='species', y=feature, data=iris_data)
 plt.title(f'{feature} Distribution')
 plt.xlabel('species')
 plt.ylabel(feature)
 st.pyplot(plt)
 
# 특성 간 상관 관계 시각화
st.subheader('특성 간 상관 관계')
correlation_matrix = iris_data.corr()
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
ax = sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
st.pyplot(plt)
# 품종별 특성 산점도 시각화
st.subheader('품종별 특성 산점도')
sns.pairplot(iris_data, hue='species', diag_kind='kde')
sns.pairplot(iris_data, hue='species', diag_kind='kde')
st.pyplot(plt)

그 외 약간 잡다(?) 한 느낌의 코드도 있는데, 이는 세션 값 테스트 코드라고 했는데, rerun 사이사이에 value들을 (영원히 저장하는 게 아니므로) share하는 코드이다. 

import streamlit as st
input_var = st.text_input("enter a name")
st.write(f"Hello, {input_var}!")
if ("name" not in st.session_state) and (input_var != ""):
 st.session_state["name"] = input_var
st.write("first name you have entered: ")
if "name" in st.session_state:
 st.write(st.session_state["name"])
st.write(st.session_state)

 

# input widget 세션 값 변경 테스트 코드
import streamlit as st
input_select = st.selectbox("select a food", 
 options= ("sushi", "steak","burger"),
 key="food")
st.write(st.session_state)