Trouble with contour plot

Benjamin Root <ben.root-GrrYUJ3DTa8@...1455...> writes:

Hello,

I'm having a weird problem with a contour plot. Consider the following
plots:

import cPickle as pickle
import matplotlib.pyplot as plt
(Theta, Phi, Bnormal) = pickle.load(open('trouble.pickle', 'rb'))
plt.figure(0)
for i in [0, 300]:
   plt.plot(Theta, Bnormal[:, i], label='Bnormal at Phi=%.3g' % Phi[i])

plt.ylabel('Theta')
plt.legend()
plt.savefig('figure0.png')
plt.figure(1)
plt.contourf(Phi, Theta, Bnormal)
plt.xlabel('Phi')
plt.ylabel('Theta')
plt.colorbar()
plt.savefig('figure1.png')

The 'trouble.pickle' file is available on
http://www.rath.org/trouble.pickle. At Phi=0 the contour plot agrees
with the crossection (both show an n=7 oscillation), but at Phi=1.68 the
contour plot shows a uniform value while the crossection shows a phase
shifted version of oscillation at Phi=0.

It seems to me that this is a blatant contradiction.

I have also uploaded the two figures at http://www.rath.org/figure1.png
and http://www.rath.org/figure0.png.

Am I missing something, or is this a bug?

$ python --version
Python 2.6.5
$ python -c 'import matplotlib; print matplotlib.__version__'
1.0.0

Thanks,

  -Nikolaus

Nikolaus,

What might be happening is that the Theta variable isn't monotonic. It
first goes from zero to pi, then from -pi to 0. This also explains the odd
lines that appear in the line plots at the top and bottom. Try reforming
your arrays so that the domain is monotonic (note that you will have to
adjust the Phi and the Bnormal arrays as well because they were arranged
assuming a certain domain from Theta.

Indeed, this was the problem. Thank you very much!

However, it seems to me that this is quite a serious bug. The contour
documentation on
http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.Axes.contour
does not mention this requirement, and obviously the contour method
itself does not even bother to check if its arguments are monotonically
increasing. Instead, it just *silently* produces garbage that in some
cases even looks like plausible data(!).

Am I missing something here? Otherwise I'll report this on the bug
tracker. I think this should be documented and contour() should check
its input and raise a ValueError if it's not monotonic.

Best,

   -Nikolaus

···

On Thu, Oct 28, 2010 at 3:31 PM, Nikolaus Rath <Nikolaus-BTH8mxji4b0@...1836...455...> wrote:

--
»Time flies like an arrow, fruit flies like a Banana.«

  PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C

Nikolaus,

You are right, the documentation is seriously lacking and woefully out-of-date. It still claims that it can not handle internal regions correctly with masked arrays (I am pretty sure that is fixed) and it says nothing of any characteristics of X and Y. I also don’t like how contourf() things are in the doc string for contour() and things that are for contour() are in contourf(). I wonder if we can do a much better job arranging this documentation.

I don’t know if there are any strict requirement on monotonicity for X and Y, or if there are any cases where the plot is still valid even if that property is violated. If it is a requirement, then I agree that there should be a check.

Ben Root

P.S. - I find that in many cases, contourf() is the wrong function to use for such plots, and find pcolor() (or one of its variants) to be better suited. Don’t know what is better for you in your case, but it might be something to investigate.

···

On Fri, Oct 29, 2010 at 7:44 AM, Nikolaus Rath <Nikolaus@…3333…2…> wrote:

Benjamin Root <ben.root-GrrYUJ3DTa8@…1455…> writes:

On Thu, Oct 28, 2010 at 3:31 PM, Nikolaus Rath <Nikolaus-BTH8mxji4b0@…1455…> wrote:

Hello,

I’m having a weird problem with a contour plot. Consider the following

plots:

import cPickle as pickle

import matplotlib.pyplot as plt

(Theta, Phi, Bnormal) = pickle.load(open(‘trouble.pickle’, ‘rb’))

plt.figure(0)

for i in [0, 300]:

plt.plot(Theta, Bnormal[:, i], label=‘Bnormal at Phi=%.3g’ % Phi[i])

plt.ylabel(‘Theta’)

plt.legend()

plt.savefig(‘figure0.png’)

plt.figure(1)

plt.contourf(Phi, Theta, Bnormal)

plt.xlabel(‘Phi’)

plt.ylabel(‘Theta’)

plt.colorbar()

plt.savefig(‘figure1.png’)

The ‘trouble.pickle’ file is available on

http://www.rath.org/trouble.pickle. At Phi=0 the contour plot agrees

with the crossection (both show an n=7 oscillation), but at Phi=1.68 the

contour plot shows a uniform value while the crossection shows a phase

shifted version of oscillation at Phi=0.

It seems to me that this is a blatant contradiction.

I have also uploaded the two figures at http://www.rath.org/figure1.png

and http://www.rath.org/figure0.png.

Am I missing something, or is this a bug?

$ python --version

Python 2.6.5

$ python -c ‘import matplotlib; print matplotlib.version

1.0.0

Thanks,

-Nikolaus

Nikolaus,

What might be happening is that the Theta variable isn’t monotonic. It

first goes from zero to pi, then from -pi to 0. This also explains the odd

lines that appear in the line plots at the top and bottom. Try reforming

your arrays so that the domain is monotonic (note that you will have to

adjust the Phi and the Bnormal arrays as well because they were arranged

assuming a certain domain from Theta.

Indeed, this was the problem. Thank you very much!

However, it seems to me that this is quite a serious bug. The contour

documentation on

http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.Axes.contour

does not mention this requirement, and obviously the contour method

itself does not even bother to check if its arguments are monotonically

increasing. Instead, it just silently produces garbage that in some

cases even looks like plausible data(!).

Am I missing something here? Otherwise I’ll report this on the bug

tracker. I think this should be documented and contour() should check

its input and raise a ValueError if it’s not monotonic.

Best,

-Nikolaus

I don't know if there are any strict requirement on monotonicity for X
and Y, or if there are any cases where the plot is still valid even if
that property is violated. If it is a requirement, then I agree that
there should be a check.

For sensible output, it is a requirement. Contour and contourf (like imshow, pcolor, and pcolormesh) work with gridded data. Gridding is the responsibility of the user. It can be done in many different ways, so it makes sense to keep the gridding separate from the display of the gridded data.

If there is a check--and I am not convinced there should be--it should provide only a warning. It is perfectly reasonable for a person to take a dataset and contour it even if the grid is not monotonic. Sometimes one wants to get a quick look at raw input, complete with errors.

Eric