Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix handling single contour level out of data range#17179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
lhuedepohl wants to merge1 commit intomatplotlib:mainfromlhuedepohl:master
Closed

Fix handling single contour level out of data range#17179

lhuedepohl wants to merge1 commit intomatplotlib:mainfromlhuedepohl:master

Conversation

lhuedepohl
Copy link

PR Summary

Previously, the behavior of ContourSet was special when a single contour
level was specified that was out of range of the given z array.

In that case, instead of the given value the minimum of the dataset was
contoured, instead. This is very unexpected, in my opinion.

This simple change simply makes no contour line at all, instead.

PR Checklist

The change is so simple and small, I believe none of the entries in the checklist is really applicable. I tested, of course, that with[np.nan] in placeplt.contour() still works. I am unsure, however, in what other places that change could have unintended side-effects, so I would be glad for some review.

  • Has Pytest style unit tests
  • Code isFlake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

Previously, the behavior of ContourSet was special when a single contourlevel was specified that was out of range of the given z array.In that case, instead of the given value the minimum of the dataset wascontoured, instead. This is very unexpected, in my opinion.This simple change simply makes no contour line at all, instead.
@dstansby
Copy link
Member

Since there aren't any levels, would it be possible to just set it to an empty list?

@lhuedepohl
Copy link
Author

That is what I initially tried, but this seems to break some assumptions elsewhere. If I setself.levels = [] the following test script,

test.py:

import matplotlibimport matplotlib.pyplot as pltimport numpy as npz = np.ones((5, 5))z[0, 0] = 2plt.contour(z, [3.0])plt.show()

produces this error

./test.py:7: UserWarning: No contour levels were found within the data range.  plt.contour(z, [3.0])Traceback (most recent call last):  File "./test.py", line 7, in <module>    plt.contour(z, [3.0])  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 2397, in contour    if __ret._A is not None: sci(__ret)  # noqa  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 2929, in sci    return gca()._sci(im)  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 1866, in _sci    if im.collections[0] not in self.collections:IndexError: list index out of range

The observation was that withnp.nan no visible contours are produced. Of course, this is also a somewhat unclean solution - someone familiar with the contouring code should probably decide if this is appropriate or if some rework on other parts might be necessary.

@jklymak
Copy link
Member

This PR could use a little more explanation and motivating example. It seems like maybe its reasonable, but its an API change to change the returned type, so it'll need some justification and tests. Also what does this proposed change do to colorbars that are attached to the contour? I'll guess they don't like the NaN, but I've not tested. Also, what is the use case that needs this fixed?

@lhuedepohl
Copy link
Author

lhuedepohl commentedApr 30, 2020
edited
Loading

I fully concede that the commit is a bit of a hack. I believe, however, that it strictly better than the current behavior, where an arbitrary contour line is drawn instead.

Let me demonstrate. Take an array with values between 0. and 1. and try to draw a contour line at value 3.0:

demo.py:

#!/usr/bin/python3import matplotlib.pyplot as pltimport numpy as npz = np.ones((5, 5)) * 1.0z[0, 0] = 0.z[1, 0] = 0.z[0, 1] = 0.plt.contour(z, [3.0])plt.title("Contour of the value $3$?")plt.savefig("bogus_contour.png")

This produces an output file, an a user warning at run-time:

./demo.py:11: UserWarning: No contour levels were found within the data range.  plt.contour(z, [3.0])

The output file has a contour line drawn at 0.0, instead of 3.0:
bogus_contour

I think it is quite dangerous to simply print such a run-time warning and then proceed to contour a basically arbitrary z-value instead.

@lhuedepohl
Copy link
Author

Also what does this proposed change do to colorbars that are attached to the contour?

Colorbars do not work in this case, even without my patch:

test_colorbar.py:

#!/usr/bin/python3import matplotlib.pyplot as pltimport numpy as npz = np.ones((5, 5))z[0, 0] = 0z[1, 0] = 0z[0, 1] = 0plt.figure(1)plt.contour(z, [3.0])plt.colorbar()plt.title("Contour of the value $3$?")plt.savefig("bogus_contour.png")

produces

./test_colorbar.py:12: UserWarning: No contour levels were found within the data range.  plt.contour(z, [3.0])Traceback (most recent call last):  File "./test_colorbar.py", line 13, in <module>    plt.colorbar()  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 2031, in colorbar    ret = gcf().colorbar(mappable, cax=cax, ax=ax, **kw)  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/figure.py", line 2206, in colorbar    cb = cbar.colorbar_factory(cax, mappable, **cb_kw)  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/colorbar.py", line 1714, in colorbar_factory    cb = Colorbar(cax, mappable, **kwargs)  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/colorbar.py", line 1222, in __init__    ColorbarBase.__init__(self, ax, **kwargs)  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/colorbar.py", line 480, in __init__    self.draw_all()  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/colorbar.py", line 514, in draw_all    self._config_axes(X, Y)  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/colorbar.py", line 725, in _config_axes    xy = self._outline(X, Y)  File "/home/lorenz/.local/lib/python3.8/site-packages/matplotlib/colorbar.py", line 775, in _outline    x = X.T.reshape(-1)[ii]  File "/usr/lib64/python3.8/site-packages/numpy/ma/core.py", line 3188, in __getitem__    dout = self.data[indx]IndexError: index 2 is out of bounds for axis 0 with size 2

@jklymakjklymak marked this pull request as draftApril 23, 2021 15:15
@jklymak
Copy link
Member

This still seems useful, but needs more work...

@dstansby
Copy link
Member

The example given in#17179 (comment) is now fixed on the Matplotlib main branch - I'm not sure when or how it was fixed, but given that I'm going to close this PR. If I've got anything wrong there please shout and we can re-open!

@rcomer
Copy link
Member

I haven't read in detail, but I think#24912 might be the relevant fix.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers
No reviews
Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

4 participants
@lhuedepohl@dstansby@jklymak@rcomer

[8]ページ先頭

©2009-2025 Movatter.jp