행위

"Python streamlit dashboard"의 두 판 사이의 차이

DB CAFE

(참조 사이트)
 
(같은 사용자의 중간 판 3개는 보이지 않습니다)
1번째 줄: 1번째 줄:
= 파이썬 Streamlit 대시보드 개발 =
+
== streamlit dashbaord 개발 ==
== 설치 ==
 
https://blog.zarathu.com/posts/2023-02-01-streamlit/
 
  
== 실행 방법 ==
+
=== 코드 ===
<source lang=python>
 
streamlit run test.py
 
</source>
 
 
 
== Streamlit 샘플 ==
 
* 샘플 소스
 
 
<source lang=python>
 
<source lang=python>
 
import streamlit as st
 
import streamlit as st
st.title('Hello Streamlit')
+
import plotly.express as px
</source>
+
import pandas as pd
 
+
import os
* 실행
+
import warnings
<source lang=python>
+
warnings.filterwarnings('ignore')
streamlit run app.py
 
</source>
 
 
 
== 문자열 관련 ==
 
<source lang=sql>
 
import streamlit as st
 
 
 
# 타이틀
 
st.title('this is title')
 
# 헤더
 
st.header('this is header')
 
# 서브헤더
 
st.subheader('this is subheader')
 
</source>
 
 
 
== 레이아웃 만들기 ==
 
 
 
* 레이아웃으로 웹페이지 분할
 
* columns 함수
 
 
 
<source lang=sql>
 
import streamlit as st
 
 
 
col1,col2 = st.columns([2,3])
 
# 공간을 2:3 으로 분할하여 col1과 col2 컬럼 생성. 
 
  
with col1 :
+
st.set_page_config(page_title="Superstore!!!", page_icon=":bar_chart:",layout="wide")
  # column 1 에 담을 내용
 
  st.title('here is column1')
 
with col2 :
 
  # column 2 에 담을 내용
 
  st.title('here is column2')
 
  st.checkbox('this is checkbox1 in col2 ')
 
  
 +
st.title(" :bar_chart: Sample SuperStore EDA")
 +
st.markdown('<style>div.block-container{padding-top:1rem;}</style>',unsafe_allow_html=True)
  
# with 구문 말고 다르게 사용 가능
+
fl = st.file_uploader(":file_folder: Upload a file",type=(["csv","txt","xlsx","xls"]))
col1.subheader(' i am column1  subheader !! ')
+
if fl is not None:
col2.checkbox('this is checkbox2 in col2 ')  
+
    filename = fl.name
# => 위에 with col2: 안의 내용과 같은 기능
+
    st.write(filename)
</source>
+
    df = pd.read_csv(filename, encoding = "ISO-8859-1")
 +
else:
 +
    os.chdir(r"C:\Users\AEPAC\Desktop\Streamlit")
 +
    df = pd.read_csv("Superstore.csv", encoding = "ISO-8859-1")
  
 +
col1, col2 = st.columns((2))
 +
df["Order Date"] = pd.to_datetime(df["Order Date"])
  
github repository: https://github.com/streamlit/streamlit
+
# Getting the min and max date
tutorial: https://docs.streamlit.io/en/stable/getting_started.html
+
startDate = pd.to_datetime(df["Order Date"]).min()
+
endDate = pd.to_datetime(df["Order Date"]).max()
streamlit는 파이썬 기반으로 손쉽게 웹 어플리케이션을 개발하는 오픈소스입니다. 웹에 대한 이해 없이도 간단한 파이썬 코드만으로 대부분의 웹 어플리케이션 구현이 가능합니다. 간단한 데이터 Visualization 혹은 인공지능 모델 시연 등 여러 분야에 활용될 수 있을 것 같습니다.
 
 
 
Installation
 
 
- Install command
 
$ pip install streamlit
 
$ streamlit hello
 
  👋 Welcome to Streamlit!
 
  
  If you're one of our development partners or you're interested in getting
+
with col1:
  personal technical support or Streamlit updates, please enter your email
+
    date1 = pd.to_datetime(st.date_input("Start Date", startDate))
  address below. Otherwise, you may leave the field blank.
 
  
  Email: sh951011@gmail.com
+
with col2:
 +
    date2 = pd.to_datetime(st.date_input("End Date", endDate))
  
  Privacy Policy:
+
df = df[(df["Order Date"] >= date1) & (df["Order Date"] <= date2)].copy()
  As an open source project, we collect usage statistics. We cannot see and do
 
  not store information contained in Streamlit apps. You can find out more by
 
  reading our privacy policy at: https://streamlit.io/privacy-policy
 
  
  If you'd like to opt out of usage statistics, add the following to
+
st.sidebar.header("Choose your filter: ")
  ~/.streamlit/config.toml, creating that file if necessary:
+
# Create for Region
 +
region = st.sidebar.multiselect("Pick your Region", df["Region"].unique())
 +
if not region:
 +
    df2 = df.copy()
 +
else:
 +
    df2 = df[df["Region"].isin(region)]
  
    [browser]
+
# Create for State
     gatherUsageStats = false
+
state = st.sidebar.multiselect("Pick the State", df2["State"].unique())
 +
if not state:
 +
    df3 = df2.copy()
 +
else:
 +
     df3 = df2[df2["State"].isin(state)]
  
 +
# Create for City
 +
city = st.sidebar.multiselect("Pick the City",df3["City"].unique())
  
  Welcome to Streamlit. Check out our demo in your browser.
+
# Filter the data based on Region, State and City
  
  Local URL: http://localhost:8501
+
if not region and not state and not city:
  Network URL: http://192.168.35.186:8501
+
    filtered_df = df
 +
elif not state and not city:
 +
    filtered_df = df[df["Region"].isin(region)]
 +
elif not region and not city:
 +
    filtered_df = df[df["State"].isin(state)]
 +
elif state and city:
 +
    filtered_df = df3[df["State"].isin(state) & df3["City"].isin(city)]
 +
elif region and city:
 +
    filtered_df = df3[df["Region"].isin(region) & df3["City"].isin(city)]
 +
elif region and state:
 +
    filtered_df = df3[df["Region"].isin(region) & df3["State"].isin(state)]
 +
elif city:
 +
    filtered_df = df3[df3["City"].isin(city)]
 +
else:
 +
    filtered_df = df3[df3["Region"].isin(region) & df3["State"].isin(state) & df3["City"].isin(city)]
  
  Ready to create your own Python apps super quickly?
+
category_df = filtered_df.groupby(by = ["Category"], as_index = False)["Sales"].sum()
  Head over to https://docs.streamlit.io
 
  
  May you create awesome apps!
+
with col1:
+
    st.subheader("Category wise Sales")
Get Started
+
    fig = px.bar(category_df, x = "Category", y = "Sales", text = ['${:,.2f}'.format(x) for x in category_df["Sales"]],
+
                template = "seaborn")
Create your first Streamlit app
+
    st.plotly_chart(fig,use_container_width=True, height = 200)
 
1. first_app.py를 만들고 streamlit를 import 합니다.
 
import streamlit as st
 
import pandas as pd
 
2. st.write()을 사용합니다.
 
  
st.title('My first app')
+
with col2:
st.write("Here's our first attempt at using data to create a table:")
+
    st.subheader("Region wise Sales")
st.write(pd.DataFrame({
+
    fig = px.pie(filtered_df, values = "Sales", names = "Region", hole = 0.5)
    'first column': [1, 2, 3, 4],
+
     fig.update_traces(text = filtered_df["Region"], textposition = "outside")
     'second column': [10, 20, 30, 40]
+
    st.plotly_chart(fig,use_container_width=True)
}))
 
st.write()는 str 타입뿐만 아니라 pandas의 DataFrame도 손쉽게 write 할 수 있습니다.
 
 
3. Run by streamlit
 
$ streamlit run first_app.py
 
 
여기까지만 해도 streamlit을 활용하면 상당히 편리하게 데이터를 보여줄 수 있습니다. 다음으로는 streamlit을 이용해서 데이터 visualization하는 방법에 대해 살펴보겠습니다.
 
 
Draw charts and maps
 
 
웹 어플리케이션에 bar chart, line chart, map을 추가하는 법을 대해 배워봅시다.
 
 
- Draw a line chart
 
 
파이썬에서는 matplotlib과 같은 라이브러리를 이용하면 쉽게 line chart를 그릴 수 있습니다만, 웹 어플리케이션에서 이런 이미지를 띄우려면 상황에 따라 복잡해질 수도 있습니다. 하지만 streamlit에서는 st.line_chart() 메서드로 편리하게 line chart를 추가할 수 있습니다.
 
 
chart_data = pd.DataFrame(
 
    np.random.randn(20, 3),
 
    columns=['a', 'b', 'c'])
 
  
st.line_chart(chart_data)
+
cl1, cl2 = st.columns((2))
+
with cl1:
- Plot a map
+
    with st.expander("Category_ViewData"):
+
        st.write(category_df.style.background_gradient(cmap="Blues"))
지도 역시 마찬가지입니다. 노 베이스로 지도를 그린다면 굉장히 어렵겠지만, streamlit에서는 지도 역시 st.map() 메서드로 편리하게 지원합니다.
+
        csv = category_df.to_csv(index = False).encode('utf-8')
map_data = pd.DataFrame(
+
        st.download_button("Download Data", data = csv, file_name = "Category.csv", mime = "text/csv",
    np.random.randn(1000, 2) / [50, 50] + [37.76, -122.4],
+
                            help = 'Click here to download the data as a CSV file')
    columns=['lat', 'lon'])
 
  
st.map(map_data)
+
with cl2:
+
    with st.expander("Region_ViewData"):
+
        region = filtered_df.groupby(by = "Region", as_index = False)["Sales"].sum()
Add interactivity with widgets
+
        st.write(region.style.background_gradient(cmap="Oranges"))
+
        csv = region.to_csv(index = False).encode('utf-8')
streamlit은 체크박스, 버튼, 슬라이더 등 여러 interactive 위젯 API를 제공합니다. streamlit에서 제공하는 모든 API는 여기에서 확인할 수 있습니다.
+
        st.download_button("Download Data", data = csv, file_name = "Region.csv", mime = "text/csv",
+
                        help = 'Click here to download the data as a CSV file')
- Checkbox show/hide data
+
       
+
filtered_df["month_year"] = filtered_df["Order Date"].dt.to_period("M")
st.checkbox()를 이용하면 체크박스를 이용해서 데이터 show/hide 설정을 할 수 있습니다. st.checkbox()는 위젯명을 argument로 받아서 처리합니다.
+
st.subheader('Time Series Analysis')
  
if st.checkbox('Show dataframe'):
+
linechart = pd.DataFrame(filtered_df.groupby(filtered_df["month_year"].dt.strftime("%Y : %b"))["Sales"].sum()).reset_index()
    chart_data = pd.DataFrame(
+
fig2 = px.line(linechart, x = "month_year", y="Sales", labels = {"Sales": "Amount"},height=500, width = 1000,template="gridon")
      np.random.randn(20, 3),
+
st.plotly_chart(fig2,use_container_width=True)
      columns=['a', 'b', 'c'])
 
  
     chart_data
+
with st.expander("View Data of TimeSeries:"):
+
     st.write(linechart.T.style.background_gradient(cmap="Blues"))
+
    csv = linechart.to_csv(index=False).encode("utf-8")
- Selectbox for options
+
    st.download_button('Download Data', data = csv, file_name = "TimeSeries.csv", mime ='text/csv')
 
st.selectbox()는 pandas.Series를 입력으로 받아서 옵션을 선택받게 할 수 있습니다.
 
import streamlit as st
 
import pandas as pd
 
  
st.title('TUNiBerse')
+
# Create a treem based on Region, category, sub-Category
option = st.selectbox(
+
st.subheader("Hierarchical view of Sales using TreeMap")
    '당신의 직책을 선택해주세요.',
+
fig3 = px.treemap(filtered_df, path = ["Region","Category","Sub-Category"], values = "Sales",hover_data = ["Sales"],
    pd.Series(['CEO', 'AI Engineer', 'Intern', 'Product Manager']))
+
                  color = "Sub-Category")
 +
fig3.update_layout(width = 800, height = 650)
 +
st.plotly_chart(fig3, use_container_width=True)
  
'You selected: ', option
+
chart1, chart2 = st.columns((2))
+
with chart1:
Lay out your app
+
    st.subheader('Segment wise Sales')
+
    fig = px.pie(filtered_df, values = "Sales", names = "Segment", template = "plotly_dark")
웹 어플리케이션을 구현할 때 중요한 점 중 하나를 레이아웃입니다. 어떻게 화면을 구성하냐에 따라서 더 깔끔하고 직관적이게 보일 수가 있습니다. streamlit은 이런 기능 또한 손쉽게 다룰 수 있습니다.
+
     fig.update_traces(text = filtered_df["Segment"], textposition = "inside")
+
    st.plotly_chart(fig,use_container_width=True)
- Selectbox를 사이드로
 
 
방금 앞에서 했던 selectbox를 사이드로 옮기고 싶다면 어떻게 해야할까요? streamlit에서는 아래와 같이 간단하게 구현 가능합니다.
 
import streamlit as st
 
import pandas as pd
 
 
 
st.title('TUNiBerse')
 
option = st.sidebar.selectbox(
 
     '당신의 직책을 선택해주세요.',
 
    pd.Series(['CEO', 'AI Engineer', 'Intern', 'Product Manager']))
 
  
'You selected: ', option
+
with chart2:
+
    st.subheader('Category wise Sales')
위와 같이 streamlit에서 제공하는 대부분의 element는 st.sidebar. [element_name]() 포맷으로 사용 가능합니다. 위의 위젯 외에도 button, expander 등 여러 위젯이 있으니 다양하게 사용해보시길 바랍니다.
+
    fig = px.pie(filtered_df, values = "Sales", names = "Category", template = "gridon")
+
    fig.update_traces(text = filtered_df["Category"], textposition = "inside")
Show progress
+
    st.plotly_chart(fig,use_container_width=True)
 
이번에는 웹페이지에 진행현황을 표시해봅시다. st.progress()를 이용하면 아래처럼 쉽게 사용이 가능합니다.
 
import time
 
  
'Starting a long computation...'
+
import plotly.figure_factory as ff
 +
st.subheader(":point_right: Month wise Sub-Category Sales Summary")
 +
with st.expander("Summary_Table"):
 +
    df_sample = df[0:5][["Region","State","City","Category","Sales","Profit","Quantity"]]
 +
    fig = ff.create_table(df_sample, colorscale = "Cividis")
 +
    st.plotly_chart(fig, use_container_width=True)
  
# Add a placeholder
+
    st.markdown("Month wise sub-Category Table")
latest_iteration = st.empty()
+
    filtered_df["month"] = filtered_df["Order Date"].dt.month_name()
bar = st.progress(0)
+
    sub_category_Year = pd.pivot_table(data = filtered_df, values = "Sales", index = ["Sub-Category"],columns = "month")
 +
    st.write(sub_category_Year.style.background_gradient(cmap="Blues"))
  
for i in range(100):
+
# Create a scatter plot
  # Update the progress bar with each iteration.
+
data1 = px.scatter(filtered_df, x = "Sales", y = "Profit", size = "Quantity")
  latest_iteration.text(f'Iteration {i+1}')
+
data1['layout'].update(title="Relationship between Sales and Profits using Scatter Plot.",
  bar.progress(i + 1)
+
                      titlefont = dict(size=20),xaxis = dict(title="Sales",titlefont=dict(size=19)),
  time.sleep(0.1)
+
                      yaxis = dict(title = "Profit", titlefont = dict(size=19)))
 +
st.plotly_chart(data1,use_container_width=True)
  
'...and now we\'re done!
+
with st.expander("View Data"):
+
    st.write(filtered_df.iloc[:500,1:20:2].style.background_gradient(cmap="Oranges"))
 
Share your app
 
 
streamlit으로 개발한 app은 Streamlit Cloud로 deploy, manage, share가 모두 가능합니다. 현재 Streamlit Cloud는 초대를 받은 멤버에 한해서 사용이 가능합니다. Request an invite에 몇 가지 사항을 제출하고 사용해주시면 됩니다.
 
 
다음 3 스텝으로 간단하게 구현 가능합니다.
 
 
1. Put your app in a public Github repo (and make sure it has a requirements.txt!)
 
2. Sign into share.streamlit.io
 
3. Click ‘Deploy an app’ and then paste in your GitHub URL
 
  
 +
# Download orginal DataSet
 +
csv = df.to_csv(index = False).encode('utf-8')
 +
st.download_button('Download Data', data = csv, file_name = "Data.csv",mime = "text/csv")
 +
</source>
  
== 참조 사이트 ==
+
=== adidas 쇼핑몰 ===
 +
* https://github.com/AbhisheakSaraswat/PythonStreamlit/blob/main/Dashboard.py
 +
=== 참조 사이트 ===
 
   
 
   
 
https://docs.kanaries.net/topics/Streamlit/streamlit-dashboard
 
https://docs.kanaries.net/topics/Streamlit/streamlit-dashboard
  
 
https://analyticsindiamag.com/ai-mysteries/build-and-deploy-your-first-real-time-dashboard-with-streamlit/
 
https://analyticsindiamag.com/ai-mysteries/build-and-deploy-your-first-real-time-dashboard-with-streamlit/
 
  
 
https://www.geeksforgeeks.org/create-interactive-dashboard-in-python-using-streamlit/
 
https://www.geeksforgeeks.org/create-interactive-dashboard-in-python-using-streamlit/

2024년 8월 26일 (월) 18:18 기준 최신판

thumb_up 추천메뉴 바로가기


1 streamlit dashbaord 개발[편집]

1.1 코드[편집]

import streamlit as st
import plotly.express as px
import pandas as pd
import os
import warnings
warnings.filterwarnings('ignore')

st.set_page_config(page_title="Superstore!!!", page_icon=":bar_chart:",layout="wide")

st.title(" :bar_chart: Sample SuperStore EDA")
st.markdown('<style>div.block-container{padding-top:1rem;}</style>',unsafe_allow_html=True)

fl = st.file_uploader(":file_folder: Upload a file",type=(["csv","txt","xlsx","xls"]))
if fl is not None:
    filename = fl.name
    st.write(filename)
    df = pd.read_csv(filename, encoding = "ISO-8859-1")
else:
    os.chdir(r"C:\Users\AEPAC\Desktop\Streamlit")
    df = pd.read_csv("Superstore.csv", encoding = "ISO-8859-1")

col1, col2 = st.columns((2))
df["Order Date"] = pd.to_datetime(df["Order Date"])

# Getting the min and max date 
startDate = pd.to_datetime(df["Order Date"]).min()
endDate = pd.to_datetime(df["Order Date"]).max()

with col1:
    date1 = pd.to_datetime(st.date_input("Start Date", startDate))

with col2:
    date2 = pd.to_datetime(st.date_input("End Date", endDate))

df = df[(df["Order Date"] >= date1) & (df["Order Date"] <= date2)].copy()

st.sidebar.header("Choose your filter: ")
# Create for Region
region = st.sidebar.multiselect("Pick your Region", df["Region"].unique())
if not region:
    df2 = df.copy()
else:
    df2 = df[df["Region"].isin(region)]

# Create for State
state = st.sidebar.multiselect("Pick the State", df2["State"].unique())
if not state:
    df3 = df2.copy()
else:
    df3 = df2[df2["State"].isin(state)]

# Create for City
city = st.sidebar.multiselect("Pick the City",df3["City"].unique())

# Filter the data based on Region, State and City

if not region and not state and not city:
    filtered_df = df
elif not state and not city:
    filtered_df = df[df["Region"].isin(region)]
elif not region and not city:
    filtered_df = df[df["State"].isin(state)]
elif state and city:
    filtered_df = df3[df["State"].isin(state) & df3["City"].isin(city)]
elif region and city:
    filtered_df = df3[df["Region"].isin(region) & df3["City"].isin(city)]
elif region and state:
    filtered_df = df3[df["Region"].isin(region) & df3["State"].isin(state)]
elif city:
    filtered_df = df3[df3["City"].isin(city)]
else:
    filtered_df = df3[df3["Region"].isin(region) & df3["State"].isin(state) & df3["City"].isin(city)]

category_df = filtered_df.groupby(by = ["Category"], as_index = False)["Sales"].sum()

with col1:
    st.subheader("Category wise Sales")
    fig = px.bar(category_df, x = "Category", y = "Sales", text = ['${:,.2f}'.format(x) for x in category_df["Sales"]],
                 template = "seaborn")
    st.plotly_chart(fig,use_container_width=True, height = 200)

with col2:
    st.subheader("Region wise Sales")
    fig = px.pie(filtered_df, values = "Sales", names = "Region", hole = 0.5)
    fig.update_traces(text = filtered_df["Region"], textposition = "outside")
    st.plotly_chart(fig,use_container_width=True)

cl1, cl2 = st.columns((2))
with cl1:
    with st.expander("Category_ViewData"):
        st.write(category_df.style.background_gradient(cmap="Blues"))
        csv = category_df.to_csv(index = False).encode('utf-8')
        st.download_button("Download Data", data = csv, file_name = "Category.csv", mime = "text/csv",
                            help = 'Click here to download the data as a CSV file')

with cl2:
    with st.expander("Region_ViewData"):
        region = filtered_df.groupby(by = "Region", as_index = False)["Sales"].sum()
        st.write(region.style.background_gradient(cmap="Oranges"))
        csv = region.to_csv(index = False).encode('utf-8')
        st.download_button("Download Data", data = csv, file_name = "Region.csv", mime = "text/csv",
                        help = 'Click here to download the data as a CSV file')
        
filtered_df["month_year"] = filtered_df["Order Date"].dt.to_period("M")
st.subheader('Time Series Analysis')

linechart = pd.DataFrame(filtered_df.groupby(filtered_df["month_year"].dt.strftime("%Y : %b"))["Sales"].sum()).reset_index()
fig2 = px.line(linechart, x = "month_year", y="Sales", labels = {"Sales": "Amount"},height=500, width = 1000,template="gridon")
st.plotly_chart(fig2,use_container_width=True)

with st.expander("View Data of TimeSeries:"):
    st.write(linechart.T.style.background_gradient(cmap="Blues"))
    csv = linechart.to_csv(index=False).encode("utf-8")
    st.download_button('Download Data', data = csv, file_name = "TimeSeries.csv", mime ='text/csv')

# Create a treem based on Region, category, sub-Category
st.subheader("Hierarchical view of Sales using TreeMap")
fig3 = px.treemap(filtered_df, path = ["Region","Category","Sub-Category"], values = "Sales",hover_data = ["Sales"],
                  color = "Sub-Category")
fig3.update_layout(width = 800, height = 650)
st.plotly_chart(fig3, use_container_width=True)

chart1, chart2 = st.columns((2))
with chart1:
    st.subheader('Segment wise Sales')
    fig = px.pie(filtered_df, values = "Sales", names = "Segment", template = "plotly_dark")
    fig.update_traces(text = filtered_df["Segment"], textposition = "inside")
    st.plotly_chart(fig,use_container_width=True)

with chart2:
    st.subheader('Category wise Sales')
    fig = px.pie(filtered_df, values = "Sales", names = "Category", template = "gridon")
    fig.update_traces(text = filtered_df["Category"], textposition = "inside")
    st.plotly_chart(fig,use_container_width=True)

import plotly.figure_factory as ff
st.subheader(":point_right: Month wise Sub-Category Sales Summary")
with st.expander("Summary_Table"):
    df_sample = df[0:5][["Region","State","City","Category","Sales","Profit","Quantity"]]
    fig = ff.create_table(df_sample, colorscale = "Cividis")
    st.plotly_chart(fig, use_container_width=True)

    st.markdown("Month wise sub-Category Table")
    filtered_df["month"] = filtered_df["Order Date"].dt.month_name()
    sub_category_Year = pd.pivot_table(data = filtered_df, values = "Sales", index = ["Sub-Category"],columns = "month")
    st.write(sub_category_Year.style.background_gradient(cmap="Blues"))

# Create a scatter plot
data1 = px.scatter(filtered_df, x = "Sales", y = "Profit", size = "Quantity")
data1['layout'].update(title="Relationship between Sales and Profits using Scatter Plot.",
                       titlefont = dict(size=20),xaxis = dict(title="Sales",titlefont=dict(size=19)),
                       yaxis = dict(title = "Profit", titlefont = dict(size=19)))
st.plotly_chart(data1,use_container_width=True)

with st.expander("View Data"):
    st.write(filtered_df.iloc[:500,1:20:2].style.background_gradient(cmap="Oranges"))

# Download orginal DataSet
csv = df.to_csv(index = False).encode('utf-8')
st.download_button('Download Data', data = csv, file_name = "Data.csv",mime = "text/csv")