# plt.contour levels parameter don't work as intended if receive a single int #11913

Closed
opened this Issue Aug 22, 2018 · 5 comments

Projects
None yet
5 participants

### Bug report

Bug summary

The official documentation (https://matplotlib.org/api/_as_gen/matplotlib.pyplot.contour.html) says that the parameter `levels` of the `pyplot.contour` function is an integer will be calculated and shown a number of contours equal to the number passed as a parameter.
The reality of the facts, however, is that the outline associated with the past value is plotted.

Code for reproduction

I used the contour demo example from https://matplotlib.org/gallery/images_contours_and_fields/contour_demo.html#contour-demo adding the `levels` parameter as int.

```import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt

delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
# the original demo had 2 here, but so most of the values would have been less than 5
Z = (Z1 - Z2) * 6

plt.contour(X, Y, Z, levels=5)
plt.show()```

Actual outcome

Expected outcome

According to official documentation I should expect 5 outlines and not the boundary associated with the value 5.

The expected output was obtained by modifying the penultimate line in:

`plt.contour(X, Y, Z, levels=np.linspace(np.min(Z),np.max(Z),7))`

Matplotlib version

• Operating system: Arch Linux
• Matplotlib version: 2.2.3
• Matplotlib backend (`print(matplotlib.get_backend())`): Qt5Agg
• Python version: 3.7.0
• Other libraries: `numpy`

All libraries have been installed via the official ArchLinux repository

Contributor

### jklymak commented Aug 22, 2018

 Yeah, this is a bit funky. It works fine if you do: `plt.contour(X, Y, Z, 5)`. So if you specify `levels` as a kwarg, it assumes you have entered the actual levels you want contoured. Its debatable if this is desirable or not - I'd vote for it being undesirable, and `levels=5` should behave as you expected it should (i.e. the same as if 5 was passed in as a positional argument), but maybe the original authors had a reason for this behaviour. I would say that `levels=[5]` should only make one contour.

Contributor

### jklymak commented Aug 22, 2018

 Milestoning 3.1, since this behaviour has been present since at least 2.0.2
Member

### tacaswell commented Aug 22, 2018

 I think @efiring changed some of this for 3.0 already.
Contributor

### jklymak commented Aug 22, 2018

 Well, yes. Its worse (?) on master: ``````Traceback (most recent call last): File "testCont.py", line 15, in plt.contour(X, Y, Z, levels=5) File "/Users/jklymak/matplotlib/lib/matplotlib/pyplot.py", line 2544, in contour __ret = gca().contour(*args, data=data, **kwargs) File "/Users/jklymak/matplotlib/lib/matplotlib/__init__.py", line 1763, in inner return func(ax, *args, **kwargs) File "/Users/jklymak/matplotlib/lib/matplotlib/axes/_axes.py", line 6209, in contour contours = mcontour.QuadContourSet(self, *args, **kwargs) File "/Users/jklymak/matplotlib/lib/matplotlib/contour.py", line 887, in __init__ kwargs = self._process_args(*args, **kwargs) File "/Users/jklymak/matplotlib/lib/matplotlib/contour.py", line 1499, in _process_args x, y, z = self._contour_args(args, kwargs) File "/Users/jklymak/matplotlib/lib/matplotlib/contour.py", line 1569, in _contour_args self._contour_level_args(z, args) File "/Users/jklymak/matplotlib/lib/matplotlib/contour.py", line 1255, in _contour_level_args if len(self.levels) > 1 and np.min(np.diff(self.levels)) <= 0.0: TypeError: len() of unsized object ``````
Member

### efiring commented Aug 22, 2018

 I see where the problem is.

### efiring added a commit to efiring/matplotlib that referenced this issue Aug 23, 2018

``` BUG: make arg 'N' and kwarg 'levels' behave the same when scalar ```
`Closes matplotlib#11913`
``` 6c6c506 ```

Merged