evo / app.py
Rozeeeee's picture
Update app.py
599218b verified
Raw
History Blame
4.04 kB
import streamlit as st
import pandas as pd
import requests
import plotly.express as px
import io
# 設置顏色主題
theme = px.colors.qualitative.Bold
# 下載並載入 CSV 數據
def download_and_load_csv(url):
response = requests.get(url)
response.encoding = 'utf-8'
df = pd.read_csv(io.StringIO(response.text), encoding='utf-8')
df = df.fillna(0) # 避免 NaN 錯誤
return df
# 美化圖表
def beautify_chart(fig):
fig.update_layout(
font_family="Arial",
font_color="#444",
title_font_family="Arial",
title_font_color="#000",
legend_title_font_color="#000",
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
)
fig.update_xaxes(showline=True, linewidth=2, linecolor='lightgray', gridcolor='lightgray')
fig.update_yaxes(showline=True, linewidth=2, linecolor='lightgray', gridcolor='lightgray')
return fig
# **生成 Plotly 圖表**
def generate_plots(df, df_name, selected_columns, chart_type):
selected_columns = list(selected_columns) # 確保是列表
if not selected_columns:
st.error("❌ 沒有選擇數據欄位,請至少選擇一個!")
return
if "公司名稱" not in df.columns:
st.error("❌ 缺少 `公司名稱` 欄位,請確認數據格式!")
return
# ✅ **確保所有 y 軸數據與 x 軸 (公司名稱) 長度一致**
valid_columns = [col for col in selected_columns if col in df.columns and len(df[col]) == len(df["公司名稱"])]
if not valid_columns:
st.error("❌ 選擇的欄位長度與 `公司名稱` 不匹配,請檢查數據!")
return
with st.expander(f"📊 顯示 {df_name} 圖表"):
st.subheader(f"{df_name} - {chart_type} 圖")
# **根據選擇的圖表類型來繪製**
if chart_type == "折線圖":
fig = px.line(df, x="公司名稱", y=valid_columns, title=f"{df_name} - 折線圖", color_discrete_sequence=theme)
elif chart_type == "散點圖":
fig = px.scatter(df, x="公司名稱", y=valid_columns, title=f"{df_name} - 散點圖", color_discrete_sequence=theme)
elif chart_type == "長條圖":
fig = px.bar(df, x="公司名稱", y=valid_columns, title=f"{df_name} - 長條圖", color_discrete_sequence=theme)
elif chart_type == "餅圖":
total_emissions = df.groupby("公司名稱")[valid_columns].sum().reset_index()
total_emissions = total_emissions.melt(id_vars=["公司名稱"], value_vars=valid_columns, var_name="排放類型", value_name="總排放量")
fig = px.pie(total_emissions, values='總排放量', names='公司名稱', title=f"{df_name} - 餅圖", color_discrete_sequence=theme, hole=0.3)
fig.update_traces(textposition='inside', textinfo='percent+label')
fig = beautify_chart(fig)
st.plotly_chart(fig, use_container_width=True) # ✅ **讓圖表自適應畫面**
# **下載數據**
urls = [
"https://mopsfin.twse.com.tw/opendata/t187ap46_L_1.csv",
"https://mopsfin.twse.com.tw/opendata/t187ap46_O_2.csv",
"https://mopsfin.twse.com.tw/opendata/t187ap46_L_6.csv"
]
dfs = [download_and_load_csv(url) for url in urls]
combined_df = pd.concat(dfs, ignore_index=True)
# **Streamlit UI**
st.title("📊 台灣企業 ESG 數據分析")
st.subheader("📂 數據預覽")
st.dataframe(combined_df)
# **選擇數據欄位**
emission_columns = ["範疇一排放量(噸CO2e)", "範疇二排放量(噸CO2e)", "範疇三排放量(噸CO2e)"]
selected_columns = st.multiselect("選擇要顯示的排放類別", emission_columns, default=emission_columns[:1])
# **選擇圖表類型**
chart_type = st.selectbox("選擇圖表類型", ["折線圖", "散點圖", "長條圖", "餅圖"])
# **生成圖表**
if selected_columns:
generate_plots(combined_df, "綜合數據", selected_columns, chart_type)
else:
st.write("⚠️ 請選擇至少一個排放類別來顯示圖表。")