Problems interpolating and evaluating numpy array at arbitrary points with Scipy - python

I am trying to replicate some of the functionality of Matlab's interp2. I know somewhat similar questions have been asked before, but none apply to my specific case.
I have a distance map (available at this Google drive location):
https://drive.google.com/open?id=0B6acq_amk5e3X0Q5UG1ya1VhSlE&authuser=0
Values are normalized in the range 0-1. Size is 200 rows by 300 columns.
I can load it up with this code snippet:
import numpy as np
dstnc1=np.load('dstnc.npy')
Coordinates are defined by the next snippet:
xmin = 0.
xmax = 9000.
ymin = 0.
ymax = 6000.
r1,c1 = dstnc1.shape
x = np.linspace(xmin,xmax,c1)
y = np.linspace(ymin, ymax,r1)
I have three map points defined by vectors xnew1, ynew1 with this snippet:
xnew1=[3700.540199,3845.940199,3983.240199]
ynew1=[1782.8611,1769.862,1694.862]
I check their location with respect to the distance map with this:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(20, 16))
ax = fig.add_subplot(1, 1, 1)
plt.imshow(dstnc1, cmap=my_cmap_r,vmin=0,vmax=0.3,
extent=[0, 9000, 0, 6000], origin='upper')
plt.scatter(xnew1, ynew1, s=50, linewidths=0.15)
plt.show()
They plot in the correct location. Now I would like to extract the
distance value at those three points. I tried first interp2d.
from scipy.interpolate import interp2d
x1 = np.linspace(xmin,xmax,c1)
y1 = np.linspace(ymin,ymax,r1)
f = interp2d(x1, y1, dstnc1, kind='cubic')
but when I try to evaluate with:
test=f(xnew1,ynew1)
I get this error:
--------------------
ValueError Traceback (most recent call last)
<ipython-input-299-d0f42e609b23> in <module>()
----> 1 test=f(xnew1,ynew1)
C:\...\AppData\Local\Continuum\Anaconda\lib\site-packages\scipy\interpolate\interpolate.pyc
in __call__(self, x, y, dx, dy)
270 (self.y_min, self.y_max)))
271
--> 272 z = fitpack.bisplev(x, y, self.tck, dx, dy)
273 z = atleast_2d(z)
274 z = transpose(z)
C:\...\AppData\Local\Continuum\Anaconda\lib\site-packages\scipy\interpolate\fitpack.pyc
in bisplev(x, y, tck, dx, dy)
1027 z,ier = _fitpack._bispev(tx,ty,c,kx,ky,x,y,dx,dy)
1028 if ier == 10:
-> 1029 raise ValueError("Invalid input data")
1030 if ier:
1031 raise TypeError("An error occurred")
ValueError: Invalid input data
If I try RectBivariateSpline:
from scipy.interpolate import RectBivariateSpline
x2 = np.linspace(xmin,xmax,r1)
y2 = np.linspace(ymin,ymax,c1)
f = RectBivariateSpline(x2, y2, dstnc1)
I get this error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-302-d0f42e609b23> in <module>()
----> 1 test=f(xnew1,ynew1)
C:\...\AppData\Local\Continuum\Anaconda\lib\site-packages\scipy\interpolate\fitpack2.pyc
in __call__(self, x, y, mth, dx, dy, grid)
643 z,ier = dfitpack.bispev(tx,ty,c,kx,ky,x,y)
644 if not ier == 0:
--> 645 raise ValueError("Error code returned by
bispev: %s" % ier)
646 else:
647 # standard Numpy broadcasting
ValueError: Error code returned by bispev: 10
Any suggestion as to whether I am using the wrong functions or the right
function with wrong syntax, and how I may fix it is appreciated. Thank you.
UPDATE
I am running Python 2.7.9 and Scipy 0.14.0 (on Continuum Anaconda)
As posted on the Scipy mailing list here the documentation seems confusing, being a mix of Scipy 0.14.0, and the next version. Can anybody suggest a workaround or the correct syntax for version 0.14.0.
UPDATE 2
tried
xnew1=np.array([3700.540199,3845.940199,3983.240199])
ynew1=np.array([1782.8611,1769.862,1694.862])
as suggested inj a comment but the error remains.

This syntax worked with RectBivariateSpline
x2 = np.linspace(xmin,xmax,c1)
y2 = np.linspace(ymin,ymax,r1)
f2 = sp.interpolate.RectBivariateSpline(x2, y2, dstnc1.T,kx=1, ky=1)
I can then evaluate at new points with this:
out2 = f2.ev(xnew1,ynew1)
For interp2d I am stuck as I am not able to bypass firewall at my office to update Anaconda (Windows). I may be able at home on a Mac installation, in which case, if I get the syntax right, I will add to thsi answer.

Related

typeerror for function defined

I am trying to plot a 2D heat map of the function/surface but it is throwing me the type error which I am unable to resolve..
from numbers import Real
from numpy.lib.type_check import real
x = np.linspace(-2,2, num=40, endpoint=True, retstep=False, dtype=None, axis=0)
y = np.linspace(-2,2, num=40, endpoint=True, retstep=False, dtype=None, axis=0)
`
def goldstein_func(x,y):
z = (1+(x+y+1)**2*(19-14*x+3*x**2-14*y+6*x*y+3*y**2))*(30+(2*x-3*y)**2*(18-32*x+12*x**2+48*y-36*x*y+27*y**2))
m = np.array(x,y)
plt.imshow(goldstein_func(x,y), 4)
plt.show()
**The above code throw in an error below:
TypeError Traceback (most recent call last)
in
----> 2 plt.imshow(goldstein_func(x,y), 4)
3 plt.show()
in goldstein_func(x, y)
10 z = (1+(x+y+1)**2*(19-14*x+3*x**2-14*y+6*x*y+3*y**2))*(30+(2*x-3*y)**2*(18-32*x+12*x**2+48*y-36*x*y+27*y**2))
---> 11 m = np.array(x,y)
TypeError: Cannot construct a dtype from an array**
I tried to fix the type-error
It appears that an issue is happening when attempting to construct a NumPy array with np.array(x, y) inside the goldstein_func() function. The np.array() function needs one argument that symbolizes the components of the array or several arguments that symbolizes multiple arrays to be combined. Nevertheless, in your code, you're supplying two independent arguments, x and y, which is producing the TypeError.
To fix the mistake, you can use the np.meshgrid function to create 2-D arrays from the 1-D arrays x and y, and then pass these arrays into the goldstein_func to calculate the matching z values. Here's the adjusted code:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2, 2, num=40, endpoint=True)
y = np.linspace(-2, 2, num=40, endpoint=True)
X, Y = np.meshgrid(x, y)
def goldstein_func(x, y):
z = (1+(x+y+1)**2*(19-14*x+3*x**2-14*y+6*x*y+3*y**2))*(30+(2*x-3*y)**2*(18-32*x+12*x**2+48*y-36*x*y+27*y**2))
return z
Z = goldstein_func(X, Y)
plt.imshow(Z, cmap='hot', extent=(-2, 2, -2, 2))
plt.show()
I hope this helps you out.

Index Error: Index 206893 is out of bounds for axis 0 with size 206893, griddata issue

I have an issue for the last 4 days trying to understand a python error:
`enter code here`IndexError: index 206893 is out of bounds for axis 0 with size 206893
when applying, griddata and "nearest" interpolation method using the following lines:
create a matrix where I will store the first interpolated file
tempnew = np.ones((np.asarray(w1[0,0,:,:]).shape))*np.nan
The lon, lat coordinate points of the original grid
lonl,latl = np.meshgrid(lon,lat)
points = np.vstack((np.array(lonl).flatten(),np.array(latl).flatten())).transpose()
The values of the original file
values = np.array([np.asarray(temp[0,0,:,:])]).flatten()
The dimensions of the grid that I want to interpolate to
lons = np.array(nav_lon)
lats = np.array(nav_lat)
X,Y = np.meshgrid(lons,lats)
Interpolation
tempnew = griddata(points,values, (X,Y), method = "nearest",fill_value=-3)
Here the dimension of each of the variables that I use above:
#tempnew.shape: (728, 312) #(Dimensions of tempnew is (lats,lons))
#lat.shape: (661,) #(original latitude)
#lon.shape: (313,) #(original longitude)
#points.shape: (206893, 2)
#values.shape: (206893,)
#X.shape: (728, 312)
#Y.shape: (728, 312)
Can you help me? * I would like to note here that the original file grid is regular (A-type) grid data whereas the grid to which I want to interpolate to is not regular (C-grid data)
The error looks like this:
In [36]: tempnew = sp.interpolate.griddata(points,values, (X,Y), method = "nearest
...: ",fill_value=-3)
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-36-0d0b46a3542f> in <module>
----> 1 tempnew = sp.interpolate.griddata(points,values, (X,Y), method =
"nearest",fill_value=-3)
~/software/anaconda3/envs/mhw/lib/python3.7/site-packages/scipy/interpolate/ndgriddata.py in
griddata(points, values, xi, method, fill_value, rescale)
217 elif method == 'nearest':
218 ip = NearestNDInterpolator(points, values, rescale=rescale)
--> 219 return ip(xi)
220 elif method == 'linear':
221 ip = LinearNDInterpolator(points, values, fill_value=fill_value,
~/software/anaconda3/envs/mhw/lib/python3.7/site-packages/scipy/interpolate/ndgriddata.py in
__call__(self, *args)
79 xi = self._scale_x(xi)
80 dist, i = self.tree.query(xi)
---> 81 return self.values[i]
82
83
IndexError: index 206893 is out of bounds for axis 0 with size 206893
Thanks in advance,
Sofi
I encountered this error in my Python code using the scipy.interpolate.NearestNDInterpolator class. The error message that is returned is not very clear. In the end, I found that one of the values I was inserting into my interpolant had a value of 1e184 and caused this error message. After resetting this value to 0.0, my Python script ran successfully.

matplotlib streamplot error for a specific number of gridpoints

The following minimal code snippet fails when n=29 but works when n=28 or n=30.
import numpy
import matplotlib.pyplot as plt
x = np.linspace(0,1,n)
plt.streamplot(x,x,np.meshgrid(x,x)[0],np.meshgrid(x,x)[1])
plt.show()
The error given when n=29 is
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
~/.local/lib/python3.6/site-packages/matplotlib/streamplot.py in _integrate_rk12(x0, y0, dmap, f, maxlength)
526 try:
--> 527 k1x, k1y = f(xi, yi)
528 k2x, k2y = f(xi + ds * k1x,
~/.local/lib/python3.6/site-packages/matplotlib/streamplot.py in backward_time(xi, yi)
434 def backward_time(xi, yi):
--> 435 dxi, dyi = forward_time(xi, yi)
436 return -dxi, -dyi
~/.local/lib/python3.6/site-packages/matplotlib/streamplot.py in forward_time(xi, yi)
425 def forward_time(xi, yi):
--> 426 ds_dt = interpgrid(speed, xi, yi)
427 if ds_dt == 0:
~/.local/lib/python3.6/site-packages/matplotlib/streamplot.py in interpgrid(a, xi, yi)
619 a00 = a[y, x]
--> 620 a01 = a[y, xn]
621 a10 = a[yn, x]
~/.local/lib/python3.6/site-packages/numpy/ma/core.py in __getitem__(self, indx)
3196 # So it's easier to stick to the current version
-> 3197 dout = self.data[indx]
3198 _mask = self._mask
IndexError: index 29 is out of bounds for axis 1 with size 29
This has been driving me crazy for a while. The plots are generated when n=28 or n=30. I even checked the code on google collab to make sure that I did not screw up my libraries somehow.
Here's the link
Any idea as to why this is happening?
This is because of an indexing error in the matplotlib 2.2.x series. Solved in matplotlib 3.x with this patch. The github issue for the bug I created is here. The patch might get backported to 2.2.x

Match filtering in Python

I'm trying to do a simple match filtering operation on a data set in python (so I tried doing conjugation followed by convolution). However, an error message is showing in the convolution function saying object too deep for desired array. Below is the code I'm using:
import numpy as np
import cPickle
import matplotlib.pyplot as plt
with open('meteor2.pkl', 'rb') as f:
data = cPickle.load(f)
vlt = data['vlt']
mfilt=np.conjugate(vlt)
mfilt1=np.convolve(vlt,mfilt,mode='full')
#mfilt=np.conjugate(vlt)
#mfilt1=np.convolve(vlt,mfilt,'same')
r = data['r']
t = data['t']
codes = data['codes']
freqs = data['freqs']
ch0_db = 10*np.log10(np.abs(mfilt1[:, 0, :])**2)
plt.figure()
plt.imshow(ch0_db.T, vmin=0, origin='lower', cmap=plt.cm.coolwarm,aspect='auto')
plt.title('All pulses')
plt.figure()
plt.imshow(ch0_db[3::5, :].T, vmin=0, origin='lower', cmap=plt.cm.coolwarm,aspect='auto')
plt.title('Minimum sidelobe coded-pulses')
plt.show()
np.convolve does one-dimensional convolution, so in this line:
mfilt1=np.convolve(vlt,mfilt,mode='full')
you'll get that error if either vlt or mfilt is not 1-D. For example,
In [12]: x = np.array([[1,2,3]]) # x is 2-D
In [13]: y = np.array([1,2,3])
In [14]: np.convolve(x, y, mode='full')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-14-9bf37a14877a> in <module>()
----> 1 np.convolve(x, y, mode='full')
/home/warren/anaconda/lib/python2.7/site-packages/numpy/core/numeric.pyc in convolve(a, v, mode)
822 raise ValueError('v cannot be empty')
823 mode = _mode_from_name(mode)
--> 824 return multiarray.correlate(a, v[::-1], mode)
825
826 def outer(a,b):
ValueError: object too deep for desired array
It looks like you want 2-D (or higher) convolution. scipy has a few options:
scipy.ndimage.convolve
scipy.signal.convolve
scipy.signal.convolve2d

Vector/array output from `scipy.ndimage.map_coordinates`

Basically, is it possible to get scipy.ndimage.map_coordinates to return a multi-valued structure, instead of just a scalar? I'd like to be able to interpolate once to retrieve 5 values at a point, rather than having to interpolate 5 times.
Here's my try at a MWE to demonstrate the problem. I'll start with a 3D interpolation of a scalar. I won't go between points for now because that's not the point.
import numpy as np
from scipy import ndimage
coords = np.array([[1.,1.,1.]])
a = np.arange(3*3*3).reshape(3,3,3)
ndimage.map_coordinates(a,coords.T) # array([13.])
Now, suppose I want a to have pairs of values, not just one. My instinct is
a = np.arange(3*3*3*2).reshape(3,3,3,2)
a[1,1,1] # array([26.,27.])
ndimage.map_coordinates(a[:,:,:],coords.T) # I'd like array([26.,27.])
Instead of the desired output, I get the following:
RuntimeError Traceback (most recent call last)
(...)/<ipython-input-84-77334fb7469f> in <module>()
----> 1 ndimage.map_coordinates(a[:,:,:],np.array([[1.,1.,1.]]).T)
/usr/lib/python2.7/dist-packages/scipy/ndimage/interpolation.pyc in map_coordinates(input, coordinates, output, order, mode, cval, prefilter)
287 raise RuntimeError('input and output rank must be > 0')
288 if coordinates.shape[0] != input.ndim:
--> 289 raise RuntimeError('invalid shape for coordinate array')
290 mode = _extend_mode_to_code(mode)
291 if prefilter and order > 1:
RuntimeError: invalid shape for coordinate array
I can't find a permutation of the shapes of any of the structures (a, coords, etc.) that gives me the answer I'm looking for. Also, if there's a better way to do this than using map_coordinates, go ahead. I thought scipy.interpolate.interp1d might be the way to go but I can't find any documentation or an inkling of what it might do...
That's not possible, I think.
But tensor product interpolation is not difficult:
import numpy as np
from scipy.interpolate import interp1d
def interpn(*args, **kw):
"""Interpolation on N-D.
ai = interpn(x, y, z, ..., a, xi, yi, zi, ...)
where the arrays x, y, z, ... define a rectangular grid
and a.shape == (len(x), len(y), len(z), ...)
"""
method = kw.pop('method', 'cubic')
if kw:
raise ValueError("Unknown arguments: " % kw.keys())
nd = (len(args)-1)//2
if len(args) != 2*nd+1:
raise ValueError("Wrong number of arguments")
q = args[:nd]
qi = args[nd+1:]
a = args[nd]
for j in range(nd):
a = interp1d(q[j], a, axis=j, kind=method)(qi[j])
return a
import matplotlib.pyplot as plt
x = np.linspace(0, 1, 6)
y = np.linspace(0, 1, 7)
k = np.array([0, 1])
z = np.cos(2*x[:,None,None] + k[None,None,:]) * np.sin(3*y[None,:,None])
xi = np.linspace(0, 1, 60)
yi = np.linspace(0, 1, 70)
zi = interpn(x, y, z, xi, yi, method='linear')
plt.subplot(221)
plt.imshow(z[:,:,0].T, interpolation='nearest')
plt.subplot(222)
plt.imshow(zi[:,:,0].T, interpolation='nearest')
plt.subplot(223)
plt.imshow(z[:,:,1].T, interpolation='nearest')
plt.subplot(224)
plt.imshow(zi[:,:,1].T, interpolation='nearest')
plt.show()

Categories

Resources