[Experimental] Synchronize axes in interactive show diff (#4570)

* Synchronize axes in the show_diff interactive view

* Modify show_diff layout to include test name in plot

* Fix issue where the difference displayed was wrong

This occured when the expected color was black but the generated color was something different.

* Also show number of non matching pixels in the show diff gui

* Implemented suggestions from Chopan50
This commit is contained in:
Henrik Skov Midtiby 2026-02-13 22:34:57 +01:00 committed by GitHub
commit f6611bac46
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -3,10 +3,13 @@ from __future__ import annotations
import logging
import warnings
import numpy as np
from manim.typing import PixelArray
from manim.utils.color import BLACK, PURE_GREEN, PURE_RED
__all__ = ["show_diff_helper"]
FRAME_ABSOLUTE_TOLERANCE = 1.01
def show_diff_helper(
@ -23,22 +26,52 @@ def show_diff_helper(
fig = plt.figure()
fig.suptitle(f"Test difference summary at frame {frame_number}", fontsize=16)
ax = fig.add_subplot(gs[0, 0])
ax.imshow(frame_data)
ax.set_title("Generated")
ax1 = fig.add_subplot(gs[0, 0])
ax1.imshow(frame_data)
ax1.set_title("Generated")
ax = fig.add_subplot(gs[0, 1])
ax.imshow(expected_frame_data)
ax.set_title("Expected")
ax2 = fig.add_subplot(gs[0, 1], sharex=ax1, sharey=ax1)
ax2.imshow(expected_frame_data)
ax2.set_title("Expected")
ax = fig.add_subplot(gs[1, :])
ax3 = fig.add_subplot(gs[1, 0], sharex=ax1, sharey=ax1)
generated_is_expected = (frame_data == expected_frame_data).all(2)
expected_is_black = (expected_frame_data == BLACK.to_int_rgba()).all(2)
diff_im = expected_frame_data.copy()
diff_im[generated_is_expected & ~expected_is_black] = PURE_GREEN.to_int_rgba()
diff_im[~generated_is_expected & ~expected_is_black] = PURE_RED.to_int_rgba()
ax.imshow(diff_im, interpolation="nearest")
ax.set_title("Difference summary: (green = same, red = different)")
diff_im[~generated_is_expected] = PURE_RED.to_int_rgba()
ax3.imshow(diff_im, interpolation="nearest")
ax3.set_title("Difference")
fig.text(
x=0.55,
y=0.46,
s=f"Testname:\n {control_data_filename[:-4]}",
wrap=True,
transform=fig.transFigure,
fontsize=12,
verticalalignment="top",
)
number_of_matches = np.isclose(
frame_data, expected_frame_data, atol=FRAME_ABSOLUTE_TOLERANCE
).sum()
number_of_mismatches = frame_data.size - number_of_matches
fig.text(
x=0.55,
y=0.34,
s=f"Difference count:\n {number_of_mismatches}",
transform=fig.transFigure,
fontsize=12,
verticalalignment="top",
)
fig.text(
x=0.55,
y=0.22,
s="Difference summary: \n green = same\n red = different",
transform=fig.transFigure,
fontsize=12,
verticalalignment="top",
)
with warnings.catch_warnings():
warnings.simplefilter("error")