Skip to content

ENH: allow non-monotonic contour levels#31237

Open
jklymak wants to merge 3 commits intomatplotlib:mainfrom
jklymak:enh-allow-non-monotonic-contour
Open

ENH: allow non-monotonic contour levels#31237
jklymak wants to merge 3 commits intomatplotlib:mainfrom
jklymak:enh-allow-non-monotonic-contour

Conversation

@jklymak
Copy link
Member

@jklymak jklymak commented Mar 4, 2026

This removes the restriction on contour needing to have monotonically increasing contour levels. No sorting of the levels is done. The documentation change is trivial.

This restriction was put in for contourf, #5477, but doesn't seem necessary for contour.

Addresses #31227

import numpy as np
import matplotlib.pyplot as plt

Z = np.arange(100).reshape(10, 10)
fig, axs = plt.subplots(2, 2, layout='constrained', sharex=True, sharey=True)
levels0 = np.array([0, 30, 10, 20, 33, 80, 53])

axs[0, 0].contour(Z, levels=levels0, colors=['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'black'])

axs[0, 1].contour(Z, levels=levels0)
axs[1, 0].contour(Z, levels=np.sort(levels0))
axs[1, 1].contour(Z, levels=np.sort(levels0)[::-1])

plt.show()
Contour

@jklymak jklymak changed the title ENH: allow non-monotonic contour ENH: allow non-monotonic contour levels Mar 4, 2026
@jklymak jklymak marked this pull request as ready for review March 4, 2026 23:53
@jklymak
Copy link
Member Author

jklymak commented Mar 5, 2026

Test failures are unrelated so far as I can tell...

@WeatherGod
Copy link
Member

If I remember correctly, we decided to make the interfaces consistent since the APIs are so similar.

@jklymak
Copy link
Member Author

jklymak commented Mar 5, 2026

I don't see a strong argument for consistency here. If the inputs were contradictory that would be a problem, but the allowed contourf levels are a subset of the allowed contour levels. If someone needs to toggle between the two, they just need to use the more restrictive levels.

@WeatherGod
Copy link
Member

Thoughts, @ianthomas23?

@ianthomas23
Copy link
Member

Thoughts, @ianthomas23?

Personally I'm not in favour of introducing differences between contour and contourf.

@jklymak
Copy link
Member Author

jklymak commented Mar 5, 2026

The colors argument is not consistent between the two, so filled and unfilled contours are already inconsistent. If this did a big sorting song-and-dance to make this work, I'd agree it's not worth it. But the suggestion here is not so much to introduce an inconsistency, as to allow flexibility the existing code already supports.

@timhoffm
Copy link
Member

timhoffm commented Mar 6, 2026

I think this needs more documentation as the removal of the order opens up room for ambiguity.

AFAICS:

  • If levels and colors are given, the mapping between levels and colors is in that order.
  • If colors is not an explicit lists, color values are taken from the cmap, and here the values are internally sorted.

Is that correct?

@jklymak
Copy link
Member Author

jklymak commented Mar 6, 2026

I think this needs more documentation as the removal of the order opens up room for ambiguity.

AFAICS:

  • If levels and colors are given, the mapping between levels and colors is in that order.
  • If colors is not an explicit lists, color values are taken from the cmap, and here the values are internally sorted.

Is that correct?

Thats correct, and I think that would be expected behaviour. A color list is an ordered list that goes with the ordered list of levels. A colormap maps from a value to a color, so I think the expected value to use is level.

I've mildly updated the docs to state this. I don't think we need to go overboard with documenting this - I'm not claiming we should encourage this usage, just that I don't think it should fail arbitrarily

@scottshambaugh
Copy link
Contributor

scottshambaugh commented Mar 9, 2026

From the discussion in #31227

So now that we no longer have the historic limitation, there is no technical problem allowing monotonically decreasing contour levels.

I don't see any issue with supporting monotonically decreasing levels if it's feasible. And then doing it for both contour and contourf keeps (more) API parity.

Not requiring contour to be monotonic I think is also fine.

@jklymak
Copy link
Member Author

jklymak commented Mar 10, 2026

Yeah, this PR doesn't go as far as allowing filled contourf to be monotonically decreasing. That would require some juggling of the arguments to match the order specified by the user.

@WeatherGod
Copy link
Member

WeatherGod commented Mar 12, 2026

There are two developers who have stated that they are against this particular change (allowing discrepancy between contour and contourf).

@WeatherGod
Copy link
Member

Just noticed that Scott's comment was edited to include his approval of non-monotonic constraint of contour, so I'll edit my comment to take that part out. There are still two devs that have expressed opposition to this change.

@jklymak
Copy link
Member Author

jklymak commented Mar 12, 2026

@WeatherGod I've still not understood why breaking "consistency" would lead to problems. I'm all for consistent APIs when they lead to less confusion, cleaner code, or to avoid overly convoluted documentation (probably in that order), but in this case it seems to just be a restriction for consistency's sake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants