Skip to content

Conversation

trygvrad
Copy link
Contributor

Test not working as intended

The test test_image.test_image_cursor_formatting() is intended to test mouseover formatting of masked image data.
see issue #15103 and resolution in PR #15140 .

def test_image_cursor_formatting():
    fig, ax = plt.subplots()
    im = ax.imshow(np.zeros((4, 4)))

    data = np.ma.masked_array([0], mask=[True])
    assert im.format_cursor_data(data) == '[]'
    ...

However, this test does not work as intended, because it Artist.format_cursor_data() will in normal circumstances call _ColorizerInterface._format_cursor_data_override():

    def format_cursor_data(self, data):
        if np.ndim(data) == 0 and hasattr(self, "_format_cursor_data_override"):
            return self._format_cursor_data_override(data)
        ...

However, because of the way test_image_cursor_formatting() is implemented the array sent to im.format_cursor_data() is 1d, and _format_cursor_data_override() is therefore not called.

i.e. this test does not test the formatting of masked image data as intended.

The relevant behavior has another test

The relevant test (test_image.test_image_cursor_formatting()) is 6 years old. Since then, a more comprehensive test for im.format_cursor_data() has been developed, reproduced below.

@pytest.mark.parametrize(
    "data, text", [
        ([[10001, 10000]], "[10001.000]"),
        ([[.123, .987]], "[0.123]"),
        ([[np.nan, 1, 2]], "[]"),
        ([[1, 1+1e-15]], "[1.0000000000000000]"),
        ([[-1, -1]], "[-1.0]"),
        ([[0, 0]], "[0.00]"),
    ])
def test_format_cursor_data(data, text):
    from matplotlib.backend_bases import MouseEvent

    fig, ax = plt.subplots()
    im = ax.imshow(data)

    xdisp, ydisp = ax.transData.transform([0, 0])
    event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp)
    assert im.format_cursor_data(im.get_cursor_data(event)) == text

This tests im.format_cursor_data() with masked values (nan), and I therefore believe it is not necessary to adapt test_image.test_image_cursor_formatting() so that it tests the relevant behavior, and im.format_cursor_data() can instead be removed.

Why did this attract my attention

I noticed this because I am adapting _format_cursor_data_override() to work with multivariate data, see #29876 and related PRs, and need to develop new tests for this behavior. I attempted to base my tests on test_image.test_image_cursor_formatting() but this proved futile, and I will instead implement tests based on test_image.test_format_cursor_data().

This test does not test im.format_cursor_data() because it test it with 1d arrays, whereas the artist.format_cursor_data() should forward to colrizingArtist._format_cursor_data_override() but this only happens with 0d data. The correct behavior with nans is tested in the existing test test_format_cursor_data(), so the test removed here, even if working as intended, is superfluous.
@dstansby dstansby added this to the v3.11.0 milestone Sep 4, 2025
@dstansby dstansby merged commit 553cec1 into matplotlib:main Sep 4, 2025
39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants