Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to use `scipy.interpolate.RectBivariateSpline` with `matplotlib.pyplot,plot_surface`

I tried building a minimal example to reproduce a problem I was having. Please ignore the randomly generated data arrays x and y. I am feeding perfectly meaningful data into the zSpline call inside plot_surface. You could try replacing the penultimate line with - surf=ax.plot_surface(xg,yg,z,rstride=1,cstride=1,cmap=cm.coolwarm,linewidth=0.1) where I have replaced the ZSpline with the coarse data z. This works which indicates to me that I am not mistaken on syntax.

My code is-

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
from scipy.interpolate import RectBivariateSpline

size=21
dat = np.random.randn(size, 2)
x=dat[:,0]
y=dat[:,1]
z=np.random.randn(size//3,size//3)
i=np.tile([1,2,3],size//3)
bool_dat=(i==1)
x_new=x[bool_dat]
y_new=y[bool_dat]
xi=np.linspace(x_new.min(),x_new.max(),size//3)
yi=np.linspace(y_new.min(),y_new.max(),size//3)

#print z.shape,xi.shape,yi.shape

zSpline = RectBivariateSpline(xi,yi,z)

xg,yg = np.meshgrid(xi,yi)
print zSpline(xg,yg)
fig=plt.figure()
ax=fig.gca(projection='3d')
surf=ax.plot_surface(xg,yg,zSpline(xg,yg),rstride=1,cstride=1,cmap=cm.coolwarm,linewidth=0.1)
plt.show()

The error I get is -

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-a98e6c15985e> in <module>()
     22 
     23 xg,yg = np.meshgrid(xi,yi)
---> 24 print zSpline(xg,yg)
     25 fig=plt.figure()
     26 ax=fig.gca(projection='3d')

/usr/lib/python2.7/dist-packages/scipy/interpolate/fitpack2.pyc in __call__(self, x, y, mth)
    671             z,ier = dfitpack.bispev(tx,ty,c,kx,ky,x,y)
    672             if not ier == 0:
--> 673                 raise ValueError("Error code returned by bispev: %s" % ier)
    674             return z
    675         raise NotImplementedError('unknown method mth=%s' % mth)

ValueError: Error code returned by bispev: 10

Which leads me to believe that problem is with the interpolation routine and not the data/syntax. Any suggestions on how to test this further?

EDIT: In response to the comment that tells me that the problem is probably from the type of data, I decided to test with non-random data. the following code is almost the same as the first one - but I will paste it again anyway.

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
from scipy.interpolate import RectBivariateSpline

size=21
xi=np.linspace(-np.pi,np.pi,size)
yi=np.linspace(-np.pi,np.pi,size)

xg,yg = np.meshgrid(xi,yi)
z=np.sin(xg)*np.sin(yg) #nice and smooth function
zSpline = RectBivariateSpline(xi,yi,z,kx=2,ky=2)
fig=plt.figure()
ax=fig.gca(projection='3d')
surf=ax.plot_surface(xg,yg,z,rstride=1,cstride=1,cmap=cm.coolwarm,linewidth=0.1)
#surf=ax.plot_surface(xg,yg,zSpline(xg,yg),rstride=1,cstride=1,cmap=cm.coolwarm,linewidth=0.1)
plt.show()

This gives me the following image as output. plot with coarse data However if the zSpline is used, an error is raised.

EDIT2: The issue resolves itself if I use xg,yg = np.ogrid[-np.pi:np.pi:size*1j,-np.pi:np.pi:size*1j] instead of meshgrid. But I still do not know why!

like image 759
Debanjan Basu Avatar asked Mar 17 '23 15:03

Debanjan Basu


1 Answers

See the documentation.

The issue is that xg and yg you give to the spline are 2D arrays, but the routine expects them to be 1D arrays that define the grid (i.e. xi,yi).

like image 119
pv. Avatar answered Apr 07 '23 00:04

pv.