2

There is numpy.ma.masked_where for masking a a single value. And there is also numpy.ma.masked_inside for masking intervals.

However I don't quite understand how it is supposed to work.

I found this snippet:

import numpy.ma as M              
from pylab import *

figure()

xx = np.arange(-0.5,5.5,0.01) 
vals = 1/(xx-2)        
vals = M.array(vals)
mvals = M.masked_where(xx==2, vals)

subplot(121)
plot(xx, mvals, linewidth=3, color='red') 
xlim(-1,6)
ylim(-5,5) 

However, I would like to do something like this (Which does not work, I know):

mvals = M.masked_where(abs(xx) < 2.001 and abs(xx) > 1.999, vals)

Therefore I tried to use masked_inside like this :

mvals = ma.masked_inside(xx, 1.999, 2.001)

But the result is not what I wanted, it's just a straight line... I wanted something like this.

The entire script is this:

def f(x):
    return  (x**3 - 3*x) / (x**2 - 4)

figure()
xx = np.arange(begin, end, precision)
vals = [f(x) for x in xx]
vals = M.array(vals)
mvals = ma.masked_inside(xx, 1.999, 2.001)
subplot(121)
plot(xx, mvals, linewidth=1, c='red')
xlim(-4,4)
ylim(-4,4)
gca().set_aspect('equal', adjustable='box')
show()

How is masked_inside meant to be used correctly?

Community
  • 1
  • 1
lo tolmencre
  • 3,275
  • 17
  • 47

1 Answers1

2

The problem is not np.masked_inside but at which point and on which array you use it (you apply it on the values after you already applied your function!).

The np.ma.masked_inside is just a convenience wrapper around np.ma.masked_where:

def masked_inside(x, v1, v2, copy=True):
    # That's the actual source code
    if v2 < v1:
        (v1, v2) = (v2, v1)
    xf = filled(x)
    condition = (xf >= v1) & (xf <= v2)
    return masked_where(condition, x, copy=copy)

If you apply it like this:

import numpy as np
import matplotlib.pyplot as plt

def f(x):
    return  (x**3 - 3*x) / (x**2 - 4)

# linspace is much better suited than arange for such plots
x = np.linspace(-5, 5, 10000)
# mask the x values
mvals = np.ma.masked_inside(x, 1.999, 2.001)  
mvals = np.ma.masked_inside(mvals, -2.001, -1.999)  

# Instead of the masked_inside you could also use
# mvals = np.ma.masked_where(np.logical_and(abs(x) > 1.999, abs(x) < 2.001), x) 

# then apply the function
vals = f(mvals)                  

plt.figure()
plt.plot(x, vals, linewidth=1, c='red')
plt.ylim(-6, 6)

Then the output looks almost like the one you linked:

enter image description here

MSeifert
  • 118,681
  • 27
  • 271
  • 293
  • Ok thanks. But then the interface is different from `masked_where´, as there it is applied on the list of function values. – lo tolmencre Jan 17 '17 at 01:18
  • @lotolmencre I've edited the answer. `masked_inside` is just a wrapper around `masked_where` and saves you to compare them manually and do a "logical and" operation. – MSeifert Jan 17 '17 at 01:25