Problem interpolating using RBF from python's scipy - python

I am following the accepted answer of this thread using my ownd gridded data.
I load it as:
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
import pylab as py
token = open('Ydata_48_of_50.txt','r')
linestoken=token.readlines()
tokens_column_numberX = 0
resulttokenX=[]
for x in linestoken:
resulttokenX.append(x.split()[tokens_column_numberX])
token.close()
resulttokenX = np.array(resulttokenX)
(I do the same for Y and F(X, Y)) and then, I use what is displayed in the aforementioned link:
xi, yi = np.linspace(resulttokenX.min(), resulttokenX.max(), 200), np.linspace(resulttokenY.min(), resulttokenY.max(), 200)
xi, yi = np.meshgrid(xi, yi)
# Interpolate
rbf = scipy.interpolate.Rbf(resulttokenX, resulttokenY, resulttokenF, function='linear')
Unfortunately, the last line here is an error. I get
xi, yi = np.linspace(resulttokenX2.min(), resulttokenX2.max(), 200), np.linspace(resulttokenY2.min(), resulttokenY2.max(), 200)
File "D:\Users\me\anaconda3\lib\site-packages\numpy\core\_methods.py", line 43, in _amin
return umr_minimum(a, axis, None, out, keepdims, initial, where)
TypeError: cannot perform reduce with flexible type
I have no idea why this happens, since in the original code x appears in the last line and is
type(x)
Out[26]: numpy.ndarray
which is the same type of variable as
type(resulttokenX2)
Out[24]: numpy.ndarray
I don't know why this happens. Can someone tell me what I have to do to reproduce the original code with my gridded data instead of random?
Thanks.
Edit:
resulttokenY2
Out[3]:
array(['3.2000000e+01', '3.2000000e+01',
are the first lines of resulttokenY2

After some very helpful advice from Yann ziselman I have managed to do it. This is the full code:
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
import pylab as py
import scipy
token = open('Ydata_48_of_50.txt','r')
linestoken=token.readlines()
tokens_column_numberX = 0
tokens_column_numberY = 1
tokens_column_numberF = 2
resulttokenX=[]
resulttokenY=[]
resulttokenF=[]
for x in linestoken:
resulttokenX.append(x.split()[tokens_column_numberX])
resulttokenY.append(x.split()[tokens_column_numberY])
resulttokenF.append(x.split()[tokens_column_numberF])
token.close()
resulttokenX2 = np.array(resulttokenX)
resulttokenY2 = np.array(resulttokenY)
resulttokenF2 = np.array(resulttokenF)
# Set up a regular grid of interpolation points
xi, yi = np.linspace(resulttokenX2.astype('float').min(), resulttokenX2.astype('float').max(), 100), np.linspace(resulttokenY2.astype('float').min(), resulttokenY2.astype('float').max(), 100)
xi, yi = np.meshgrid(xi, yi)
# Interpolate
rbf = scipy.interpolate.Rbf(resulttokenX2, resulttokenY2, resulttokenF2, function='linear')
zi = rbf(xi, yi)
plt.imshow(zi, vmin=resulttokenF2.astype('float').min(), vmax=resulttokenF2.astype('float').max(), origin='lower', extent=[resulttokenX2.astype('float').min(), resulttokenX2.astype('float').max(), resulttokenY2.astype('float').min(), resulttokenY2.astype('float').max()])
plt.scatter(resulttokenX2.astype('float'), resulttokenY2.astype('float'), c=resulttokenF2.astype('float'))
plt.colorbar()
plt.show()

Related

Plotting Taylor series expansions from Sympy in MatPlotLib [duplicate]

i´am trying to plot the function sin(x)/x and a taylor approximation of it.
i use python 3 and pyzo - the first plot works but i have problems converting the series coming from the sympy module to an numpy expression that would work.
import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from sympy.abc import x
x = np.linspace(-10, 10, 100)
y = np.sin(x)/x #first function
plt.plot(x, y, 'k') #this is working fine
### this is a code that removes the "0(x**something)" part of
the series at the end
i found it here http://pastebin.com/ZNQakWP7
def series(expr, x, x0, n, removeO=False):
"""
sympy bugs avoided
"""
# expr_series = expr.series(x, x0, n)
# return expr_series.removeO() if removeO else expr_series
expansion = list()
for t in expr.lseries(x, x0):
p = t.as_coeff_exponent(x)[1]
if p < n:
expansion.append(t)
else:
break
if not removeO:
expansion.append(sp.O(x**n))
return sp.Add(*expansion)
### my code continued ####
y_t=series(sp.sin(x)/x,x,0,6,removeO=True)
if i look at y_t now i get this approximation
out: x**4/120 - x**2/6 + 1
Now i try to convert this to numpy in order to plot it as i did with the first function.
f_t = lambdify(x, y_t,modules=['numpy'])
x = np.linspace(-10, 10, 100) #i do this because x has
#been a symbolic variable before
plt.plot(x, y_t, 'b') #this is where the problem occurs
i get the first plot also a second error message:
File "<console>", line 1, in <module>
File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\pyplot.py", line 2832, in plot
ret = ax.plot(*args, **kwargs)
File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\axes.py", line 3998, in plot
for line in self._get_lines(*args, **kwargs):
How can i achieve my idea to plot something coming from sympy?
Another idea i had was to convert the sympy out from the series to a string and then parsing this somehow to a numpy expression. I would be thankful for any help here!
I think your problem is that this:
plt.plot(x, y_t, 'b') #this is where the problem occurs
should be something like:
plt.plot(x, f_t(x), 'b')
f_t is the lambdified series, so it is a callable function that evaluates its argument.
I used lambdify in the following example, and it works for me:
from sympy.abc import x
from sympy import sin, series
from sympy.utilities.lambdify import lambdify
import numpy as np
import matplotlib.pyplot as plt
func = sin(x)/x
taylor = series(func, n=6).removeO()
evalfunc = lambdify(x, func, modules=['numpy'])
evaltaylor = lambdify(x, taylor, modules=['numpy'])
t = np.linspace(-5.5, 5.5, 100)
plt.plot(t, evalfunc(t), 'b', label='sin(x)/x')
plt.plot(t, evaltaylor(t), 'r', label='Taylor')
plt.legend(loc='best')
plt.show()
Here's the plot generated by the script.

Python Scipy Interpolate Griddata - How do i extract X,Y,Z data out griddata based interpolation in Python

I have a set of x,y,z data on an irregular grid. I tried to interpolate the same on a regular grid using griddata. Now, how can i extract the output (X,Y,Z) to a file in Python. Any help is much appreciated.
The code is as shown below
import numpy as np
import matplotlib.pyplot as plt
import numpy.ma as ma
from numpy.random import uniform
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
# Read data from an existing dataframe
x = df['X']
y = df['Y']
z = df['WD']
# define grid.
xi = np.linspace(-4900,6000,100)
yi = np.linspace(-5200,7700,100)
# grid the data.
zi = griddata((x, y), z, (xi[None,:], yi[:,None]), method='cubic')
xn=[]
yn=[]
l=1
for i in range(0, len(xi)):
for j in range(0, len(yi)):
xn[l]=xi[i]
yn[l]=yi[j]
l=l+1
d = np.vstack((xn,yn,zi))
np.savetxt("file.csv", d, delimiter=",", fmt='% 4d')
Apparently this method works tills extracting the zi values using griddata, and not beyond that.
I am trying to extract the xi,yi,zi from the griddata and write this information to a file to be used by another program.
Can anyone advice on how to go about it?

Algorithm equalivence from Matlab to Python

I've plotted a 3-d mesh in Matlab by below little m-file:
[x,n] = meshgrid(0:0.1:20, 1:1:100);
mu = 0;
sigma = sqrt(2)./n;
f = normcdf(x,mu,sigma);
mesh(x,n,f);
I am going to acquire the same result by utilization of Python and its corresponding modules, by below code snippet:
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as plt
sigma = 1
def integrand(x, n):
return (n/(2*sigma*np.sqrt(np.pi)))*np.exp(-(n**2*x**2)/(4*sigma**2))
tt = np.linspace(0, 20, 2000)
nn = np.linspace(1, 100, 100)
T = np.zeros([len(tt), len(nn)])
for i,t in enumerate(tt):
for j,n in enumerate(nn):
T[i, j], _ = quad(integrand, -np.inf, t, args=(n,))
x, y = np.mgrid[0:20:0.01, 1:101:1]
plt.pcolormesh(x, y, T)
plt.show()
But the output of the Python is is considerably different with the Matlab one, and as a matter of fact is unacceptable.
I am afraid of wrong utilization of the functions just like linespace, enumerate or mgrid...
Does somebody have any idea about?!...
PS. Unfortunately, I couldn't insert the output plots within this thread...!
Best
..............................
Edit: I changed the linespace and mgrid intervals and replaced plot_surface method... The output is 3d now with the suitable accuracy and smoothness...
From what I see the equivalent solution would be:
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
x, n = np.mgrid[0:20:0.01, 1:100:1]
mu = 0
sigma = np.sqrt(2)/n
f = norm.cdf(x, mu, sigma)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(x, n, f, rstride=x.shape[0]//20, cstride=x.shape[1]//20, alpha=0.3)
plt.show()
Unfortunately 3D plotting with matplotlib is not as straight forward as with matlab.
Here is the plot from this code:
Your Matlab code generate 201 points through x:
[x,n] = meshgrid(0:0.1:20, 1:1:100);
While your Python code generate only 20 points:
tt = np.linspace(0, 19, 20)
Maybe it's causing accuracy problems?
Try this code:
tt = np.linspace(0, 20, 201)
The seminal points to resolve the problem was:
1- Necessity of the equivalence regarding the provided dimensions of the linespace and mgrid functions...
2- Utilization of a mesh with more density to make a bee line into a high degree of smoothness...
3- Application of a 3d plotter function, like plot_surf...
The current code is totally valid...

resampled time using scipy.signal.resample

I have a signal that is not sampled equidistant; for further processing it needs to be. I thought that scipy.signal.resample would do it, but I do not understand its behavior.
The signal is in y, corresponding time in x.
The resampled is expected in yy, with all corresponding time in xx. Does anyone know what I do wrong or how to achieve what I need?
This code does not work: xx is not time:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
x = np.array([0,1,2,3,4,5,6,6.5,7,7.5,8,8.5,9])
y = np.cos(-x**2/4.0)
num=50
z=signal.resample(y, num, x, axis=0, window=None)
yy=z[0]
xx=z[1]
plt.plot(x,y)
plt.plot(xx,yy)
plt.show()
Even when you give the x coordinates (which corresponds to the t argument), resample assumes that the sampling is uniform.
Consider using one of the univariate interpolators in scipy.interpolate.
For example, this script:
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
x = np.array([0,1,2,3,4,5,6,6.5,7,7.5,8,8.5,9])
y = np.cos(-x**2/4.0)
f = interpolate.interp1d(x, y)
num = 50
xx = np.linspace(x[0], x[-1], num)
yy = f(xx)
plt.plot(x,y, 'bo-')
plt.plot(xx,yy, 'g.-')
plt.show()
generates this plot:
Check the docstring of interp1d for options to control the interpolation, and also check out the other interpolation classes.

Plot/Convert an expression coming from sympy: Taylor series with matplotlib

i´am trying to plot the function sin(x)/x and a taylor approximation of it.
i use python 3 and pyzo - the first plot works but i have problems converting the series coming from the sympy module to an numpy expression that would work.
import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from sympy.abc import x
x = np.linspace(-10, 10, 100)
y = np.sin(x)/x #first function
plt.plot(x, y, 'k') #this is working fine
### this is a code that removes the "0(x**something)" part of
the series at the end
i found it here http://pastebin.com/ZNQakWP7
def series(expr, x, x0, n, removeO=False):
"""
sympy bugs avoided
"""
# expr_series = expr.series(x, x0, n)
# return expr_series.removeO() if removeO else expr_series
expansion = list()
for t in expr.lseries(x, x0):
p = t.as_coeff_exponent(x)[1]
if p < n:
expansion.append(t)
else:
break
if not removeO:
expansion.append(sp.O(x**n))
return sp.Add(*expansion)
### my code continued ####
y_t=series(sp.sin(x)/x,x,0,6,removeO=True)
if i look at y_t now i get this approximation
out: x**4/120 - x**2/6 + 1
Now i try to convert this to numpy in order to plot it as i did with the first function.
f_t = lambdify(x, y_t,modules=['numpy'])
x = np.linspace(-10, 10, 100) #i do this because x has
#been a symbolic variable before
plt.plot(x, y_t, 'b') #this is where the problem occurs
i get the first plot also a second error message:
File "<console>", line 1, in <module>
File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\pyplot.py", line 2832, in plot
ret = ax.plot(*args, **kwargs)
File "F:\pyzo2013_0_2_2\lib\site-packages\matplotlib\axes.py", line 3998, in plot
for line in self._get_lines(*args, **kwargs):
How can i achieve my idea to plot something coming from sympy?
Another idea i had was to convert the sympy out from the series to a string and then parsing this somehow to a numpy expression. I would be thankful for any help here!
I think your problem is that this:
plt.plot(x, y_t, 'b') #this is where the problem occurs
should be something like:
plt.plot(x, f_t(x), 'b')
f_t is the lambdified series, so it is a callable function that evaluates its argument.
I used lambdify in the following example, and it works for me:
from sympy.abc import x
from sympy import sin, series
from sympy.utilities.lambdify import lambdify
import numpy as np
import matplotlib.pyplot as plt
func = sin(x)/x
taylor = series(func, n=6).removeO()
evalfunc = lambdify(x, func, modules=['numpy'])
evaltaylor = lambdify(x, taylor, modules=['numpy'])
t = np.linspace(-5.5, 5.5, 100)
plt.plot(t, evalfunc(t), 'b', label='sin(x)/x')
plt.plot(t, evaltaylor(t), 'r', label='Taylor')
plt.legend(loc='best')
plt.show()
Here's the plot generated by the script.

Categories