data_journalism / app.py
jonghhhh's picture
Update app.py
0f3dda5 verified
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import pandas_bokeh
# ๊ธ€ ์“ฐ๊ธฐ(๋งํฌ ์‚ฝ์ž…)
st.title('๊ฒฝํฌ๋Œ€ ์ธ๊ทผ ๊ฐ€์„ฑ๋น„ ์ข‹์€ ๋ง›์ง‘ ๋Š˜์–ด ... ๊ฑด๊ฐ•์‹์€ "๊ธ€์Ž„"')
st.header('๋Œ€ํ•™์ƒ ๋Œ€์ƒ ์ €๋ ดํ•˜๊ณ  ๋ง›์žˆ๋Š” ์Œ์‹์  ์ธ๊ธฐ')
st.subheader('๋ถ„์‹, ์ค‘์‹, ํ•œ์‹์— ์ผ์‹๊นŒ์ง€ ๋‹ค์–‘ํ•œ ์Œ์‹ ์‹ธ๊ฒŒ ์ œ๊ณต')
st.subheader('์ถ•์ œ ํ–‰์‚ฌ์— ํ–„๋ฒ„๊ฑฐ-ํ•ซ๋„๊ทธ ํ‘ธ๋“œํŠธ๋Ÿญ๋„ ๋“ฑ์žฅ')
st.write('''๊ฒฝํฌ๋Œ€ ์ธ๊ทผ์—๋Š” ์ตœ๊ทผ ๊ฐ€์„ฑ๋น„ ์ข‹์€ ๋ง›์ง‘๋“ค์ด ์†์† ๋“ค์–ด์„œ๋ฉฐ ํ•™์ƒ๋“ค ์‚ฌ์ด์—์„œ ์ธ๊ธฐ๋ฅผ ๋Œ๊ณ  ์žˆ๋‹ค. ํ•œ์ •๋œ ๋Œ€ํ•™์ƒ ์ง€๊ฐ‘์‚ฌ์ •์— ๋งž๋Š” ์ €๋ ดํ•œ ๊ฐ€๊ฒฉ๊ณผ ๋‹ค์–‘ํ•˜๊ณ  ํ€„๋ฆฌํ‹ฐ ๋†’์€ ๋ฉ”๋‰ด๋กœ ์ž…์†Œ๋ฌธ์ด ๋‚˜๋ฉด์„œ ์„ฑ์—… ์ค‘์ธ ๊ฒƒ์ด๋‹ค.
์ด์ฒ˜๋Ÿผ ๊ฒฝํฌ๋Œ€ ์ฃผ๋ณ€์—๋Š” ํ•™์ƒ๋“ค ์‚ฌ์ด์—์„œ ์ž…์†Œ๋ฌธ์ด ์ž์žํ•œ ๊ฐ€์„ฑ๋น„ ๋ง›์ง‘๋“ค์ด ๋งŽ๋‹ค. ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋Œ€ํ•™ ์ถ•์ œ ๋•Œ๋ฉด ๋‹ค์–‘ํ•œ [ํ‘ธ๋“œํŠธ๋Ÿญ](https://namu.wiki/w/%ED%91%B8%EB%93%9C%20%ED%8A%B8%EB%9F%AD)๋“ค๋„ ์ฐพ์•„์™€ ์ €๋ ดํ•˜๊ณ  ๋ง›์žˆ๋Š” ๋ฉ”๋‰ด๋ฅผ ์„ ๋ณด์ด๋ฉฐ ํฐ ์ธ๊ธฐ๋ฅผ ๋ˆ๋‹ค.
์ตœ๊ทผ ๋ฌผ๊ฐ€์ƒ์Šน์œผ๋กœ ์ธํ•ด ์™ธ ๋ถ€๋‹ด์ด ํฐ ๋Œ€ํ•™์ƒ๋“ค์—๊ฒŒ ์ด๋Ÿฐ ๊ฐ€์„ฑ๋น„ ๋†’์€ ๋ง›์ง‘๊ณผ ํ‘ธ๋“œํŠธ๋Ÿญ์€ ํ™˜์˜๋ฐ›์„ ๋งŒํ•˜๋‹ค.''' )
# ์‚ฌ์ง„ ์‚ฝ์ž…
st.image('photo1.jpg', caption='์ง€๋‚œ 4์›”20์ผ ๊ฒฝํฌ๋Œ€ ๊ต๋‚ด์—์„œ ํ•™์ƒ๋“ค์ด ํ‘ธ๋“œํŠธ๋Ÿญ์—์„œ ์Œ์‹์„ ๊ตฌ๋งคํ•˜๊ณ  ์žˆ๋‹ค')
st.image('photo2.jpg', caption='๊ฒฝํฌ๋Œ€ ๊ทผ์ฒ˜ ๋ง›์ง‘ ์ง€๋„(--- ์ œ๊ณต)')
st.header('์‹ผ ๊ฒŒ ๋น„์ง€๋–ก? ๊ฑด๊ฐ•์‹์€ "์•ˆ ๋ณด์ด๋„ค"')
st.subheader('์ €๋ ดํ•˜๊ณ  ํ‘ธ์งํ•˜์ง€๋งŒ ์˜์–‘๊ณผ ๊ฑด๊ฐ•์€ ์‹ค์ข…')
st.subheader('"๋Œ€ํ•™๊ฐ€ ๋จน๊ฑฐ๋ฆฌ, ๊ฑด๊ฐ•์˜ ๊ท ํ˜•์„ ์žก์•„์•ผ ํ•  ๋•Œ"')
st.write('''๊ฒฝํฌ๋Œ€ ์ธ๊ทผ ๋ง›์ง‘๋“ค์˜ ๋ฉ”๋‰ด๋ฅผ ์ž์„ธํžˆ ๋ณด๋ฉด ๊ฑด๊ฐ•ํ•œ ์‹์žฌ๋ฃŒ๋‚˜ ์˜์–‘์€ ํฌ๊ฒŒ ๊ณ ๋ ค๋˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์•„ ์•„์‰ฌ์›€์ด ๋‚จ๋Š”๋‹ค.
๋Œ€ํ•™๊ฐ€์—์„œ ๊ฑด๊ฐ•์— ๋Œ€ํ•œ ๊ณ ๋ฏผ๋ณด๋‹ค ์‹ธ๊ณ  ๋ฐฐ๋ถ€๋ฅด๊ฒŒ ๋จน์„ ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด ์ธ๊ธฐ์ธ ์ ์€ ์ดํ•ด๋œ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ๋ฒˆ์ฏค์€ ์˜์–‘๊ณผ ๊ฑด๊ฐ•์„ ์ƒ๊ฐํ•ด๋ด์•ผ ํ•œ๋‹ค.
์ฒญ๋…„๋•Œ๋ถ€ํ„ฐ ๊ฑด๊ฐ•์‹์„ ์„ญ์ทจํ•˜๊ณ  ์˜ฌ๋ฐ”๋ฅธ ์‹์Šต๊ด€์„ ๊ฐ€์ ธ์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.''' )
# ๋ฐ์ดํ„ฐ ๋ณด์—ฌ์ฃผ๊ธฐ
df_แ„€แ…งแ†ผแ„’แ…ดแ„ƒแ…ขแ„†แ…กแ†บแ„Œแ…ตแ†ธ = pd.read_excel('data_blogs.xlsx', index_col=0)
st.write('์ทจ์žฌํŒ€์€ ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ทธ์—์„œ "๊ฒฝํฌ๋Œ€ ๋ง›์ง‘"์„ ๊ฒ€์ƒ‰ํ•ด ๊ธ€ 300๊ฐœ๋ฅผ ์ˆ˜์ง‘ํ–ˆ๋‹ค', df_แ„€แ…งแ†ผแ„’แ…ดแ„ƒแ…ขแ„†แ…กแ†บแ„Œแ…ตแ†ธ)
df_แ„€แ…งแ†ผแ„’แ…ดแ„ƒแ…ขแ„†แ…กแ†บแ„Œแ…ตแ†ธ_keyword = pd.read_excel('data_keywords.xlsx', index_col=0)
st.write('๋ธ”๋กœ๊ทธ ๊ธ€์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์ถœํ˜„ํ•œ ๋‹จ์–ด๋Š” ~~~ ์„ค๋ช…~~~', df_แ„€แ…งแ†ผแ„’แ…ดแ„ƒแ…ขแ„†แ…กแ†บแ„Œแ…ตแ†ธ_keyword)
# ์›Œ๋“œํด๋ผ์šฐ๋“œ
st.write('์ฃผ์š” ๋‹จ์–ด๋“ค์„ ์›Œ๋“œํด๋ผ์šฐ๋“œ๋กœ ๋ณด์—ฌ์ฃผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค')
st.image('wordcloud.png')
# ์—ฐ๊ฒฐ๋ง ๋ถ„์„
st.write('''์ทจ์žฌํŒ€์€ ์ฃผ์š” ๋‹จ์–ด๋“ค ๊ฐ„์— ๊ณต๋™์ถœํ˜„ํ•˜๋Š” ๊ด€๊ณ„๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์˜๋ฏธ์—ฐ๊ฒฐ๋ง์„ ๊ทธ๋ ค๋ณด์•˜๋‹ค.
๋ถ„์„๊ฒฐ๊ณผ, ~~์„ค๋ช…~~''')
st.image('network.png')
# ๋ฐ์ดํ„ฐ(๊ตํ†ต์‚ฌ๊ณ ) ๋ณด์—ฌ์ฃผ๊ธฐ
df_๊ตํ†ต์‚ฌ๊ณ  = pd.read_excel('data_traffic_accidents.xlsx', index_col=0)
st.write('๋‹ค์Œ ๋ฐ์ดํ„ฐ๋Š” ์ „๊ตญ์˜ ๊ตํ†ต์‚ฌ๊ณ ๋ฅผ ์ง€์—ญ๋ณ„๋กœ ์ง‘๊ณ„ํ•œ ๊ฒƒ์ด๋‹ค', df_๊ตํ†ต์‚ฌ๊ณ )
# ๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ ๋ฐ›์•„ ์ถœ๋ ฅ
query = st.text_input('์ด ๊ณณ์— ์ง€์—ญ๋ช…(์‹œ๊ตฐ๊ตฌ๋™์๋ฉด)์„ ์ž…๋ ฅํ•˜๋ฉด ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋งŒ ๊ฒ€์ƒ‰ํ•ด ๋ณด์—ฌ์ค๋‹ˆ๋‹ค', key='region1_input')
df_๊ตํ†ต์‚ฌ๊ณ ['select1']=df_๊ตํ†ต์‚ฌ๊ณ ['์‚ฌ๊ณ ์ง€์—ญ์œ„์น˜๋ช…'].apply(lambda x: 1 if query in x else 0)
st.write('๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ:', df_๊ตํ†ต์‚ฌ๊ณ [df_๊ตํ†ต์‚ฌ๊ณ ['select1']==1])
# ๊ตํ†ต์‚ฌ๊ณ  ์œ ํ˜•๊ณผ ์—ฐ๋„์— ๋”ฐ๋ฅธ pivot table ๋ณด์—ฌ์ฃผ๊ธฐ
df_๊ตํ†ต์‚ฌ๊ณ _pivot=df_๊ตํ†ต์‚ฌ๊ณ .pivot_table(index='์‚ฌ๊ณ ์œ ํ˜•๊ตฌ๋ถ„', columns='์‚ฌ๊ณ ์—ฐ๋„', values='์‚ฌ๊ณ ๊ฑด์ˆ˜', aggfunc='sum')
df_๊ตํ†ต์‚ฌ๊ณ _heatmap=df_๊ตํ†ต์‚ฌ๊ณ _pivot.style.background_gradient(cmap='Oranges').format("{:.2f}")
st.write('๋‹ค์Œ ํ‘œ๋Š” ๊ตํ†ต์‚ฌ๊ณ  ๊ฑด์ˆ˜๋ฅผ ์œ ํ˜•๊ณผ ์—ฐ๋„์— ๋”ฐ๋ผ ๊ตฌ๋ถ„ํ•œ ๊ฒƒ์ด๋‹ค', df_๊ตํ†ต์‚ฌ๊ณ _heatmap)
# ๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ ๋ฐ›์•„ pivot table ์ถœ๋ ฅ
query_pivot = st.text_input('์ด ๊ณณ์— ์ง€์—ญ๋ช…(์‹œ๊ตฐ๊ตฌ)์„ ์ž…๋ ฅํ•˜๋ฉด ๊ด€๋ จ ๋ฐ์ดํ„ฐ๋งŒ ๊ฒ€์ƒ‰ํ•ด ๋ณด์—ฌ์ค๋‹ˆ๋‹ค', key='region2_input')
df_๊ตํ†ต์‚ฌ๊ณ ['select2']=df_๊ตํ†ต์‚ฌ๊ณ ['์‚ฌ๊ณ ์ง€์—ญ์œ„์น˜๋ช…'].apply(lambda x: 1 if query_pivot in x else 0)
df_๊ตํ†ต์‚ฌ๊ณ _pivot_selected=df_๊ตํ†ต์‚ฌ๊ณ [df_๊ตํ†ต์‚ฌ๊ณ ['select2']==1].pivot_table(index='์‚ฌ๊ณ ์œ ํ˜•๊ตฌ๋ถ„', columns='์‚ฌ๊ณ ์—ฐ๋„', values='์‚ฌ๊ณ ๊ฑด์ˆ˜', aggfunc='sum')
df_๊ตํ†ต์‚ฌ๊ณ _heatmap_selected=df_๊ตํ†ต์‚ฌ๊ณ _pivot_selected.style.background_gradient(cmap='Oranges').format("{:.2f}")
st.write('๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ:', df_๊ตํ†ต์‚ฌ๊ณ _heatmap_selected)
# pandas_bokeh ๊ทธ๋ž˜ํ”„ ๋ณด์—ฌ์ฃผ๊ธฐ
st.write('์ „๊ตญ ๊ตํ†ต์‚ฌ๊ณ  ๋ฐ์ดํ„ฐ์— ๋”ฐ๋ฅด๋ฉด, ์‚ฌ๊ณ ๊ฑด์ˆ˜์™€ ์ค‘์ƒ์ž์ˆ˜๋Š” ๋ฐ€์ ‘ํ•œ ๊ด€๋ จ์„ ๋งบ๊ณ  ์žˆ๋‹ค. ~~~์„ค๋ช…~~. *๊ทธ๋ž˜ํ”„ ๋‚ด ์ ์— ์ปค์„œ๋ฅผ ๋Œ€๋ฉด ์ง€์—ญ๋ช…์ด ๋‚˜ํƒ€๋‚œ๋‹ค')
p_scatter = df_๊ตํ†ต์‚ฌ๊ณ .plot_bokeh.scatter(
x="์‚ฌ๊ณ ๊ฑด์ˆ˜",
y="์ค‘์ƒ์ž์ˆ˜",
title="์‚ฌ๊ณ ๊ฑด์ˆ˜์™€ ์ค‘์ƒ์ž์ˆ˜",
size=10,
hovertool_string="""<h6>์œ„์น˜:@{์‚ฌ๊ณ ์ง€์—ญ์œ„์น˜๋ช…}</h6>"""
)
st.bokeh_chart(p_scatter, use_container_width=True)
# ์„ ํƒํ•œ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ถœ๋ ฅ
option = st.selectbox('์—ฐ๋„๋ฅผ ์„ ํƒํ•˜๋ฉด ํ•ด๋‹น ์‹œ๊ธฐ์˜ ๊ทธ๋ž˜ํ”„๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค',
(2012, 2013, 2014, 2015, 2016, 2018, 2017, 2019, 2020, 2021), key='year_input')
p_scatter_selected = df_๊ตํ†ต์‚ฌ๊ณ [df_๊ตํ†ต์‚ฌ๊ณ ['์‚ฌ๊ณ ์—ฐ๋„']==option].plot_bokeh.scatter(
x="์‚ฌ๊ณ ๊ฑด์ˆ˜",
y="์ค‘์ƒ์ž์ˆ˜",
title="์‚ฌ๊ณ ๊ฑด์ˆ˜์™€ ์ค‘์ƒ์ž์ˆ˜",
size=10,
hovertool_string="""<h6>์œ„์น˜:@{์‚ฌ๊ณ ์ง€์—ญ์œ„์น˜๋ช…}</h6>"""
)
st.write('๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ:')
st.bokeh_chart(p_scatter_selected, use_container_width=True)