Spaces:
Build error
Build error
| 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("⚠️ 請選擇至少一個排放類別來顯示圖表。") | |