masking values in quiver plot

Hi all,

maybe I've misunderstood something concerning masking or quiver plots:
I want to exclude some data from a quiver plot. Here's an example:

--------------------8<----
import numpy as N
import pylab as pl
import matplotlib.numerix.ma as ma

# prepare data
X,Y = pl.meshgrid(range(5),range(5))
angles = pl.rand(5,5)
U = N.cos(angles)
V = N.sin(angles)

# prepare mask
M = N.zeros((5,5), dtype='bool')
M[2,2] = True

# apply mask
Um = ma.masked_array(U,mask=M)
Vm = ma.masked_array(V,mask=M)

# plot
pl.quiver(X,Y,Um,Vm)
# pl.plot(range(5),Um[2],'x')

pl.show()
---------------------->8----

Using the commented 'plot' command works as expected, but 'quiver' results in
empty axes. If I take U,V instead of Um,Vm, the arrows are drawn ..
What am I doing wrong or is there another way to exclude arrows from being
plotted?

  Thank you in advance,

    Michael

Michael Roettger wrote:

Hi all,

maybe I've misunderstood something concerning masking or quiver plots:
I want to exclude some data from a quiver plot. Here's an example:

--------------------8<----
import numpy as N
import pylab as pl
import matplotlib.numerix.ma as ma

# prepare data
X,Y = pl.meshgrid(range(5),range(5))
angles = pl.rand(5,5)
U = N.cos(angles)
V = N.sin(angles)

# prepare mask
M = N.zeros((5,5), dtype='bool')
M[2,2] = True

# apply mask
Um = ma.masked_array(U,mask=M)
Vm = ma.masked_array(V,mask=M)

# plot
pl.quiver(X,Y,Um,Vm)
# pl.plot(range(5),Um[2],'x')

pl.show()
---------------------->8----

Using the commented 'plot' command works as expected, but 'quiver' results in
empty axes. If I take U,V instead of Um,Vm, the arrows are drawn ..
What am I doing wrong or is there another way to exclude arrows from being
plotted?

  Thank you in advance,

    Michael
  
Michael: With 0.98.3, all the arrows are drawn - I don't see empty axes. However, the masked elements are not excluded, so I do think it's a bug.

-Jeff

···

--
Jeffrey S. Whitaker Phone : (303)497-6313
NOAA/OAR/CDC R/PSD1 FAX : (303)497-6449
325 Broadway Boulder, CO, USA 80305-3328

Michael Roettger wrote:

Hi all,

maybe I've misunderstood something concerning masking or quiver plots:
I want to exclude some data from a quiver plot. Here's an example:

--------------------8<----
import numpy as N
import pylab as pl
import matplotlib.numerix.ma as ma

# prepare data
X,Y = pl.meshgrid(range(5),range(5))
angles = pl.rand(5,5)
U = N.cos(angles)
V = N.sin(angles)

# prepare mask
M = N.zeros((5,5), dtype='bool')
M[2,2] = True

# apply mask
Um = ma.masked_array(U,mask=M)
Vm = ma.masked_array(V,mask=M)

# plot
pl.quiver(X,Y,Um,Vm)
# pl.plot(range(5),Um[2],'x')

pl.show()
---------------------->8----

Using the commented 'plot' command works as expected, but 'quiver' results in
empty axes. If I take U,V instead of Um,Vm, the arrows are drawn ..
What am I doing wrong or is there another way to exclude arrows from being
plotted?

  Thank you in advance,

    Michael

Michael: I've fixed this now in svn. If you don't want to update to svn trunk, you can make this simple change in quiver.py

--- lib/matplotlib/quiver.py (revision 6046)
+++ lib/matplotlib/quiver.py (working copy)
@@ -334,6 +334,12 @@
     def __init__(self, ax, *args, **kw):
         self.ax = ax
         X, Y, U, V, C = self._parse_args(*args)
+ if C is not None:
+ X, Y, U, V, C = delete_masked_points(X.ravel(),Y.ravel(),U.ravel(),
+ V.ravel(),C.ravel())
+ else:
+ X, Y, U, V = delete_masked_points(X.ravel(),Y.ravel(),U.ravel(),
+ V.ravel())
         self.X = X
         self.Y = Y
         self.XY = np.hstack((X[:,np.newaxis], Y[:,np.newaxis]))

-Jeff

···

--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg

Jeff Whitaker wrote:

Michael Roettger wrote:

Hi all,

maybe I've misunderstood something concerning masking or quiver plots:
I want to exclude some data from a quiver plot. Here's an example:

--------------------8<----
import numpy as N
import pylab as pl
import matplotlib.numerix.ma as ma

# prepare data
X,Y = pl.meshgrid(range(5),range(5))
angles = pl.rand(5,5)
U = N.cos(angles)
V = N.sin(angles)

# prepare mask
M = N.zeros((5,5), dtype='bool')
M[2,2] = True

# apply mask
Um = ma.masked_array(U,mask=M)
Vm = ma.masked_array(V,mask=M)

# plot
pl.quiver(X,Y,Um,Vm)
# pl.plot(range(5),Um[2],'x')

pl.show()
---------------------->8----

Using the commented 'plot' command works as expected, but 'quiver' results in
empty axes. If I take U,V instead of Um,Vm, the arrows are drawn ..
What am I doing wrong or is there another way to exclude arrows from being
plotted?

  Thank you in advance,

    Michael

Michael: I've fixed this now in svn. If you don't want to update to svn trunk, you can make this simple change in quiver.py

Jeff,

Thanks for the quick fix--it will help for now, and will work in most use cases, but it is not actually correct in general. The problem is that quiver supports input of changed values of U, V, and C on the existing X, Y grid, and these changed values can be masked arrays with different points masked. (See Quiver.set_UVC().) That is why I did not use delete_masked_points in the first place. Masked values used to be handled correctly; I suspect the bug is actually in collections, not in quiver itself. I can't track it down right now, but may be able to look at it over the weekend.

Eric

···

--- lib/matplotlib/quiver.py (revision 6046)
+++ lib/matplotlib/quiver.py (working copy)
@@ -334,6 +334,12 @@
     def __init__(self, ax, *args, **kw):
         self.ax = ax
         X, Y, U, V, C = self._parse_args(*args)
+ if C is not None:
+ X, Y, U, V, C = delete_masked_points(X.ravel(),Y.ravel(),U.ravel(),
+ V.ravel(),C.ravel())
+ else:
+ X, Y, U, V = delete_masked_points(X.ravel(),Y.ravel(),U.ravel(),
+ V.ravel())
         self.X = X
         self.Y = Y
         self.XY = np.hstack((X[:,np.newaxis], Y[:,np.newaxis]))

-Jeff

Eric Firing wrote:

Jeff Whitaker wrote:

Michael Roettger wrote:

Hi all,

maybe I've misunderstood something concerning masking or quiver plots:
I want to exclude some data from a quiver plot. Here's an example:

--------------------8<----
import numpy as N
import pylab as pl
import matplotlib.numerix.ma as ma

# prepare data
X,Y = pl.meshgrid(range(5),range(5))
angles = pl.rand(5,5)
U = N.cos(angles)
V = N.sin(angles)

# prepare mask
M = N.zeros((5,5), dtype='bool')
M[2,2] = True

# apply mask
Um = ma.masked_array(U,mask=M)
Vm = ma.masked_array(V,mask=M)

# plot
pl.quiver(X,Y,Um,Vm)
# pl.plot(range(5),Um[2],'x')

pl.show()
---------------------->8----

Using the commented 'plot' command works as expected, but 'quiver' results in
empty axes. If I take U,V instead of Um,Vm, the arrows are drawn ..
What am I doing wrong or is there another way to exclude arrows from being
plotted?

  Thank you in advance,

    Michael

Michael: I've fixed this now in svn. If you don't want to update to svn trunk, you can make this simple change in quiver.py

Jeff,

Thanks for the quick fix--it will help for now, and will work in most use cases, but it is not actually correct in general. The problem is that quiver supports input of changed values of U, V, and C on the existing X, Y grid, and these changed values can be masked arrays with different points masked. (See Quiver.set_UVC().) That is why I did not use delete_masked_points in the first place. Masked values used to be handled correctly; I suspect the bug is actually in collections, not in quiver itself. I can't track it down right now, but may be able to look at it over the weekend.

Eric

OK Eric - I figured you'd chime in when you got a chance. Let's consider it a temporary workaround then. BTW: I updated the quiver_demo.py example to test the masking.

-Jeff

···

--- lib/matplotlib/quiver.py (revision 6046)
+++ lib/matplotlib/quiver.py (working copy)
@@ -334,6 +334,12 @@
     def __init__(self, ax, *args, **kw):
         self.ax = ax
         X, Y, U, V, C = self._parse_args(*args)
+ if C is not None:
+ X, Y, U, V, C = delete_masked_points(X.ravel(),Y.ravel(),U.ravel(),
+ V.ravel(),C.ravel())
+ else:
+ X, Y, U, V = delete_masked_points(X.ravel(),Y.ravel(),U.ravel(),
+ V.ravel())
         self.X = X
         self.Y = Y
         self.XY = np.hstack((X[:,np.newaxis], Y[:,np.newaxis]))

-Jeff

--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg

Jeff Whitaker wrote:

Eric Firing wrote:

Jeff Whitaker wrote:

Michael Roettger wrote:

Hi all,

maybe I've misunderstood something concerning masking or quiver plots:
I want to exclude some data from a quiver plot. Here's an example:

--------------------8<----
import numpy as N
import pylab as pl
import matplotlib.numerix.ma as ma

# prepare data
X,Y = pl.meshgrid(range(5),range(5))
angles = pl.rand(5,5)
U = N.cos(angles)
V = N.sin(angles)

# prepare mask
M = N.zeros((5,5), dtype='bool')
M[2,2] = True

# apply mask
Um = ma.masked_array(U,mask=M)
Vm = ma.masked_array(V,mask=M)

# plot
pl.quiver(X,Y,Um,Vm)
# pl.plot(range(5),Um[2],'x')

pl.show()
---------------------->8----

Using the commented 'plot' command works as expected, but 'quiver' results in
empty axes. If I take U,V instead of Um,Vm, the arrows are drawn ..
What am I doing wrong or is there another way to exclude arrows from being
plotted?

  Thank you in advance,

    Michael

Michael: I've fixed this now in svn. If you don't want to update to svn trunk, you can make this simple change in quiver.py

Jeff,

Thanks for the quick fix--it will help for now, and will work in most use cases, but it is not actually correct in general. The problem is that quiver supports input of changed values of U, V, and C on the existing X, Y grid, and these changed values can be masked arrays with different points masked. (See Quiver.set_UVC().) That is why I did not use delete_masked_points in the first place. Masked values used to be handled correctly; I suspect the bug is actually in collections, not in quiver itself. I can't track it down right now, but may be able to look at it over the weekend.

Eric

OK Eric - I figured you'd chime in when you got a chance. Let's consider it a temporary workaround then. BTW: I updated the quiver_demo.py example to test the masking.

Very useful, thank you. I have removed the workaround and made a more consistent repair to the masked array handling. The problem came in when PolyCollection was changed to automatically close the path by default.

Eric

···

-Jeff

--- lib/matplotlib/quiver.py (revision 6046)
+++ lib/matplotlib/quiver.py (working copy)
@@ -334,6 +334,12 @@
     def __init__(self, ax, *args, **kw):
         self.ax = ax
         X, Y, U, V, C = self._parse_args(*args)
+ if C is not None:
+ X, Y, U, V, C = delete_masked_points(X.ravel(),Y.ravel(),U.ravel(),
+ V.ravel(),C.ravel())
+ else:
+ X, Y, U, V = delete_masked_points(X.ravel(),Y.ravel(),U.ravel(),
+ V.ravel())
         self.X = X
         self.Y = Y
         self.XY = np.hstack((X[:,np.newaxis], Y[:,np.newaxis]))

-Jeff