Files
pqAutomationApp/app/plots/plot_cct.py
2026-04-20 11:13:57 +08:00

325 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""CCT / 色度一致性绘制。
Step 2 重构:从 pqAutomationApp.PQAutomationApp.plot_cct 原样搬迁。
"""
import numpy as np
def plot_cct(self, test_type):
"""绘制 x 和 y 坐标分离图 - 每个点标注纵坐标值"""
self.cct_fig.clear()
gray_data = self.results.get_intermediate_data("shared", "gray")
if not gray_data:
gray_data = self.results.get_intermediate_data("cct", "gray")
if not gray_data or len(gray_data) < 2:
self.log_gui.log("⚠️ 无 xy 数据可用")
ax = self.cct_fig.add_subplot(111)
ax.text(
0.5,
0.5,
"无可用数据",
ha="center",
va="center",
fontsize=14,
color="red",
)
ax.axis("off")
self.cct_canvas.draw()
return
x_measured = [data[0] for data in gray_data]
y_measured = [data[1] for data in gray_data]
# 反转数据顺序(从暗到亮)
x_measured = x_measured[::-1]
y_measured = y_measured[::-1]
# 去掉第一个点
x_measured = x_measured[1:]
y_measured = y_measured[1:]
# 重新生成灰阶坐标
total_points = len(gray_data)
grayscale = np.linspace(100 / total_points, 100, len(x_measured))
self.log_gui.log(f"✓ 已移除第一个数据点,当前数据点数: {len(x_measured)}")
self.log_gui.log(f" x范围: {min(x_measured):.6f} - {max(x_measured):.6f}")
self.log_gui.log(f" y范围: {min(y_measured):.6f} - {max(y_measured):.6f}")
# ========== 根据测试类型读取对应参数 ==========
if test_type == "sdr_movie":
try:
x_ideal = float(self.sdr_cct_x_ideal_var.get())
x_tolerance = float(self.sdr_cct_x_tolerance_var.get())
y_ideal = float(self.sdr_cct_y_ideal_var.get())
y_tolerance = float(self.sdr_cct_y_tolerance_var.get())
self.log_gui.log("✓ 使用 SDR 色度参数")
except:
x_ideal = 0.3127
x_tolerance = 0.003
y_ideal = 0.3290
y_tolerance = 0.003
self.log_gui.log("⚠️ SDR 参数读取失败,使用默认值")
elif test_type == "hdr_movie":
try:
x_ideal = float(self.hdr_cct_x_ideal_var.get())
x_tolerance = float(self.hdr_cct_x_tolerance_var.get())
y_ideal = float(self.hdr_cct_y_ideal_var.get())
y_tolerance = float(self.hdr_cct_y_tolerance_var.get())
self.log_gui.log("✓ 使用 HDR 色度参数")
except:
x_ideal = 0.3127
x_tolerance = 0.003
y_ideal = 0.3290
y_tolerance = 0.003
self.log_gui.log("⚠️ HDR 参数读取失败,使用默认值")
else: # screen_module
try:
x_ideal = float(self.cct_x_ideal_var.get())
x_tolerance = float(self.cct_x_tolerance_var.get())
y_ideal = float(self.cct_y_ideal_var.get())
y_tolerance = float(self.cct_y_tolerance_var.get())
self.log_gui.log("✓ 使用屏模组色度参数")
except:
x_ideal = 0.306
x_tolerance = 0.003
y_ideal = 0.318
y_tolerance = 0.003
self.log_gui.log("⚠️ 屏模组参数读取失败,使用默认值")
x_low = x_ideal - x_tolerance
x_high = x_ideal + x_tolerance
y_low = y_ideal - y_tolerance
y_high = y_ideal + y_tolerance
self.log_gui.log(f"✓ 用户设置参数:")
self.log_gui.log(f" x-ideal={x_ideal:.4f}, tolerance={x_tolerance:.4f}")
self.log_gui.log(f" x范围: [{x_low:.4f}, {x_high:.4f}]")
self.log_gui.log(f" y-ideal={y_ideal:.4f}, tolerance={y_tolerance:.4f}")
self.log_gui.log(f" y范围: [{y_low:.4f}, {y_high:.4f}]")
# 为所有测试类型创建子图
ax1 = self.cct_fig.add_subplot(211)
ax2 = self.cct_fig.add_subplot(212)
# ========== 上图x coordinates ==========
ax1.plot(
grayscale,
x_measured,
"b-o",
label="屏本体",
linewidth=2,
markersize=4,
zorder=5,
)
# 为每个点添加数值标注x 坐标)
for i, (gs, x_val) in enumerate(zip(grayscale, x_measured)):
ax1.annotate(
f"{x_val:.5f}",
xy=(gs, x_val),
xytext=(0, 8),
textcoords="offset points",
ha="center",
va="bottom",
fontsize=7,
color="blue",
bbox=dict(
boxstyle="round,pad=0.2",
facecolor="white",
edgecolor="blue",
alpha=0.8,
linewidth=0.5,
),
)
# 绘制完整的参考线
full_grayscale = np.linspace(0, 100, 100)
ax1.axhline(
y=x_ideal,
color="green",
linestyle="--",
linewidth=1.5,
label=f"x-ideal ({x_ideal:.4f})",
zorder=3,
)
ax1.axhline(
y=x_low,
color="red",
linestyle=":",
linewidth=1,
alpha=0.7,
label=f"x-low ({x_low:.4f})",
zorder=2,
)
ax1.axhline(
y=x_high,
color="red",
linestyle=":",
linewidth=1,
alpha=0.7,
label=f"x-high ({x_high:.4f})",
zorder=2,
)
ax1.fill_between(
full_grayscale, x_low, x_high, alpha=0.15, color="blue", zorder=1
)
ax1.set_xlabel("灰阶 (%)", fontsize=9)
ax1.set_ylabel("CIE x", fontsize=9)
ax1.grid(True, linestyle="--", alpha=0.3)
ax1.tick_params(labelsize=8)
ax1.set_xlim(0, 105)
# 纵坐标范围由用户参数控制
x_min_data = min(x_measured)
x_max_data = max(x_measured)
data_range_x = x_max_data - x_min_data
self.log_gui.log(f" x数据波动: {data_range_x:.6f}")
range_span = x_tolerance * 2
margin_ratio = 0.20
extra_margin = range_span * margin_ratio
final_y_min = min(x_min_data, x_low) - extra_margin
final_y_max = max(x_max_data, x_high) + extra_margin
if x_min_data >= x_low and x_max_data <= x_high:
self.log_gui.log(f" x数据在tolerance范围内使用tolerance范围显示")
final_y_min = x_low - extra_margin
final_y_max = x_high + extra_margin
else:
self.log_gui.log(f" x数据超出tolerance范围扩展显示范围")
ax1.set_ylim(final_y_min, final_y_max)
self.log_gui.log(
f" x轴显示范围: {final_y_min:.6f} - {final_y_max:.6f} (跨度: {final_y_max - final_y_min:.6f})"
)
# ========== 下图y coordinates ==========
ax2.plot(
grayscale,
y_measured,
"r-o",
label="屏本体",
linewidth=2,
markersize=4,
zorder=5,
)
# 为每个点添加数值标注y 坐标)
for i, (gs, y_val) in enumerate(zip(grayscale, y_measured)):
ax2.annotate(
f"{y_val:.5f}",
xy=(gs, y_val),
xytext=(0, 8),
textcoords="offset points",
ha="center",
va="bottom",
fontsize=7,
color="red",
bbox=dict(
boxstyle="round,pad=0.2",
facecolor="white",
edgecolor="red",
alpha=0.8,
linewidth=0.5,
),
)
ax2.axhline(
y=y_ideal,
color="green",
linestyle="--",
linewidth=1.5,
label=f"y-ideal ({y_ideal:.4f})",
zorder=3,
)
ax2.axhline(
y=y_low,
color="orange",
linestyle=":",
linewidth=1,
alpha=0.7,
label=f"y-low ({y_low:.4f})",
zorder=2,
)
ax2.axhline(
y=y_high,
color="orange",
linestyle=":",
linewidth=1,
alpha=0.7,
label=f"y-high ({y_high:.4f})",
zorder=2,
)
ax2.fill_between(
full_grayscale, y_low, y_high, alpha=0.15, color="orange", zorder=1
)
ax2.set_xlabel("灰阶 (%)", fontsize=9)
ax2.set_ylabel("CIE y", fontsize=9)
ax2.grid(True, linestyle="--", alpha=0.3)
ax2.tick_params(labelsize=8)
ax2.set_xlim(0, 105)
# 纵坐标范围由用户参数控制
y_min_data = min(y_measured)
y_max_data = max(y_measured)
data_range_y = y_max_data - y_min_data
self.log_gui.log(f" y数据波动: {data_range_y:.6f}")
range_span = y_tolerance * 2
extra_margin = range_span * margin_ratio
final_y_min = min(y_min_data, y_low) - extra_margin
final_y_max = max(y_max_data, y_high) + extra_margin
if y_min_data >= y_low and y_max_data <= y_high:
self.log_gui.log(f" y数据在tolerance范围内使用tolerance范围显示")
final_y_min = y_low - extra_margin
final_y_max = y_high + extra_margin
else:
self.log_gui.log(f" y数据超出tolerance范围扩展显示范围")
ax2.set_ylim(final_y_min, final_y_max)
self.log_gui.log(
f" y轴显示范围: {final_y_min:.6f} - {final_y_max:.6f} (跨度: {final_y_max - final_y_min:.6f})"
)
# ========== 总标题 - 统一格式(去掉统计信息)==========
test_type_name = self.get_test_type_name(test_type)
self.cct_fig.suptitle(
f"{test_type_name} - 色度一致性测试",
fontsize=12,
y=0.98,
fontweight="bold",
)
self.cct_fig.subplots_adjust(
left=0.12,
right=0.82,
top=0.92,
bottom=0.08,
hspace=0.30,
)
ax1.legend(
fontsize=7, loc="center left", bbox_to_anchor=(1.05, 0.5), framealpha=1.0
)
ax2.legend(
fontsize=7, loc="center left", bbox_to_anchor=(1.05, 0.5), framealpha=1.0
)
self.cct_canvas.draw()
self.chart_notebook.select(self.cct_chart_frame)
self.log_gui.log("✓ xy 色度坐标图绘制完成")