Lashtw commited on
Commit
21b1ca2
·
verified ·
1 Parent(s): e91108c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -100
app.py CHANGED
@@ -4,100 +4,16 @@ import plotly.graph_objects as go
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
11
  import shutil
12
- import subprocess
13
- import tarfile
14
- import requests
15
 
16
  try:
17
  import kaleido
18
  except ImportError:
19
  st.error("請安裝 'kaleido' 套件以啟用圖像導出功能:\n\n $ pip install kaleido")
20
 
21
- # 自動下載 orca
22
- if not os.path.exists("/usr/local/bin/orca"):
23
- if not os.path.exists("orca.tar.gz"):
24
- try:
25
- st.write("Downloading orca...")
26
-
27
- # 使用最新的 orca 下載連結
28
- orca_url = "https://github.com/plotly/orca/releases/download/v1.3.1/orca-1.3.1-x86_64.tar.gz"
29
-
30
- response = requests.get(orca_url, stream=True)
31
- response.raise_for_status() # 檢查下載是否成功
32
- with open("orca.tar.gz", "wb") as f:
33
- for chunk in response.iter_content(chunk_size=8192):
34
- f.write(chunk)
35
- st.write("Orca download completed.")
36
- except requests.exceptions.RequestException as e:
37
- st.error(f"Orca download failed: {e}")
38
- st.stop()
39
-
40
- try:
41
- if not os.path.exists("orca.tar.gz"):
42
- st.write("Orca file does not exist, redownloading")
43
- response = requests.get(orca_url, stream=True)
44
- response.raise_for_status()
45
- with open("orca.tar.gz", "wb") as f:
46
- for chunk in response.iter_content(chunk_size=8192):
47
- f.write(chunk)
48
-
49
- st.write("Checking orca.tar.gz file size...")
50
- file_size = os.path.getsize("orca.tar.gz")
51
- st.write(f"Orca file size is {file_size} bytes")
52
-
53
- if file_size < 1000000: # 任意設定一個最小檔案大小,防止網路錯誤檔案下載過小
54
- st.error("Orca file size is too small, try to redownload")
55
- os.remove("orca.tar.gz") #刪除壞掉的檔案
56
- response = requests.get(orca_url, stream=True)
57
- response.raise_for_status()
58
- with open("orca.tar.gz", "wb") as f:
59
- for chunk in response.iter_content(chunk_size=8192):
60
- f.write(chunk)
61
-
62
- st.write("Extracting orca...")
63
- with tarfile.open("orca.tar.gz", "r:gz") as tar:
64
- tar.extractall()
65
- st.write("Orca extraction completed.")
66
- except Exception as e:
67
- st.error(f"Orca extraction failed: {e}")
68
- st.stop()
69
-
70
- try:
71
- # 檢查 orca 執行檔的位置
72
- orca_dir = "orca-1.3.1-x86_64"
73
- if not os.path.exists(orca_dir):
74
- st.error(f"Orca directory does not exist {orca_dir}")
75
- st.stop()
76
-
77
-
78
-
79
- for root, dirs, files in os.walk(orca_dir):
80
- if "orca" in files:
81
- orca_path = os.path.join(root, "orca")
82
- st.write(f"Found orca at {orca_path}")
83
- break
84
- else:
85
- st.error("Cannot find orca binary")
86
- st.stop()
87
-
88
- st.write(f"Moving orca binary from {orca_path} to /usr/local/bin/orca")
89
- shutil.move(orca_path, "/usr/local/bin/orca")
90
- st.write("Orca binary moved.")
91
-
92
- st.write("Setting execute permissions for orca...")
93
- os.chmod("/usr/local/bin/orca", 0o755)
94
- st.write("Orca permissions set.")
95
-
96
- except Exception as e:
97
- st.error(f"Orca installation failed: {e}")
98
- st.stop()
99
- st.write("Orca installation completed.")
100
-
101
  def load_data(uploaded_file):
102
  """載入並處理CSV檔案"""
103
  try:
@@ -144,15 +60,15 @@ def create_radar_chart(df, selected_rows, selected_columns):
144
  radialaxis=dict(
145
  visible=True,
146
  range=[0, df[selected_columns].values.max() * 1.1],
147
- tickfont=dict(size=12, color='black')
148
  ),
149
  angularaxis=dict(
150
- tickfont=dict(size=16, color='black')
151
  )
152
  ),
153
  showlegend=True,
154
  legend=dict(
155
- font=dict(size=14, color='black')
156
  ),
157
  title='學生成績雷達圖',
158
  plot_bgcolor='white',
@@ -162,30 +78,46 @@ def create_radar_chart(df, selected_rows, selected_columns):
162
 
163
  return fig
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  def save_all_radar_charts(df, selected_columns, comparison_rows):
166
  """批次生成並儲存每個學生與指定比較對象的雷達圖"""
167
  output_dir = "radar_charts"
168
  os.makedirs(output_dir, exist_ok=True)
169
 
 
170
  for student in df['姓名']:
171
  if student in comparison_rows:
172
  continue
173
 
174
  fig = create_radar_chart(df, [student] + comparison_rows, selected_columns)
175
- img_bytes = pio.to_image(fig, format="png", engine="orca") # 使用 orca
176
- img = Image.open(BytesIO(img_bytes)).convert("RGBA")
177
- background = Image.new('RGBA', img.size, (255, 255, 255, 255))
178
- composite = Image.alpha_composite(background, img)
179
- draw = ImageDraw.Draw(composite)
180
-
181
- # 手動繪製圖表標籤文字
182
- for trace in fig.data:
183
- if isinstance(trace, go.Scatterpolar):
184
- for i, theta in enumerate(trace.theta):
185
- x, y = fig.layout.polar.radialaxis.range[1] * (0.5 - 0.5*trace.r[i] / fig.layout.polar.radialaxis.range[1]) * np.cos(np.radians(90-theta)), fig.layout.polar.radialaxis.range[1] * (0.5 - 0.5*trace.r[i] / fig.layout.polar.radialaxis.range[1]) * np.sin(np.radians(90-theta))
186
- draw.text((img.width / 2 + x, img.height / 2 + y - 25), str(trace.name), fill=(0, 0, 0)) # 直接使用PIL預設字型
187
  file_path = os.path.join(output_dir, f"{student}_comparison.png")
188
- composite.save(file_path)
 
189
 
190
  # 壓縮所有圖表
191
  zip_path = "radar_charts.zip"
 
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
10
  import shutil
 
 
 
11
 
12
  try:
13
  import kaleido
14
  except ImportError:
15
  st.error("請安裝 'kaleido' 套件以啟用圖像導出功能:\n\n $ pip install kaleido")
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  def load_data(uploaded_file):
18
  """載入並處理CSV檔案"""
19
  try:
 
60
  radialaxis=dict(
61
  visible=True,
62
  range=[0, df[selected_columns].values.max() * 1.1],
63
+ tickfont=dict(size=12, color='black', family="Microsoft JhengHei, Noto Sans CJK, Arial")
64
  ),
65
  angularaxis=dict(
66
+ tickfont=dict(size=16, color='black', family="Microsoft JhengHei, Noto Sans CJK, Arial")
67
  )
68
  ),
69
  showlegend=True,
70
  legend=dict(
71
+ font=dict(size=14, color='black', family="Microsoft JhengHei, Noto Sans CJK, Arial")
72
  ),
73
  title='學生成績雷達圖',
74
  plot_bgcolor='white',
 
78
 
79
  return fig
80
 
81
+ def apply_font_to_all_text(fig):
82
+ """強制設定圖表內所有文字元素的字型"""
83
+ for trace in fig.data:
84
+ if hasattr(trace, 'textfont'):
85
+ trace.textfont.family = "Microsoft JhengHei, Noto Sans CJK, Arial"
86
+ if hasattr(trace, 'marker') and hasattr(trace.marker, 'textfont'):
87
+ trace.marker.textfont.family = "Microsoft JhengHei, Noto Sans CJK, Arial"
88
+ fig.update_layout(
89
+ font=dict(
90
+ family="Microsoft JhengHei, Noto Sans CJK, Arial"
91
+ )
92
+ )
93
+
94
+ if hasattr(fig, 'layout') and hasattr(fig.layout, 'xaxis'):
95
+ fig.layout.xaxis.tickfont.family = "Microsoft JhengHei, Noto Sans CJK, Arial"
96
+ if hasattr(fig, 'layout') and hasattr(fig.layout, 'yaxis'):
97
+ fig.layout.yaxis.tickfont.family = "Microsoft JhengHei, Noto Sans CJK, Arial"
98
+ if hasattr(fig, 'layout') and hasattr(fig.layout, 'polar') and hasattr(fig.layout.polar, 'radialaxis'):
99
+ fig.layout.polar.radialaxis.tickfont.family = "Microsoft JhengHei, Noto Sans CJK, Arial"
100
+ if hasattr(fig, 'layout') and hasattr(fig.layout, 'polar') and hasattr(fig.layout.polar, 'angularaxis'):
101
+ fig.layout.polar.angularaxis.tickfont.family = "Microsoft JhengHei, Noto Sans CJK, Arial"
102
+
103
+ return fig
104
+
105
+
106
  def save_all_radar_charts(df, selected_columns, comparison_rows):
107
  """批次生成並儲存每個學生與指定比較對象的雷達圖"""
108
  output_dir = "radar_charts"
109
  os.makedirs(output_dir, exist_ok=True)
110
 
111
+
112
  for student in df['姓名']:
113
  if student in comparison_rows:
114
  continue
115
 
116
  fig = create_radar_chart(df, [student] + comparison_rows, selected_columns)
117
+ fig = apply_font_to_all_text(fig)
 
 
 
 
 
 
 
 
 
 
 
118
  file_path = os.path.join(output_dir, f"{student}_comparison.png")
119
+ fig.write_image(file_path, engine="kaleido")
120
+
121
 
122
  # 壓縮所有圖表
123
  zip_path = "radar_charts.zip"