继续优化深色模式显示
This commit is contained in:
@@ -75,7 +75,7 @@ def _xy_to_uv(x: float, y: float):
|
||||
# 子图:左侧 Calman 风格面板
|
||||
# ============================================================
|
||||
|
||||
def _draw_left_panel(ax, color_patches, delta_e_values, font_scale=1.0):
|
||||
def _draw_left_panel(ax, color_patches, delta_e_values, font_scale=1.0, dark_mode=False):
|
||||
"""左侧仅保留大条形图。"""
|
||||
ax.clear()
|
||||
|
||||
@@ -98,19 +98,23 @@ def _draw_left_panel(ax, color_patches, delta_e_values, font_scale=1.0):
|
||||
zorder=3,
|
||||
)
|
||||
|
||||
text_color = "#F3F5F7" if dark_mode else "#111111"
|
||||
bg_color = "#0F1115" if dark_mode else "#FFFFFF"
|
||||
spine_color = "#8C8F94" if dark_mode else "#9A9A9A"
|
||||
|
||||
ax.set_yticks(y_pos)
|
||||
ax.set_yticklabels(color_patches, fontsize=max(5, 7 * font_scale))
|
||||
ax.set_yticklabels(color_patches, fontsize=max(5, 7 * font_scale), color=text_color)
|
||||
ax.invert_yaxis()
|
||||
|
||||
x_max = max(15.0, max(delta_e_values) * 1.15)
|
||||
ax.set_xlim(0, x_max)
|
||||
ax.tick_params(axis="x", labelsize=max(6, 8 * font_scale))
|
||||
ax.tick_params(axis="x", labelsize=max(6, 8 * font_scale), colors=text_color)
|
||||
ax.grid(axis="x", linestyle="-", linewidth=0.6, alpha=0.3, zorder=0)
|
||||
ax.grid(axis="y", linestyle=":", linewidth=0.35, alpha=0.15, zorder=0)
|
||||
|
||||
ax.set_facecolor("#FFFFFF")
|
||||
ax.set_facecolor(bg_color)
|
||||
for spine in ax.spines.values():
|
||||
spine.set_color("#9A9A9A")
|
||||
spine.set_color(spine_color)
|
||||
spine.set_linewidth(0.9)
|
||||
|
||||
|
||||
@@ -118,7 +122,7 @@ def _draw_left_panel(ax, color_patches, delta_e_values, font_scale=1.0):
|
||||
# 子图:CIE 1976 u'v' 色度图(目标 vs 实测)
|
||||
# ============================================================
|
||||
|
||||
def _draw_uv_diagram(ax, color_patches, measurements, standards, font_scale=1.0):
|
||||
def _draw_uv_diagram(ax, color_patches, measurements, standards, font_scale=1.0, dark_mode=False):
|
||||
"""绘制 CIE 1976 u'v' 上的色准对比。"""
|
||||
ax.clear()
|
||||
try:
|
||||
@@ -135,15 +139,23 @@ def _draw_uv_diagram(ax, color_patches, measurements, standards, font_scale=1.0)
|
||||
ax.set_xlim(0.0, 0.65)
|
||||
ax.set_ylim(0.0, 0.60)
|
||||
|
||||
ax.set_facecolor("#000")
|
||||
text_color = "#F3F5F7" if dark_mode else "#111111"
|
||||
sub_text_color = "#D3D7DD" if dark_mode else "#222222"
|
||||
tick_color = "#D3D7DD" if dark_mode else "#222222"
|
||||
legend_label_color = "#FFF" if dark_mode else "#111"
|
||||
legend_bg = "#111" if dark_mode else "#FFFFFF"
|
||||
legend_edge = "#FFF" if dark_mode else "#333"
|
||||
outer_edge = "#FFFFFF" if dark_mode else "#333333"
|
||||
|
||||
ax.set_facecolor("#000" if dark_mode else "#FFFFFF")
|
||||
ax.set_aspect("equal", adjustable="box")
|
||||
ax.set_title("CIE 1976 u'v'", fontsize=max(8, 11 * font_scale), fontweight="bold",
|
||||
color="#111", pad=4)
|
||||
ax.set_xlabel("u'", fontsize=max(7, 9 * font_scale), color="#222", labelpad=1)
|
||||
ax.set_ylabel("v'", fontsize=max(7, 9 * font_scale), color="#222", labelpad=1)
|
||||
ax.tick_params(axis="both", labelsize=max(6, 8 * font_scale), colors="#222")
|
||||
color=text_color, pad=4)
|
||||
ax.set_xlabel("u'", fontsize=max(7, 9 * font_scale), color=sub_text_color, labelpad=1)
|
||||
ax.set_ylabel("v'", fontsize=max(7, 9 * font_scale), color=sub_text_color, labelpad=1)
|
||||
ax.tick_params(axis="both", labelsize=max(6, 8 * font_scale), colors=tick_color)
|
||||
for sp in ax.spines.values():
|
||||
sp.set_color("#666")
|
||||
sp.set_color(outer_edge)
|
||||
sp.set_linewidth(0.9)
|
||||
|
||||
for name, meas in zip(color_patches, measurements):
|
||||
@@ -164,14 +176,14 @@ def _draw_uv_diagram(ax, color_patches, measurements, standards, font_scale=1.0)
|
||||
ax.scatter(
|
||||
[s_u], [s_v],
|
||||
s=56, marker="s",
|
||||
facecolors="none", edgecolors="#FFFFFF",
|
||||
facecolors="none", edgecolors=outer_edge,
|
||||
linewidths=1.25, zorder=18,
|
||||
)
|
||||
# 实测点:白色外圈 + 内层圆点
|
||||
ax.scatter(
|
||||
[m_u], [m_v],
|
||||
s=52, marker="o",
|
||||
facecolors="none", edgecolors="#FFFFFF",
|
||||
facecolors="none", edgecolors=outer_edge,
|
||||
linewidths=1.0, zorder=19,
|
||||
)
|
||||
ax.scatter(
|
||||
@@ -183,7 +195,7 @@ def _draw_uv_diagram(ax, color_patches, measurements, standards, font_scale=1.0)
|
||||
|
||||
legend_handles = [
|
||||
Line2D([0], [0], marker="s", linestyle="none",
|
||||
markerfacecolor="#CCCCCC", markeredgecolor="#FFFFFF",
|
||||
markerfacecolor="#CCCCCC", markeredgecolor=outer_edge,
|
||||
markersize=7, label="目标 (Target)"),
|
||||
Line2D([0], [0], marker="o", linestyle="none",
|
||||
markerfacecolor="#CCCCCC", markeredgecolor="#000000",
|
||||
@@ -192,15 +204,15 @@ def _draw_uv_diagram(ax, color_patches, measurements, standards, font_scale=1.0)
|
||||
leg = ax.legend(
|
||||
handles=legend_handles,
|
||||
loc="lower right", fontsize=max(6, 8 * font_scale),
|
||||
framealpha=0.88, labelcolor="#FFF",
|
||||
framealpha=0.88, labelcolor=legend_label_color,
|
||||
)
|
||||
if leg is not None:
|
||||
leg.get_frame().set_facecolor("#111")
|
||||
leg.get_frame().set_edgecolor("#FFF")
|
||||
leg.get_frame().set_facecolor(legend_bg)
|
||||
leg.get_frame().set_edgecolor(legend_edge)
|
||||
leg.set_zorder(50)
|
||||
|
||||
|
||||
def _draw_result_judgement(ax, accuracy_data, font_scale=1.0):
|
||||
def _draw_result_judgement(ax, accuracy_data, font_scale=1.0, dark_mode=False):
|
||||
"""底部结果条"""
|
||||
ax.clear()
|
||||
ax.set_xlim(0, 1)
|
||||
@@ -210,24 +222,28 @@ def _draw_result_judgement(ax, accuracy_data, font_scale=1.0):
|
||||
avg = accuracy_data.get("avg_delta_e", 0.0)
|
||||
mx = accuracy_data.get("max_delta_e", 0.0)
|
||||
|
||||
panel_bg = "#1A1E24" if dark_mode else "#FFFFFF"
|
||||
panel_edge = "#4A5058" if dark_mode else "#C6C6C6"
|
||||
text_color = "#F3F5F7" if dark_mode else "#111111"
|
||||
|
||||
ax.add_patch(Rectangle(
|
||||
(0.0, 0.10), 1.0, 0.80,
|
||||
transform=ax.transAxes,
|
||||
facecolor="#FFFFFF", edgecolor="#C6C6C6", linewidth=1.0,
|
||||
facecolor=panel_bg, edgecolor=panel_edge, linewidth=1.0,
|
||||
))
|
||||
|
||||
ax.text(
|
||||
0.03, 0.50,
|
||||
f"Avg dE2000: {avg:.2f}",
|
||||
ha="left", va="center",
|
||||
fontsize=max(11, 20 * font_scale), fontweight="normal", color="#111111",
|
||||
fontsize=max(11, 20 * font_scale), fontweight="normal", color=text_color,
|
||||
transform=ax.transAxes,
|
||||
)
|
||||
ax.text(
|
||||
0.52, 0.50,
|
||||
f"Max dE2000: {mx:.2f}",
|
||||
ha="left", va="center",
|
||||
fontsize=max(11, 20 * font_scale), fontweight="normal", color="#111111",
|
||||
fontsize=max(11, 20 * font_scale), fontweight="normal", color=text_color,
|
||||
transform=ax.transAxes,
|
||||
)
|
||||
|
||||
@@ -242,6 +258,14 @@ def plot_accuracy(self: "PQAutomationApp", accuracy_data, test_type):
|
||||
fig = self.accuracy_fig
|
||||
fig.clear()
|
||||
|
||||
try:
|
||||
from app.views.theme_manager import is_dark
|
||||
dark_mode = is_dark()
|
||||
except Exception:
|
||||
dark_mode = False
|
||||
|
||||
fig.patch.set_facecolor("#1B1F24" if dark_mode else "#FFFFFF")
|
||||
|
||||
# 根据当前画布像素尺寸动态缩放字体,避免窗口缩小时文字挤压重叠。
|
||||
font_scale = 1.0
|
||||
try:
|
||||
@@ -271,12 +295,13 @@ def plot_accuracy(self: "PQAutomationApp", accuracy_data, test_type):
|
||||
else:
|
||||
title = f"{test_type_name} - 色准测试(全 29色 | Gamma {target_gamma})"
|
||||
|
||||
title_color = "#F3F5F7" if dark_mode else "#111"
|
||||
fig.suptitle(
|
||||
title,
|
||||
fontsize=max(8, 11 * font_scale),
|
||||
y=0.975,
|
||||
fontweight="bold",
|
||||
color="#111",
|
||||
color=title_color,
|
||||
)
|
||||
|
||||
gs = fig.add_gridspec(
|
||||
@@ -295,7 +320,13 @@ def plot_accuracy(self: "PQAutomationApp", accuracy_data, test_type):
|
||||
# 兼容外部对 self.accuracy_ax 的引用
|
||||
self.accuracy_ax = ax_judge
|
||||
|
||||
_draw_left_panel(ax_left, color_patches, delta_e_values, font_scale=font_scale)
|
||||
_draw_left_panel(
|
||||
ax_left,
|
||||
color_patches,
|
||||
delta_e_values,
|
||||
font_scale=font_scale,
|
||||
dark_mode=dark_mode,
|
||||
)
|
||||
|
||||
try:
|
||||
standards = get_accuracy_color_standards(test_type)
|
||||
@@ -308,8 +339,14 @@ def plot_accuracy(self: "PQAutomationApp", accuracy_data, test_type):
|
||||
measurements,
|
||||
standards,
|
||||
font_scale=font_scale,
|
||||
dark_mode=dark_mode,
|
||||
)
|
||||
_draw_result_judgement(
|
||||
ax_judge,
|
||||
accuracy_data,
|
||||
font_scale=font_scale,
|
||||
dark_mode=dark_mode,
|
||||
)
|
||||
_draw_result_judgement(ax_judge, accuracy_data, font_scale=font_scale)
|
||||
|
||||
try:
|
||||
self.update_accuracy_result_table(accuracy_data, standards)
|
||||
|
||||
@@ -148,35 +148,41 @@ def _draw_measured_triangle(ax, vertices, *, uv_space=False):
|
||||
# )
|
||||
|
||||
|
||||
def _draw_coverage_box(ax, x_pos, y_pos, current_ref, coverage):
|
||||
def _draw_coverage_box(ax, x_pos, y_pos, current_ref, coverage, *, dark_mode):
|
||||
text_color = "#FFF" if dark_mode else "#111"
|
||||
box_face = "#111" if dark_mode else "#FFFFFF"
|
||||
box_edge = "#FFF" if dark_mode else "#333"
|
||||
ax.text(
|
||||
x_pos, y_pos,
|
||||
f"{current_ref}\n覆盖率: {coverage:.1f}%",
|
||||
ha="right", va="bottom",
|
||||
fontsize=11, fontweight="bold",
|
||||
color="#FFF",
|
||||
color=text_color,
|
||||
bbox=dict(
|
||||
boxstyle="round,pad=0.38",
|
||||
facecolor="#111",
|
||||
edgecolor="#FFF",
|
||||
facecolor=box_face,
|
||||
edgecolor=box_edge,
|
||||
linewidth=1.7,
|
||||
alpha=0.98,
|
||||
),
|
||||
zorder=30,
|
||||
)
|
||||
|
||||
def _style_axes(ax, *, title, xlabel, ylabel, xlim, ylim):
|
||||
ax.set_facecolor("#000")
|
||||
ax.set_title(title, fontsize=12, fontweight="bold", color="#FFF", pad=8)
|
||||
ax.set_xlabel(xlabel, fontsize=10, color="#FFF")
|
||||
ax.set_ylabel(ylabel, fontsize=10, color="#FFF")
|
||||
def _style_axes(ax, *, title, xlabel, ylabel, xlim, ylim, dark_mode):
|
||||
text = "#F4F6F8" if dark_mode else "#111"
|
||||
grid = "#444" if dark_mode else "#B8BDC3"
|
||||
spine_color = "#888" if dark_mode else "#666"
|
||||
ax.set_facecolor("#000" if dark_mode else "#FFFFFF")
|
||||
ax.set_title(title, fontsize=12, fontweight="bold", color=text, pad=8)
|
||||
ax.set_xlabel(xlabel, fontsize=10, color=text)
|
||||
ax.set_ylabel(ylabel, fontsize=10, color=text)
|
||||
ax.set_xlim(*xlim)
|
||||
ax.set_ylim(*ylim)
|
||||
ax.set_aspect("equal", adjustable="datalim")
|
||||
ax.grid(True, linestyle=":", linewidth=0.7, color="#444", alpha=0.32)
|
||||
ax.tick_params(axis="both", labelsize=9, colors="#FFF")
|
||||
ax.grid(True, linestyle=":", linewidth=0.7, color=grid, alpha=0.32)
|
||||
ax.tick_params(axis="both", labelsize=9, colors=text)
|
||||
for spine in ax.spines.values():
|
||||
spine.set_color("#888")
|
||||
spine.set_color(spine_color)
|
||||
spine.set_linewidth(0.8)
|
||||
ax.set_clip_on(False)
|
||||
|
||||
@@ -201,13 +207,19 @@ def _blit_background(ax, background, bbox):
|
||||
def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
||||
"""绘制色域图(图像层 + 框架层分离架构)。"""
|
||||
|
||||
try:
|
||||
from app.views.theme_manager import is_dark
|
||||
dark_mode = is_dark()
|
||||
except Exception:
|
||||
dark_mode = False
|
||||
|
||||
ax_xy = self.gamut_ax_xy
|
||||
ax_uv = self.gamut_ax_uv
|
||||
|
||||
ax_xy.clear()
|
||||
ax_uv.clear()
|
||||
# 全局黑色背景
|
||||
self.gamut_fig.patch.set_facecolor("#000")
|
||||
# 全局背景跟随浅/深色主题
|
||||
self.gamut_fig.patch.set_facecolor("#0D1014" if dark_mode else "#FFFFFF")
|
||||
|
||||
# ========== 读取用户选择的参考标准 ==========
|
||||
if test_type == "screen_module":
|
||||
@@ -265,6 +277,7 @@ def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
||||
xlabel="x", ylabel="y",
|
||||
xlim=(bbox_xy[0], bbox_xy[1]),
|
||||
ylim=(bbox_xy[2], bbox_xy[3]),
|
||||
dark_mode=dark_mode,
|
||||
)
|
||||
|
||||
for ref_name in other_refs:
|
||||
@@ -289,7 +302,8 @@ def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
||||
_draw_measured_triangle(ax_xy, measured_xy, uv_space=False)
|
||||
|
||||
_draw_coverage_box(
|
||||
ax_xy, bbox_xy[1] - 0.02, bbox_xy[2] + 0.02, current_ref, xy_coverage
|
||||
ax_xy, bbox_xy[1] - 0.02, bbox_xy[2] + 0.02, current_ref, xy_coverage,
|
||||
dark_mode=dark_mode,
|
||||
)
|
||||
|
||||
# 暗化三角形外部区域(黑色半透明遮罩)
|
||||
@@ -303,18 +317,19 @@ def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
||||
codes = [Path.MOVETO] + [Path.LINETO]*3 + [Path.CLOSEPOLY]
|
||||
codes += [Path.MOVETO] + [Path.LINETO]*2 + [Path.CLOSEPOLY]
|
||||
path = Path(verts, codes)
|
||||
patch = PathPatch(path, facecolor=(0,0,0,0.65), lw=0, zorder=7)
|
||||
mask_face = (0, 0, 0, 0.65) if dark_mode else (1, 1, 1, 0.50)
|
||||
patch = PathPatch(path, facecolor=mask_face, lw=0, zorder=7)
|
||||
ax_xy.add_patch(patch)
|
||||
|
||||
legend = ax_xy.legend(
|
||||
loc="upper right", fontsize=8.5,
|
||||
framealpha=0.0, edgecolor="#000", fancybox=True,
|
||||
labelcolor="#FFF"
|
||||
labelcolor="#FFF" if dark_mode else "#111"
|
||||
)
|
||||
legend.set_zorder(200)
|
||||
legend.get_frame().set_facecolor("#000")
|
||||
legend.get_frame().set_alpha(0.5)
|
||||
legend.get_frame().set_edgecolor("#FFF")
|
||||
legend.get_frame().set_facecolor("#000" if dark_mode else "#FFFFFF")
|
||||
legend.get_frame().set_alpha(0.5 if dark_mode else 0.78)
|
||||
legend.get_frame().set_edgecolor("#FFF" if dark_mode else "#333")
|
||||
ax_xy.add_artist(legend)
|
||||
|
||||
except Exception as e:
|
||||
@@ -334,6 +349,7 @@ def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
||||
xlabel="u'", ylabel="v'",
|
||||
xlim=(bbox_uv[0], bbox_uv[1]),
|
||||
ylim=(bbox_uv[2], bbox_uv[3]),
|
||||
dark_mode=dark_mode,
|
||||
)
|
||||
|
||||
measured_uv = None
|
||||
@@ -367,7 +383,8 @@ def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
||||
_draw_measured_triangle(ax_uv, measured_uv, uv_space=True)
|
||||
|
||||
_draw_coverage_box(
|
||||
ax_uv, bbox_uv[1] - 0.015, bbox_uv[2] + 0.015, current_ref, uv_coverage
|
||||
ax_uv, bbox_uv[1] - 0.015, bbox_uv[2] + 0.015, current_ref, uv_coverage,
|
||||
dark_mode=dark_mode,
|
||||
)
|
||||
|
||||
u0, u1 = bbox_uv[0], bbox_uv[1]
|
||||
@@ -379,18 +396,19 @@ def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
||||
codes = [Path.MOVETO] + [Path.LINETO]*3 + [Path.CLOSEPOLY]
|
||||
codes += [Path.MOVETO] + [Path.LINETO]*2 + [Path.CLOSEPOLY]
|
||||
path = Path(verts, codes)
|
||||
patch = PathPatch(path, facecolor=(0,0,0,0.65), lw=0, zorder=7)
|
||||
mask_face = (0, 0, 0, 0.65) if dark_mode else (1, 1, 1, 0.50)
|
||||
patch = PathPatch(path, facecolor=mask_face, lw=0, zorder=7)
|
||||
ax_uv.add_patch(patch)
|
||||
|
||||
legend_uv = ax_uv.legend(
|
||||
loc="upper right", fontsize=8.5,
|
||||
framealpha=0.0, edgecolor="#000", fancybox=True,
|
||||
labelcolor="#FFF"
|
||||
labelcolor="#FFF" if dark_mode else "#111"
|
||||
)
|
||||
legend_uv.set_zorder(200)
|
||||
legend_uv.get_frame().set_facecolor("#000")
|
||||
legend_uv.get_frame().set_alpha(0.72)
|
||||
legend_uv.get_frame().set_edgecolor("#FFF")
|
||||
legend_uv.get_frame().set_facecolor("#000" if dark_mode else "#FFFFFF")
|
||||
legend_uv.get_frame().set_alpha(0.72 if dark_mode else 0.82)
|
||||
legend_uv.get_frame().set_edgecolor("#FFF" if dark_mode else "#333")
|
||||
ax_uv.add_artist(legend_uv)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user