FIX: respect animated=True in imshow and avoid drawing animated images in the static background (closes #18985) #30694
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR summary
Closes #18985
Why is this change necessary?
imshow(..., animated=True)did not behave consistently with other animated artists. Even ifanimated=Truewas passed, the returnedAxesImagewas still registered inAxes.imagesviaadd_image, which means it was drawn into the static background on the first render. This is inconsistent with howplot(..., animated=True)works, where animated artists are excluded from the static background and are instead expected to be managed by blitting.What problem does it solve?
Because animated images were still added to
Axes.images, they would appear in the first frame of an animation before the blitting logic ever had a chance to draw them. This breaks the expectation thatanimated=Truemeans “do not draw this as part of the static background; I will manage it manually for animation.”What is the reasoning for this implementation?
In
Axes.imshow, after creating and configuring theAxesImage, we now branch based on the artist’sanimatedflag:im.get_animated()isTrue, we attach the image as a genericArtistusingadd_artistinstead of adding it toAxes.images. This prevents it from being rendered in the initial background draw and matches the behavior ofLine2D(animated=True).im.get_animated()isFalse(the default case), behavior is unchanged: we continue to calladd_image(im)and the image is part of the normal background render.This makes
imshow(..., animated=True)consistent with the existing animated artist contract, and fixes the discrepancy discussed in issue #18985.We also add a new regression test (
lib/matplotlib/tests/test_imshow_animated.py) that asserts:animated=Trueis not present inax.images, but it is still attached to the Axes (viaax.get_children()), so animation code can still manage/blit it.animated=Falseis present inax.imagesas before.No interactive drawing (
plt.show()) is required in the test.This should be backwards-compatible for non-animated images. The only behavioral change is for the
animated=Truecase, which now behaves as documented/expected for animated artists.PR checklist
test_imshow_animated.py)