Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,104 +1,80 @@
|
|
1 |
import streamlit as st
|
2 |
import pandas as pd
|
|
|
3 |
import requests
|
4 |
-
import plotly.express as px
|
5 |
-
import plotly.graph_objects as go
|
6 |
import io
|
|
|
7 |
|
8 |
-
#
|
9 |
-
theme = px.colors.qualitative.Bold
|
10 |
-
|
11 |
-
# Function to download and load CSV data
|
12 |
def download_and_load_csv(url):
|
13 |
response = requests.get(url)
|
14 |
response.encoding = 'utf-8'
|
15 |
df = pd.read_csv(io.StringIO(response.text), encoding='utf-8')
|
16 |
-
|
|
|
|
|
17 |
return df
|
18 |
|
19 |
-
#
|
20 |
-
def
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
#
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
st.subheader(f"{df_name} 餅圖")
|
49 |
-
# 分組並計算總排放量
|
50 |
-
total_emissions = df.groupby("公司名稱")[selected_columns].sum().reset_index()
|
51 |
-
total_emissions = total_emissions.melt(id_vars=["公司名稱"], value_vars=selected_columns, var_name="Emission Type", value_name="Total Emissions")
|
52 |
-
# 創建餅圖
|
53 |
-
fig_pie = px.pie(total_emissions, values='Total Emissions', names='公司名稱',
|
54 |
-
title=f"{df_name} 各公司排放量的餅圖",
|
55 |
-
color_discrete_sequence=theme, hole=0.3)
|
56 |
-
fig_pie.update_traces(textposition='inside', textinfo='percent+label')
|
57 |
-
fig_pie = beautify_chart(fig_pie)
|
58 |
-
st.plotly_chart(fig_pie)
|
59 |
-
|
60 |
-
if len(selected_columns) >= 2:
|
61 |
-
st.subheader(f"{df_name} 散點圖")
|
62 |
-
fig_scatter = px.scatter(df, x="公司名稱", y=selected_columns,
|
63 |
-
title=f"{df_name} 散點圖", color_discrete_sequence=theme)
|
64 |
-
fig_scatter = beautify_chart(fig_scatter)
|
65 |
-
st.plotly_chart(fig_scatter)
|
66 |
-
|
67 |
-
# URLs for the CSV files
|
68 |
urls = [
|
69 |
"https://mopsfin.twse.com.tw/opendata/t187ap46_L_1.csv",
|
70 |
"https://mopsfin.twse.com.tw/opendata/t187ap46_O_2.csv",
|
71 |
"https://mopsfin.twse.com.tw/opendata/t187ap46_L_6.csv"
|
72 |
]
|
73 |
|
74 |
-
#
|
75 |
-
|
76 |
|
77 |
-
#
|
78 |
-
|
79 |
|
80 |
-
#
|
81 |
-
st.
|
|
|
82 |
|
83 |
-
#
|
84 |
-
st.subheader("
|
85 |
-
st.dataframe(combined_df)
|
86 |
|
87 |
-
#
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
-
#
|
95 |
-
|
96 |
-
|
97 |
-
if st.button(f"顯示 {column}"):
|
98 |
-
selected_columns.append(column)
|
99 |
-
|
100 |
-
# Generate plots for the selected emission categories
|
101 |
-
if selected_columns:
|
102 |
-
generate_plots(combined_df, "Combined Data", selected_columns)
|
103 |
-
else:
|
104 |
-
st.write("請選擇至少一個排放類別來顯示圖表。")
|
|
|
1 |
import streamlit as st
|
2 |
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
import requests
|
|
|
|
|
5 |
import io
|
6 |
+
import plotly.express as px
|
7 |
|
8 |
+
# 下載 CSV 數據
|
|
|
|
|
|
|
9 |
def download_and_load_csv(url):
|
10 |
response = requests.get(url)
|
11 |
response.encoding = 'utf-8'
|
12 |
df = pd.read_csv(io.StringIO(response.text), encoding='utf-8')
|
13 |
+
|
14 |
+
# 清理欄位名稱
|
15 |
+
df.columns = df.columns.str.strip().str.replace("\n", "").str.replace("\r", "")
|
16 |
return df
|
17 |
|
18 |
+
# 清理數據並合併
|
19 |
+
def clean_and_merge_data(urls):
|
20 |
+
dfs = [download_and_load_csv(url) for url in urls]
|
21 |
+
combined_df = pd.concat(dfs, ignore_index=True)
|
22 |
+
|
23 |
+
# 指定要清理的排放量欄位
|
24 |
+
emission_columns = ["範疇一排放量(噸CO2e)", "範疇二排放量(噸CO2e)", "範疇三排放量(噸CO2e)"]
|
25 |
+
|
26 |
+
# 確保所有欄位名稱都乾淨
|
27 |
+
combined_df.columns = combined_df.columns.str.strip().str.replace("\n", "").str.replace("\r", "")
|
28 |
+
|
29 |
+
# 檢查是否有缺失欄位
|
30 |
+
missing_columns = [col for col in emission_columns if col not in combined_df.columns]
|
31 |
+
if missing_columns:
|
32 |
+
st.write(f"❌ 找不到這些欄位: {missing_columns}")
|
33 |
+
return combined_df # 直接返回原始數據,避免程式崩潰
|
34 |
+
|
35 |
+
# 只清理 emission_columns 內的 0 值,不影響其他欄位
|
36 |
+
combined_df[emission_columns] = combined_df[emission_columns].replace(0, np.nan).dropna(subset=emission_columns)
|
37 |
+
|
38 |
+
# 依據 "公司名稱" 進行合併,將相同公司名稱的數據進行加總
|
39 |
+
merged_df = combined_df.groupby("公司名稱", as_index=False).sum()
|
40 |
+
|
41 |
+
# 刪除包含 NaN 或 None 的列
|
42 |
+
merged_df = merged_df.dropna()
|
43 |
+
|
44 |
+
return merged_df
|
45 |
+
|
46 |
+
# CSV 來源
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
urls = [
|
48 |
"https://mopsfin.twse.com.tw/opendata/t187ap46_L_1.csv",
|
49 |
"https://mopsfin.twse.com.tw/opendata/t187ap46_O_2.csv",
|
50 |
"https://mopsfin.twse.com.tw/opendata/t187ap46_L_6.csv"
|
51 |
]
|
52 |
|
53 |
+
# 清理並合併數據
|
54 |
+
cleaned_df = clean_and_merge_data(urls)
|
55 |
|
56 |
+
# 設置 Streamlit 標題
|
57 |
+
st.title("台灣企業 ESG 數據分析與揭露")
|
58 |
|
59 |
+
# 顯示清理後的數據
|
60 |
+
st.subheader("清理 & 合併後的數據預覽")
|
61 |
+
st.dataframe(cleaned_df)
|
62 |
|
63 |
+
# 繪製動態圖表
|
64 |
+
st.subheader("ESG 排放量動��圖表")
|
|
|
65 |
|
66 |
+
# 合併三個範疇的排放量數據,並將其轉換為長格式
|
67 |
+
emission_df = cleaned_df.melt(id_vars=["公司名稱"], value_vars=["範疇一排放量(噸CO2e)", "範疇二排放量(噸CO2e)", "範疇三排放量(噸CO2e)"],
|
68 |
+
var_name="排放範疇", value_name="排放量")
|
69 |
+
|
70 |
+
# 使用 Plotly 繪製動態柱狀圖
|
71 |
+
fig = px.bar(emission_df, x="公司名稱", y="排放量", color="排放範疇", title="各公司 ESG 排放量",
|
72 |
+
labels={"排放量": "排放量 (噸CO2e)", "公司名稱": "公司名稱", "排放範疇": "排放範疇"})
|
73 |
+
|
74 |
+
# 使用 Plotly 繪製動態折線圖
|
75 |
+
fig_line = px.line(emission_df, x="公司名稱", y="排放量", color="排放範疇", title="各公司 ESG 排放量趨勢",
|
76 |
+
labels={"排放量": "排放量 (噸CO2e)", "公司名稱": "公司名稱", "排放範疇": "排放範疇"})
|
77 |
|
78 |
+
# 顯示圖表
|
79 |
+
st.plotly_chart(fig)
|
80 |
+
st.plotly_chart(fig_line)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|