Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,6 +4,7 @@ import plotly.graph_objects as go
|
|
| 4 |
import os
|
| 5 |
from zipfile import ZipFile
|
| 6 |
import plotly.io as pio
|
|
|
|
| 7 |
from io import BytesIO
|
| 8 |
import numpy as np
|
| 9 |
import os
|
|
@@ -14,7 +15,6 @@ try:
|
|
| 14 |
except ImportError:
|
| 15 |
st.error("請安裝 'kaleido' 套件以啟用圖像導出功能:\n\n $ pip install kaleido")
|
| 16 |
|
| 17 |
-
|
| 18 |
def load_data(uploaded_file):
|
| 19 |
"""載入並處理CSV檔案"""
|
| 20 |
try:
|
|
@@ -108,7 +108,6 @@ def save_radar_chart_image(fig):
|
|
| 108 |
"""使用 kaleido 輸出 png 的記憶體檔案"""
|
| 109 |
img_bytes = pio.to_image(fig, format="png", engine="kaleido")
|
| 110 |
return img_bytes
|
| 111 |
-
|
| 112 |
def main():
|
| 113 |
st.title('學生成績雷達圖產生器')
|
| 114 |
|
|
@@ -135,77 +134,79 @@ def main():
|
|
| 135 |
|
| 136 |
st.write("### 批次下載雷達圖")
|
| 137 |
comparison_rows = st.multiselect("選擇比較對象(可多選,如班平均或區標)", df['姓名'].tolist())
|
| 138 |
-
|
| 139 |
if comparison_rows:
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
# 建立圖片核取方塊
|
| 157 |
-
image_bytes = {}
|
| 158 |
-
for student in df['姓名']:
|
| 159 |
-
if student in comparison_rows:
|
| 160 |
-
continue
|
| 161 |
-
|
| 162 |
-
fig = create_radar_chart(df, [student] + comparison_rows, selected_columns)
|
| 163 |
-
fig = apply_font_to_all_text(fig)
|
| 164 |
-
image_bytes[student] = save_radar_chart_image(fig)
|
| 165 |
-
|
| 166 |
-
# 顯示圖片
|
| 167 |
-
cols = st.columns(3) # 排成三列
|
| 168 |
-
for i, student in enumerate(image_bytes.keys()):
|
| 169 |
-
with cols[i%3]:
|
| 170 |
-
st.image(image_bytes[student],use_container_width=True)
|
| 171 |
-
try:
|
| 172 |
-
st.checkbox(f"下載 {student}", key=student, value=st.session_state.selected_images[student])
|
| 173 |
-
st.session_state.selected_images[student] = st.session_state[student] # 更新選取狀態
|
| 174 |
-
except KeyError:
|
| 175 |
-
st.session_state.selected_images[student] = False # 如果還沒有這個學生則預設為不選
|
| 176 |
-
st.checkbox(f"下載 {student}", key=student, value=st.session_state.selected_images[student])
|
| 177 |
-
st.session_state.selected_images[student] = st.session_state[student] # 更新選取狀態
|
| 178 |
-
|
| 179 |
-
#全部選取和全部不選
|
| 180 |
-
if st.button("全部選取"):
|
| 181 |
-
for student in st.session_state.selected_images:
|
| 182 |
-
st.session_state.selected_images[student] = True
|
| 183 |
-
|
| 184 |
-
if st.button("全部不選"):
|
| 185 |
-
for student in st.session_state.selected_images:
|
| 186 |
-
st.session_state.selected_images[student] = False
|
| 187 |
-
|
| 188 |
-
# 下載按鈕
|
| 189 |
-
if st.button("下載選取圖片"):
|
| 190 |
-
selected_image_bytes = []
|
| 191 |
-
for student, selected in st.session_state.selected_images.items():
|
| 192 |
-
if selected:
|
| 193 |
-
selected_image_bytes.append((student,image_bytes[student]))
|
| 194 |
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
|
| 210 |
if __name__ == "__main__":
|
| 211 |
if 'selected_images' not in st.session_state:
|
|
|
|
| 4 |
import os
|
| 5 |
from zipfile import ZipFile
|
| 6 |
import plotly.io as pio
|
| 7 |
+
from PIL import Image, ImageDraw
|
| 8 |
from io import BytesIO
|
| 9 |
import numpy as np
|
| 10 |
import os
|
|
|
|
| 15 |
except ImportError:
|
| 16 |
st.error("請安裝 'kaleido' 套件以啟用圖像導出功能:\n\n $ pip install kaleido")
|
| 17 |
|
|
|
|
| 18 |
def load_data(uploaded_file):
|
| 19 |
"""載入並處理CSV檔案"""
|
| 20 |
try:
|
|
|
|
| 108 |
"""使用 kaleido 輸出 png 的記憶體檔案"""
|
| 109 |
img_bytes = pio.to_image(fig, format="png", engine="kaleido")
|
| 110 |
return img_bytes
|
|
|
|
| 111 |
def main():
|
| 112 |
st.title('學生成績雷達圖產生器')
|
| 113 |
|
|
|
|
| 134 |
|
| 135 |
st.write("### 批次下載雷達圖")
|
| 136 |
comparison_rows = st.multiselect("選擇比較對象(可多選,如班平均或區標)", df['姓名'].tolist())
|
| 137 |
+
|
| 138 |
if comparison_rows:
|
| 139 |
+
st.write("### 選擇要下載的圖片")
|
| 140 |
+
|
| 141 |
+
# 初始化選取狀態
|
| 142 |
+
if 'selected_images' not in st.session_state:
|
| 143 |
+
st.session_state.selected_images = {student: False for student in df['姓名'] if student not in comparison_rows}
|
| 144 |
+
|
| 145 |
+
# 建立圖片核取方塊
|
| 146 |
+
image_bytes = {}
|
| 147 |
+
for student in df['姓名']:
|
| 148 |
+
if student in comparison_rows:
|
| 149 |
+
continue
|
| 150 |
+
|
| 151 |
+
fig = create_radar_chart(df, [student] + comparison_rows, selected_columns)
|
| 152 |
+
fig = apply_font_to_all_text(fig)
|
| 153 |
+
image_bytes[student] = save_radar_chart_image(fig)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
|
| 155 |
+
# 顯示圖片
|
| 156 |
+
cols = st.columns(3) # 排成三列
|
| 157 |
+
for i, student in enumerate(image_bytes.keys()):
|
| 158 |
+
with cols[i % 3]:
|
| 159 |
+
st.image(image_bytes[student], use_container_width=True)
|
| 160 |
+
|
| 161 |
+
checkbox_id = f"checkbox-{student}"
|
| 162 |
+
st.markdown(
|
| 163 |
+
f"""
|
| 164 |
+
<div style="display: flex; align-items: center;">
|
| 165 |
+
<input type="checkbox" id="{checkbox_id}" {"checked" if st.session_state.selected_images[student] else ""}>
|
| 166 |
+
<label for="{checkbox_id}" style="font-family: 'Microsoft JhengHei', 'Noto Sans CJK', Arial; font-size: 16px; margin-left: 5px;">下載 {student}</label>
|
| 167 |
+
</div>
|
| 168 |
+
""",unsafe_allow_html=True
|
| 169 |
+
)
|
| 170 |
+
|
| 171 |
+
# 更新選取狀態
|
| 172 |
+
if st.session_state.get(f"checkbox-{student}_clicked"):
|
| 173 |
+
st.session_state.selected_images[student] = not st.session_state.selected_images[student]
|
| 174 |
+
st.session_state[f"checkbox-{student}_clicked"] = False
|
| 175 |
+
|
| 176 |
+
if st.checkbox("",key=f"checkbox-{student}_clicked",label_visibility="hidden"):
|
| 177 |
+
pass
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
#全部選取和全部不選
|
| 181 |
+
if st.button("全部選取"):
|
| 182 |
+
for student in st.session_state.selected_images:
|
| 183 |
+
st.session_state.selected_images[student] = True
|
| 184 |
+
|
| 185 |
+
if st.button("全部不選"):
|
| 186 |
+
for student in st.session_state.selected_images:
|
| 187 |
+
st.session_state.selected_images[student] = False
|
| 188 |
+
|
| 189 |
+
# 下載按鈕
|
| 190 |
+
if st.button("下載選取圖片"):
|
| 191 |
+
selected_image_bytes = []
|
| 192 |
+
for student, selected in st.session_state.selected_images.items():
|
| 193 |
+
if selected:
|
| 194 |
+
selected_image_bytes.append((student,image_bytes[student]))
|
| 195 |
+
|
| 196 |
+
if selected_image_bytes:
|
| 197 |
+
zip_path = "selected_radar_charts.zip"
|
| 198 |
+
with ZipFile(zip_path, 'w') as zipf:
|
| 199 |
+
for student, img_bytes in selected_image_bytes:
|
| 200 |
+
zipf.writestr(f"{student}_comparison.png", img_bytes)
|
| 201 |
+
with open(zip_path, "rb") as f:
|
| 202 |
+
st.download_button(
|
| 203 |
+
label="下載選取圖片",
|
| 204 |
+
data=f,
|
| 205 |
+
file_name="selected_radar_charts.zip",
|
| 206 |
+
mime="application/zip"
|
| 207 |
+
)
|
| 208 |
+
else:
|
| 209 |
+
st.warning("請至少選擇一張圖片下載")
|
| 210 |
|
| 211 |
if __name__ == "__main__":
|
| 212 |
if 'selected_images' not in st.session_state:
|