Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Bug]: contour/contourf silently produces nonsense levels when Z is constant (zmin == zmax) #31493

@buddy0452004

Description

@buddy0452004

Bug summary

When Z has no variation (all values are equal), contour and contourf silently
produce multiple identical levels and render empty collections with no warning
to the user. The plot appears blank or broken with no indication of why.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt

Z = np.ones((10, 10)) * 5.0  # constant Z

fig, (ax1, ax2) = plt.subplots(1, 2)
cs1 = ax1.contour(np.linspace(0, 1, 10), np.linspace(0, 1, 10), Z)
cs2 = ax2.contourf(np.linspace(0, 1, 10), np.linspace(0, 1, 10), Z)

print(f"contour levels:  {cs1.levels}")   # [5. 5. 5. 5. 5. 5. 5. 5.]
print(f"contourf levels: {cs2.levels}")   # [5. 5. 5. 5. 5. 5. 5. 5.]
print(f"contour paths:   {cs1.get_paths()}")  # all empty

Actual outcome

contour levels: [5. 5. 5. 5. 5. 5. 5. 5.]
contourf levels: [5. 5. 5. 5. 5. 5. 5. 5.]
No UserWarning raised. Plot is blank. User has no indication of why.

Expected outcome

A UserWarning should be raised:
"No contour levels can be computed: Z has no variation (min == max == 5.0)."

Similar to the existing warning "No contour levels were found within the data
range" which fires when user-supplied levels are out of range — but that
warning never fires for the auto-level case when zmin == zmax.

Additional information

Root cause is in contour.py around line 1364-1370. After zmin and zmax are
computed from Z, there is no check for zmin == zmax before _process_contour_level_args
is called. When zmin == zmax, MaxNLocator.tick_values() returns identical values,
the i1 - i0 < 3 fallback at line 1002 triggers, and the full array of identical
levels is returned silently.

The fix is a one-block addition right after line 1365:

if self.zmin == self.zmax:
    _api.warn_external(
        f"No contour levels can be computed: Z has no variation "
        f"(min == max == {self.zmin})."
    )

This is consistent with the logscale warning pattern directly below it.

Operating system

Linux

Matplotlib Version

3.10.8

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions