Struggling with piecewise polynomial interpolation in python - python

So I have this task, where im supposed to interpolate a function with polynomials. The entire interval is divided into N subintervals, and the polynomial interpolating in each subinterval is of order k. I generet all my interpolating points, but I am running into two problems.
I) For k=1, i.e first order polynomials, I've tried solving the task by having a loop generate a first order polynomial in each subinterval using the scipy interp1d, but I'd like to get all the different polynomials in a single plot.
This is my code, tried only including the nessescary bits, sorry if something is missing. intpoint here are the interpolation points, and funky(x) is just the arbitrary function im approximating.
import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as sc
intpoint=np.array([-3,-2,-1,0,1,2,3])
for i in range(len(intpoint)):
intleng=[intpoint[i],intpoint[i+1]]
myinterval=np.linspace(intpoint[i],intpoint[i+1],1000)
mypol=sc.interp1d(intleng,np.sin(intleng),1)
plt.plot(intleng, mypol(intleng))
plt.plot(myinterval,np.sin(myinterval))
plt.show()
Apologies in advance if anything is unclear, or my code is hard to follow/untidy.

import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as sc
intpoint=np.array([-3,-2,-1,0,1,2,3])
for i in range(len(intpoint)-1):
intleng=[intpoint[i],intpoint[i+1]]
myinterval=np.linspace(intpoint[i],intpoint[i+1],1000)
mypol=sc.interp1d(intleng,np.sin(intleng),1)
plt.plot(myinterval,mypol(myinterval))
plt.plot(myinterval,np.sin(myinterval))
plt.show()
I think this is what you want. There was a mistake in the plotting and you should do plt.show() only once to get one plot.

Related

Plot scatter graphs with matplotlib subplot

I am trying to plot a scatter diagram. It will take multiple arrays as input but plot into a single graph.
Here is my code:
import numpy as np
import os
import matplotlib.pyplot as plt
ax = plt.gca()
n_p=np.array([17.2,25.7,6.1,0.9,0.5,0.2])
n_d=np.array([1,2,3])
a_p=np.array([4.3,1.4,8.1,1.8,7.9,7.0])
a_d=np.array([12,13,14])
ax.scatter = ([n_d[0]/n_d[1]],[n_p[0]/n_p[1]])
ax.scatter = ([a_d[0]/a_d[1]],[a_p[0]/a_p[1]])
I will read the arrays from csv file, here I just put a simple example (for that I imported os). I want to plot the ratio of array element 2/ element 1 of n_p (as x-axis) and same with n_d (as y-axis). This will give a point in the graph. Similar operation will be followed by a_p and a_d array, and the point will be appended to the graph. There will be more data to append, but to understand the process, two is enough.
I tried to follow example from here.
If I use the color, I get syntax error.
If I do not use color, I get a blank plot.
Sorry, my coding experience is beginner so code is rather nasty.
Thanks in advance.
remove the = from the function call!
import numpy as np
import os
import matplotlib.pyplot as plt
ax = plt.gca()
n_p=np.array([17.2,25.7,6.1,0.9,0.5,0.2])
n_d=np.array([1,2,3])
a_p=np.array([4.3,1.4,8.1,1.8,7.9,7.0])
a_d=np.array([12,13,14])
ax.scatter([n_d[0]/n_d[1]],[n_p[0]/n_p[1]])
ax.scatter([a_d[0]/a_d[1]],[a_p[0]/a_p[1]])

Fit in python with curve_fit

I have to make a fit using curve_fit. My problem is that, instead of having a continous curve, I obtain a broken line, as shown in the figure. Here is my code:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
N=np.array([66851,200522,401272,801832,1200951])
e=np.array([2.88,1.75,1.17,0.80,0.71])
def er_func(x,A,c):
return A/np.sqrt(x)+c
from scipy.optimize import curve_fit
popt, pcov=curve_fit(er_func,N,e,p0=[10,1000])
plt.plot(N,er_func(N,*popt),"b")
plt.plot(N,e,"xr")
plt.xlabel("Number of events")
plt.ylabel("Error [Chn]")
[https://i.stack.imgur.com/BZtnN.png][1]
I think that this happens because I'm plotting the fit function evaluated in the correspondence of my points, and then it connects the five points with a straight line. How can I obtain a correct fit?
Thanks for any help you can provide.
I am only showing the relevant part of the code. You needed to define a fine mesh (N_mesh below) for plotting your continuous fit curve. I am highlighting the lines added/modified by a comment
N=np.array([66851,200522,401272,801832,1200951])
N_mesh = np.linspace(N[0], N[-1], 100) # Added (A mesh of 100 x-points)
e=np.array([2.88,1.75,1.17,0.80,0.71])
def er_func(x,A,c):
return A/np.sqrt(x)+c
from scipy.optimize import curve_fit
popt, pcov=curve_fit(er_func,N,e,p0=[10,1000])
plt.plot(N_mesh,er_func(N_mesh,*popt),"b", label='Fit') # Modified
plt.plot(N,e,"xr", label='Actual data') # Modified
plt.legend(fontsize=14) # Added
Output

Plot wind vectors with quiver()

I want to plot wind vectors. I use Basemap and this example http://basemaptutorial.readthedocs.org/en/latest/plotting_data.html#quiver.
In my file, the longitudes go from 0 to 360. I use latlon=True to shift it to -180:180. But, when I use "points" to define the point density, the vectors are plotted over half of my figure only.
Here is the code:
Of course, I use this code:
m=Basemap(projection='cyl',llcrnrlat=30,urcrnrlat=80, llcrnrlon=-40,urcrnrlon=40,resolution='c')
latvar=nc.variables['lat']
lat=latvar[:]
lon=nc.variables['lon'][:]
X,Y=m(lon,lat)
lons,lats=meshgrid(lon,lat)
X4,Y4=m(lons,lats)
varU=ncU.variables['var1'][0,0,:,:]
varV=ncV.variables['var2'][0,0,:,:]
speed=np.sqrt(varUvarU+varVvarV)
yy=np.arange(0,len(Y[:]),3)
xx=np.arange(0,len(X[:]),3)
points=np.meshgrid(yy,xx)
m.quiver(X4[points],Y4[points],varU[points],varV[points],speed[points],cmap=cmap‌​,latlon=True)
Can someone help me with this issue? Thanks.
You have a lot of things going on that I am not sure you need. I have tried your code with some minor modifications and it works:
import numpy
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
lon =NC.variables['lon'][:]
lat =NC.variables['lat'][:]
m=Basemap(projection='cyl',,llcrnrlat=30,urcrnrlat=80, llcrnrlon=-40,urcrnrlon=40,resolution='c')
lons,lats=numpy.meshgrid(lon,lat)
X4,Y4=m(lons,lats)
varU=NC.variables['var1'][0,0,:,:]
varV=NC.variables['var2'][0,0,:,:]
speed=numpy.sqrt(varU*varU+varV*varV)
yy=numpy.arange(0,len(lat),3)
xx=numpy.arange(0,len(lon),3)
points=numpy.meshgrid(yy,xx)
m.quiver(X4[points],Y4[points],varU[points],varV[points],speed[points],cmap=cmap,latlon=True)
plt.show()
# with all points for comparison
m.quiver(X4,Y4,varU,varV,speed,cmap=cmap,latlon=True)
plt.show()

ConvexHull not accurate enough - alternatives?

I have a cluster consistent of about 25k points and I want to find the borders. It works with ConvexHull, but the result is that I only get about 19 coordinates as output. This is definitely too few.
Here is the sample code from the SciPy documentation. If you run it you can see that the number of points is very limited.
from scipy.spatial import ConvexHull
import numpy as np
import matplotlib.pyplot as plt
points = np.random.rand(50, 2) # 30 random points in 2-D
hull = ConvexHull(points, incremental=False)
plt.plot(points[:,0], points[:,1], 'o')
for simplex in hull.simplices:
plt.plot(points[simplex,0], points[simplex,1], 'r-')
plt.show()
Is it possible to get more points to increase the accuracy of the boarder? Or do I need a different code?
Well then your hull wouldn't be convex!
Try http://www.geosensor.net/papers/duckham08.PR.pdf for an algorithm that will attempt to get what you probably want, which is something that morally follows the "border" of the set of points.
You could also try alpha-shapes.

How to use griddata from scipy.interpolate

I have a three-column (x-pixel, y-pixel, z-value) data with one million lines. The data is from an image and there are duplicated z-values. Now I need to make a surface plot. This image is a perfect example. But now the output image is null. Could someone check the code please?
import numpy as np
from enthought.mayavi import mlab
from scipy.interpolate import griddata
x,y,z = np.loadtxt('test.csv',delimiter=',',usecols=(0,1,2),unpack=True)
xi,yi = np.mgrid[0:3000:3000j, 0:3000:3000j]
zi = griddata((x, y), z, (xi, yi),method='linear')
mlab.surf(xi,yi,zi)
mlab.show()
I can't check the code without having the data, but I suspect that the problem is that you are using the default fill_value=nan as a griddata argument, so if you have gridded points that extend beyond the space of the (x,y) points, there are NaNs in the grid, which mlab may not be able to handle (matplotlib doesn't easily). Try setting fill_value=0 or another suitable real number.

Categories

Resources