Spaces:
Sleeping
Sleeping
import os | |
import requests | |
import pandas as pd | |
import plotly.express as px | |
import streamlit as st | |
import matplotlib as mpl | |
import matplotlib.font_manager as fm | |
from io import StringIO | |
# 設定 Streamlit 頁面 | |
st.set_page_config(page_title="ESG & 董事席次數據分析", layout="wide") | |
# 安裝自訂字型 | |
def install_custom_font(): | |
font_path = "TaipeiSansTCBeta-Regular.ttf" | |
if not os.path.exists(font_path): | |
font_url = "https://drive.google.com/uc?id=1eGAsTN1HBpJAkeVM57_C7ccp7hbgSz3_&export=download" | |
font_response = requests.get(font_url) | |
with open(font_path, "wb") as font_file: | |
font_file.write(font_response.content) | |
fm.fontManager.addfont(font_path) | |
mpl.rc('font', family='Taipei Sans TC Beta') | |
# 執行字型安裝 | |
install_custom_font() | |
# 下載 ESG 與 董事席次 CSV 資料 | |
esg_url = "https://mopsfin.twse.com.tw/opendata/t187ap46_L_1.csv" | |
board_url = "https://mopsfin.twse.com.tw/opendata/t187ap46_L_6.csv" | |
def load_data(url): | |
response = requests.get(url) | |
if response.status_code == 200: | |
data = response.content.decode("utf-8-sig") | |
df = pd.read_csv(StringIO(data)) | |
df.fillna(0, inplace=True) # 填補缺失值 | |
return df | |
else: | |
st.error("無法獲取資料,錯誤代碼: " + str(response.status_code)) | |
return None | |
# 加載數據 | |
df_esg = load_data(esg_url) | |
df_board = load_data(board_url) | |
# Streamlit 標題 | |
st.title("📊 ESG & 董事席次數據分析儀表板") | |
# 選擇數據類型 | |
data_option = st.sidebar.radio("📂 選擇數據類型", ["ESG 數據", "董事席次數據"]) | |
if data_option == "ESG 數據" and df_esg is not None: | |
st.subheader("📌 ESG 數據預覽") | |
st.write(df_esg.head(10)) | |
elif data_option == "董事席次數據" and df_board is not None: | |
st.subheader("📌 董事席次數據預覽") | |
st.write(df_board.head(10)) | |
# 添加數據篩選 | |
df = df_esg if data_option == "ESG 數據" else df_board | |
filter_col = st.sidebar.selectbox("選擇要篩選的欄位", df.columns) | |
unique_values = df[filter_col].unique() | |
selected_value = st.sidebar.selectbox("選擇篩選值", unique_values) | |
filtered_df = df[df[filter_col] == selected_value] | |
st.write(filtered_df.head()) | |
# 確保數據包含數值型欄位 | |
if 'filtered_df' in locals() and filtered_df is not None: | |
numeric_cols = filtered_df.select_dtypes(include=['number']).columns | |
if len(numeric_cols) > 0: | |
col_choice = st.selectbox("選擇要視覺化的數值欄位", numeric_cols) | |
if st.button("生成圖表"): | |
# 繪製長條圖 | |
st.subheader("📊 長條圖") | |
fig_bar = px.bar(filtered_df.head(10), x=filtered_df.index[:10], y=col_choice, | |
title=f"{col_choice} 長條圖", color_discrete_sequence=["#1f77b4"]) | |
st.plotly_chart(fig_bar, use_container_width=True) | |
# 繪製圓餅圖 | |
st.subheader("🥧 圓餅圖") | |
fig_pie = px.pie(filtered_df.head(10), names=filtered_df.index[:10], values=col_choice, | |
title=f"{col_choice} 圓餅圖") | |
st.plotly_chart(fig_pie, use_container_width=True) | |