YeCanming commited on
Commit
f2c0e49
·
1 Parent(s): f598a7d

feat: merge

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.png filter=lfs diff=lfs merge=lfs -text
.streamlit/config.toml CHANGED
@@ -1,6 +1,17 @@
1
  [theme]
2
- primaryColor="#F39C12"
3
- backgroundColor="#2E86C1"
4
- secondaryBackgroundColor="#7F8C8D"
5
- textColor="#FFFFFF"
6
- font="monospace"
 
 
 
 
 
 
 
 
 
 
 
 
1
  [theme]
2
+ base = "light"
3
+ baseFontSize = 15
4
+ primaryColor = "#FF5F7E"
5
+ backgroundColor = "#F9FAFB"
6
+ secondaryBackgroundColor = "#F0F4F8"
7
+ textColor = "#1F2937"
8
+ linkColor = "#2563EB"
9
+ borderColor = "#D1D5DB"
10
+ showWidgetBorder = false
11
+ baseRadius = "0.3rem"
12
+ font = "Poppins"
13
+
14
+ [theme.sidebar]
15
+ backgroundColor = "#FFFFFF"
16
+ secondaryBackgroundColor = "#F3F4F6"
17
+ borderColor = "#D1D5DB"
.streamlit/theme.toml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ theme_name = "花明 (Flowers Bright) 🌸"
2
+ theme_poem = "🌸「浅色但不苍白,明亮而不过曝,柔和中有力量」"
.streamlit/themes/antropic.toml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ theme_name = "Antropic"
2
+
3
+ [theme]
4
+ primaryColor = "#bb5a38"
5
+ backgroundColor = "#f4f3ed"
6
+ secondaryBackgroundColor = "#ecebe3"
7
+ textColor = "#3d3a2a"
8
+ linkColor = "#3d3a2a"
9
+ borderColor = "#d3d2ca"
10
+ showWidgetBorder = true
11
+ baseRadius = "0.6rem"
12
+ font = "SpaceGrotesk"
13
+ headingFont = "SpaceGroteskHeader"
14
+ codeFont = "SpaceMono"
15
+ codeBackgroundColor = "#ecebe4"
16
+ showSidebarBorder = true
17
+
18
+ [theme.sidebar]
19
+ backgroundColor = "#e8e7dd"
20
+ secondaryBackgroundColor = "#ecebe3"
.streamlit/themes/flowers_bright.toml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ theme_name = "花明 (Flowers Bright) 🌸"
2
+ theme_poem = "🌸「浅色但不苍白,明亮而不过曝,柔和中有力量」"
3
+
4
+ [theme]
5
+ base = "light"
6
+ baseFontSize = 15
7
+ primaryColor = "#FF5F7E" # 樱花粉
8
+ backgroundColor = "#F9FAFB" # 轻柔灰白
9
+ secondaryBackgroundColor = "#F0F4F8" # 卡片淡蓝灰
10
+ textColor = "#1F2937" # 蓝黑灰
11
+ linkColor = "#2563EB" # 浅蓝色链接
12
+ borderColor = "#D1D5DB" # 卡片分界线
13
+ showWidgetBorder = false
14
+ baseRadius = "0.3rem"
15
+ font = "Poppins" # 保持现代圆润感
16
+
17
+ [theme.sidebar]
18
+ backgroundColor = "#FFFFFF"
19
+ secondaryBackgroundColor = "#F3F4F6"
20
+ borderColor = "#D1D5DB"
.streamlit/themes/spotify.toml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ theme_name = "Spotify"
2
+
3
+ [theme]
4
+ base = "dark"
5
+ baseFontSize = 15
6
+ primaryColor = "#1ED760"
7
+ backgroundColor = "#121212"
8
+ secondaryBackgroundColor = "#333333"
9
+ textColor = "#FFFFFF"
10
+ linkColor = "#9D9D9D"
11
+ borderColor = "#7F7F7F"
12
+ showWidgetBorder = false
13
+ baseRadius = "0.3rem"
14
+ font = "Poppins"
15
+
16
+ [theme.sidebar]
17
+ backgroundColor = "#000000"
18
+ secondaryBackgroundColor = "#333333"
19
+ borderColor = "#696969"
.streamlit/themes/willows_dark.toml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ theme_name = "柳暗 (Willows Dark) 🌒"
2
+ theme_poem = "🌒「深而不死黑,蓝而不夺目,静而不沉闷」柳影婆娑之下,代码悄然生长。"
3
+
4
+ [theme]
5
+ base = "dark"
6
+ baseFontSize = 15
7
+ primaryColor = "#6EA8FE" # 柔和的蓝色光感
8
+ backgroundColor = "#0D1117" # 深夜蓝黑
9
+ secondaryBackgroundColor = "#1A1F2B" # 柔和灰蓝
10
+ textColor = "#D1D5DB" # 清晰柔白
11
+ linkColor = "#B8C0FF" # 柔紫蓝
12
+ borderColor = "#2E3440" # 北极灰边
13
+ showWidgetBorder = false
14
+ baseRadius = "0.3rem"
15
+ font = "JetBrains Mono" # 强科技感
16
+
17
+ [theme.sidebar]
18
+ backgroundColor = "#0A0A0A"
19
+ secondaryBackgroundColor = "#1A1A1A"
20
+ borderColor = "#2E3440"
logo.png ADDED

Git LFS Details

  • SHA256: 6184b7d0eb9265bf8928c9cd9731dec91589eb57aafc97e4d5be804bf1588f16
  • Pointer size: 132 Bytes
  • Size of remote file: 1.69 MB
src/streamlit_app.py CHANGED
@@ -1,4 +1,7 @@
1
  import streamlit as st
 
 
 
2
  from pathlib import Path
3
  import plotly.graph_objects as go
4
  import plotly.express as px
@@ -6,14 +9,18 @@ from plotly.subplots import make_subplots
6
  import pandas as pd
7
  import time
8
 
 
 
 
9
  # 导入重构后的模块
10
  try:
11
  from utils import DATA_ROOT_PATH, AppMode
12
  from data_models import Study, Trial # Study, Trial will be used
13
  from data_loader import discover_studies_cached, ensure_data_directory_exists
 
14
  except ImportError as e:
15
  st.error(
16
- f"导入模块失败,请确保 utils.py, data_models.py, data_loader.py 文件存在于正确的位置: {e}"
17
  )
18
  st.stop()
19
 
@@ -40,14 +47,13 @@ if "auto_play_speed" not in st.session_state:
40
  if "auto_play_needs_rerun" not in st.session_state:
41
  st.session_state.auto_play_needs_rerun = False
42
 
43
- # --- Page Configuration ---
44
- st.set_page_config(layout="wide", page_title="柳暗花明 (flowillower)")
45
 
46
 
47
  # --- UI Rendering ---
48
 
49
  # --- Header ---
50
- header_cols = st.columns([2, 3, 1.5, 0.5, 0.5, 0.5])
51
  with header_cols[0]:
52
  st.markdown("## 柳暗花明")
53
  st.caption("flowillower")
@@ -87,6 +93,10 @@ else:
87
  with header_cols[3]: st.button("➕", help="添加 (Add)", disabled=True)
88
  with header_cols[4]: st.button("⚙️", help="设置 (Settings)", disabled=True)
89
  with header_cols[5]: st.button("👤", help="用户 (User)", disabled=True)
 
 
 
 
90
  st.markdown("---")
91
 
92
  # --- Sidebar ---
@@ -175,7 +185,8 @@ if current_study and current_trial:
175
  with control_cols[0]:
176
  # 滑动条
177
  if st.session_state.shared_selected_global_step is None:
178
- st.session_state.shared_selected_global_step = min_step
 
179
 
180
  # 确保当前选中的步骤在有效范围内
181
  if st.session_state.shared_selected_global_step not in all_global_steps:
@@ -273,6 +284,105 @@ if current_study and current_trial:
273
 
274
  with st.container(border=True):
275
  st.subheader(metric_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  try:
277
  # 创建 Plotly 图表
278
  fig = go.Figure()
@@ -358,7 +468,7 @@ if current_study and current_trial:
358
 
359
  except Exception as e:
360
  st.error(f"为指标 '{metric_name}' 生成图表时出错: {e}")
361
- st.dataframe(df_metric)
362
  # raise e
363
 
364
 
 
1
  import streamlit as st
2
+ # --- Page Configuration ---
3
+ st.set_page_config(layout="wide", page_title="柳暗花明 (flowillower)", page_icon=":sunrise_over_mountains:", initial_sidebar_state="expanded")
4
+
5
  from pathlib import Path
6
  import plotly.graph_objects as go
7
  import plotly.express as px
 
9
  import pandas as pd
10
  import time
11
 
12
+ # --- Logo ---
13
+ st.logo("logo.png", icon_image="logo.png")
14
+
15
  # 导入重构后的模块
16
  try:
17
  from utils import DATA_ROOT_PATH, AppMode
18
  from data_models import Study, Trial # Study, Trial will be used
19
  from data_loader import discover_studies_cached, ensure_data_directory_exists
20
+ from theme_selector import render_theme_selector # 新增:导入主题选择器
21
  except ImportError as e:
22
  st.error(
23
+ f"导入模块失败,请确保 utils.py, data_models.py, data_loader.py, theme_selector.py 文件存在于正确的位置: {e}"
24
  )
25
  st.stop()
26
 
 
47
  if "auto_play_needs_rerun" not in st.session_state:
48
  st.session_state.auto_play_needs_rerun = False
49
 
50
+
 
51
 
52
 
53
  # --- UI Rendering ---
54
 
55
  # --- Header ---
56
+ header_cols = st.columns([2, 3, 1.5, 0.5, 0.5, 0.5, 1]) # 新增一列用于主题选择器
57
  with header_cols[0]:
58
  st.markdown("## 柳暗花明")
59
  st.caption("flowillower")
 
93
  with header_cols[3]: st.button("➕", help="添加 (Add)", disabled=True)
94
  with header_cols[4]: st.button("⚙️", help="设置 (Settings)", disabled=True)
95
  with header_cols[5]: st.button("👤", help="用户 (User)", disabled=True)
96
+ with header_cols[6]: # 新增:主题选择器列
97
+ with st.container():
98
+ # st.markdown("**主题**")
99
+ render_theme_selector()
100
  st.markdown("---")
101
 
102
  # --- Sidebar ---
 
185
  with control_cols[0]:
186
  # 滑动条
187
  if st.session_state.shared_selected_global_step is None:
188
+ # 默认选择最后一个step
189
+ st.session_state.shared_selected_global_step = max_step
190
 
191
  # 确保当前选中的步骤在有效范围内
192
  if st.session_state.shared_selected_global_step not in all_global_steps:
 
284
 
285
  with st.container(border=True):
286
  st.subheader(metric_name)
287
+
288
+ # 添加metric组件 - 显示当前值和增量
289
+ try:
290
+ current_step = st.session_state.shared_selected_global_step
291
+
292
+ # 获取所有可能的track
293
+ all_tracks = df_metric['track'].unique() if 'track' in df_metric.columns else [None]
294
+
295
+ # 为每个track创建metric组件
296
+ if len(all_tracks) > 1:
297
+ metric_cols = st.columns(len(all_tracks))
298
+ else:
299
+ metric_cols = [st] # 使用整个容器
300
+
301
+ for idx, track in enumerate(all_tracks):
302
+ # 查找当前步骤的数据
303
+ if track is not None:
304
+ current_step_data = df_metric[
305
+ (df_metric['global_step'] == current_step) &
306
+ (df_metric['track'] == track)
307
+ ]
308
+ else:
309
+ current_step_data = df_metric[df_metric['global_step'] == current_step]
310
+
311
+ current_value = None
312
+ delta_value = None
313
+
314
+ # 如果当前步骤没有该track的数据,向前查找最近的步骤
315
+ if current_step_data.empty:
316
+ # 向前查找最近的有该track数据的步骤
317
+ current_index = all_global_steps.index(current_step)
318
+ for search_idx in range(current_index - 1, -1, -1):
319
+ search_step = all_global_steps[search_idx]
320
+ if track is not None:
321
+ search_data = df_metric[
322
+ (df_metric['global_step'] == search_step) &
323
+ (df_metric['track'] == track)
324
+ ]
325
+ else:
326
+ search_data = df_metric[df_metric['global_step'] == search_step]
327
+
328
+ if not search_data.empty:
329
+ current_value = search_data['value'].iloc[0]
330
+ current_step_found = search_step
331
+ break
332
+ else:
333
+ current_value = current_step_data['value'].iloc[0]
334
+ current_step_found = current_step
335
+
336
+ # 计算增量:查找比当前找到的步骤更早的数据
337
+ if current_value is not None:
338
+ current_found_index = all_global_steps.index(current_step_found)
339
+ for prev_idx in range(current_found_index - 1, -1, -1):
340
+ prev_step = all_global_steps[prev_idx]
341
+ if track is not None:
342
+ prev_step_data = df_metric[
343
+ (df_metric['global_step'] == prev_step) &
344
+ (df_metric['track'] == track)
345
+ ]
346
+ else:
347
+ prev_step_data = df_metric[df_metric['global_step'] == prev_step]
348
+
349
+ if not prev_step_data.empty:
350
+ prev_value = prev_step_data['value'].iloc[0]
351
+ delta_value = current_value - prev_value
352
+ break
353
+
354
+ # 显示metric组件
355
+ with metric_cols[idx] if len(all_tracks) > 1 else metric_cols[0]:
356
+ if current_value is not None:
357
+ # 确定label
358
+ if track is not None:
359
+ if current_step_found != current_step:
360
+ label = f"{track} (Step {current_step_found})"
361
+ else:
362
+ label = f"{track}"
363
+ else:
364
+ if current_step_found != current_step:
365
+ label = f"当前值 (Step {current_step_found})"
366
+ else:
367
+ label = f"当前值 (Step {current_step})"
368
+
369
+ st.metric(
370
+ label=label,
371
+ value=f"{current_value:.4f}",
372
+ delta=f"{delta_value:.4f}" if delta_value is not None else None
373
+ )
374
+ else:
375
+ # 没有找到任何数据
376
+ track_label = track if track is not None else "数据"
377
+ st.metric(
378
+ label=f"{track_label}",
379
+ value="无数据",
380
+ delta=None
381
+ )
382
+
383
+ except Exception as e:
384
+ st.warning(f"计算指标值时出错: {e}")
385
+
386
  try:
387
  # 创建 Plotly 图表
388
  fig = go.Figure()
 
468
 
469
  except Exception as e:
470
  st.error(f"为指标 '{metric_name}' 生成图表时出错: {e}")
471
+ st.dataframe(df_metric)
472
  # raise e
473
 
474
 
src/theme_selector.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import toml
3
+ from pathlib import Path
4
+ import os
5
+ import time
6
+
7
+ class ThemeSelector:
8
+ def __init__(self, themes_dir=".streamlit/themes", config_path=".streamlit/config.toml"):
9
+ self.themes_dir = Path(themes_dir)
10
+ self.config_path = Path(config_path)
11
+ self.themes = {}
12
+ self.load_themes()
13
+
14
+ def load_themes(self):
15
+ """加载所有主题文件"""
16
+ self.themes = {}
17
+ if not self.themes_dir.exists():
18
+ return
19
+
20
+ for theme_file in self.themes_dir.glob("*.toml"):
21
+ try:
22
+ theme_data = toml.load(theme_file)
23
+
24
+ # 从根级别获取theme_name和theme_poem
25
+ theme_name = theme_data.get("theme_name", theme_file.stem)
26
+ theme_poem = theme_data.get("theme_poem", "")
27
+ theme_config = theme_data.get("theme", {})
28
+
29
+ self.themes[theme_name] = {
30
+ "file": theme_file,
31
+ "name": theme_name,
32
+ "poem": theme_poem,
33
+ "config": theme_config
34
+ }
35
+ except Exception as e:
36
+ st.warning(f"读取主题文件 {theme_file} 失败: {e}")
37
+
38
+ def get_current_theme(self):
39
+ """获取当前主题名称"""
40
+ if not self.config_path.exists():
41
+ return None
42
+
43
+ try:
44
+ # config = toml.load(self.config_path)
45
+ # # 从根级别读取theme_name
46
+ # current_theme_name = config.get("theme") or {}
47
+ # current_theme_name = current_theme_name.get("theme_name")
48
+ # return current_theme_name
49
+ theme_toml = self.config_path.parent/"theme.toml"
50
+ theme = toml.load(theme_toml)
51
+ return theme.get("theme_name")
52
+
53
+ except Exception:
54
+ return None
55
+
56
+ def apply_theme(self, theme_name):
57
+ """应用选定的主题"""
58
+ if theme_name not in self.themes:
59
+ st.error(f"主题 '{theme_name}' 不存在")
60
+ return False
61
+
62
+ try:
63
+ # 确保配置目录存在
64
+ self.config_path.parent.mkdir(parents=True, exist_ok=True)
65
+
66
+ # 读取现有配置或创建新配置
67
+ config = {}
68
+ if self.config_path.exists():
69
+ try:
70
+ config = toml.load(self.config_path)
71
+ except Exception:
72
+ config = {}
73
+
74
+ # 添加根级别的theme_name和theme_poem
75
+ # config["theme_name"] = self.themes[theme_name]["name"]
76
+ # config["theme_poem"] = self.themes[theme_name]["poem"]
77
+
78
+ # 更新主题配置
79
+ theme_config = self.themes[theme_name]["config"].copy()
80
+ # theme_config["theme_name"] = self.themes[theme_name]["name"]
81
+ # theme_config["theme_poem"] = self.themes[theme_name]["poem"]
82
+ config["theme"] |= theme_config
83
+
84
+ # 写入配置文件
85
+ with open(self.config_path, "w", encoding="utf-8") as f:
86
+ toml.dump(config, f)
87
+
88
+ theme_toml = self.config_path.parent/"theme.toml"
89
+ with open(theme_toml, "w", encoding="utf-8") as f:
90
+ toml.dump(dict(
91
+ theme_name = self.themes[theme_name]["name"],
92
+ theme_poem = self.themes[theme_name]["poem"]
93
+ ), f)
94
+
95
+ return True
96
+
97
+ except Exception as e:
98
+ st.error(f"应用主题失败: {e}")
99
+ return False
100
+
101
+ def render_theme_selector(self):
102
+ """渲染主题选择器UI"""
103
+ if not self.themes:
104
+ st.warning("未找到可用主题")
105
+ return
106
+
107
+ theme_names = list(self.themes.keys())
108
+ current_theme = self.get_current_theme()
109
+
110
+ # 确定当前选中的索引
111
+ current_index = 0
112
+ if current_theme and current_theme in theme_names:
113
+ current_index = theme_names.index(current_theme)
114
+
115
+ # 主题选择下拉菜单
116
+ selected_theme = st.selectbox(
117
+ "选择主题",
118
+ options=theme_names,
119
+ index=current_index,
120
+ format_func=lambda x: self.themes[x]["name"],
121
+ key="theme_selector_widget",
122
+ label_visibility="collapsed"
123
+ )
124
+
125
+ # 如果选择了新主题
126
+ if selected_theme != current_theme:
127
+ if self.apply_theme(selected_theme):
128
+ # 显示主题诗句
129
+ theme_poem = self.themes[selected_theme]["poem"]
130
+ if theme_poem:
131
+ st.toast(f"✨ {theme_poem}", icon="🎨")
132
+ else:
133
+ st.toast(f"已切换到主题: {selected_theme}", icon="🎨")
134
+
135
+ time.sleep(3)
136
+ # 延迟重新运行以应用主题
137
+ st.rerun()
138
+
139
+ return selected_theme
140
+
141
+ # 全局主题选择器实例
142
+ _theme_selector = None
143
+
144
+ def get_theme_selector():
145
+ """获取全局主题选择器实例"""
146
+ global _theme_selector
147
+ if _theme_selector is None:
148
+ _theme_selector = ThemeSelector()
149
+ return _theme_selector
150
+
151
+ def render_theme_selector():
152
+ """便捷函数:渲染主题选择器"""
153
+ return get_theme_selector().render_theme_selector()