Interpolate a curve on itself using NumPy - python

I have the following curve as two arrays, of x and y positions.
Imagine if you were to draw vertical lines going through each point, and add points on the curve wherever these lines intersect the curve. This is what I want.
I tried using np.interp(x, x, y), but I ended up with the following mess:
How can I do this? Is it possible with np.interp?
This might be something that should be asked in a different question, but I would also like there to be points added where the curve crosses over itself.

According to the docs the array of X values should be sorted (or periodic), otherwise "the result is nonsense". You can try to split your curve into sections, and then interpolate each part on the others. You can find the correct splitting places by looking at where np.diff(x) changes sign.

Related

Interpolating to get rid of NANs and contour plot

I have these arrays that I need to interpolate and make the smoothest possible interpolation:
x = time
y = height
z = latitude
print np.shape(x)
print np.shape(y)
print np.shape(z)
Result:
(99, 25)
(99, 25)
(99, 25)
y is altitude and it's not uniform. It has a bunch of nan's and even though they're all the same size (a variable n_alt with the number of altitudes, which is for this example 99).
x is time and it's uniform all the way through (all the values in one column of that array are the same).
z is latitude and it's the actual 'z' and it's an array with the same number of rows as the number of time points and same number of rows as the altitude points.
I want to interpolate in 2D (the data set has series of nans in both x and y directions) to fill the gaps on the data, since several files will cover a certain altitude range and not others
My questions are:
1) is there a good way to fill the gaps the 2 directions while making the grid uniform (the idea is to plot that and also save the interpolated data (x,y and z) into a new file as well)?
2) what's a good way to contour plot the data with the shape I mentioned earlier (tried plt.contour, but it doesn't give a satisfactory result just plotting that straight up)?
Thanks y'all
Edit:
I believe this will illustrate the question better:
X: Time, Y: Altitude, Z: Latitude or Longitude
I essentially want to fill up the white space (I understand the consequences of extrapolations and all, but I just want, at this point, to have an algorithm that works. The blue dots is my grid and the color plot is just a normal plt.contour (no interpolation done). I want to make such that I have blue dots all over the plot area.
Rafael! With respect to your interpolation question, I can explain the math if you want to manually come up with an interpolation function, but there is an existing resource you might want to look into: scipy.interpolate.RegularGridInterpolator
(see https://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.interpolate.RegularGridInterpolator.html)
If I have misunderstood your issue, another interpolation method from the class might be appropriate: see, scipy.interpolate
For plotting the 3d surface, https://matplotlib.org/examples/mplot3d/surface3d_demo.html might help guide you! Let me know if this helps! Just comment if you would like me to expand! Hopefully those are the resources you were looking for!

Python - Problems contour plotting offset grid of data

My data is regularly spaced, but not quite a grid - each row of points is slightly offset from the one below.
The data is in the form of 3 1D arrays, x, y, z, with each index corresponding to a point. It is smoothly varying data - approximately Gaussian.
The point density is quite high. What is the best way to plot this data?
I tried meshgrid, but it gives me some bad contours through regions that have no data points near the contour's value.
I have tried rbf interpolation according to this post:
Python : 2d contour plot from 3 lists : x, y and rho?
but this just gives me nonsense - all the contours are on one edge - does not reflect the data at all.
Any other ideas for what I can try. Maybe I should be using some sort of nearest neighbour interpolation? Here is a picture of about a 1/4 of my data points: http://imgur.com/a/b00R6
I'm surprised it is causing me such difficulty - it seems like it should be fairly easy to plot.
The easiest way to plot ungridded data is probably tricontour or tricontourf (a filled tricontour plot).
Having 1D arrays of the x, y and z coordinates x, y and z, you'd simply call
plt.tricontourf(x,y,z, n, ...)
to obtain n levels of contours.
The other quick method is to interpolate on a grid using matplotlib.mlab.griddata to obtain a regular grid from the irregular points.
Both methods are compared in an example on the matplotlib page:
Tricontour vs. griddata
Found the answer: needed to rescale my data.

Plotting 3D points with Python Matploltlib

I want to create a small simulation, and I think I know how, but in order to actually see what happens I need to visualize it.
I started with a 5x5x5 array, which I want to fill up with values.
data = numpy.zeros(shape=(5,5,5))
data[:,:,0]=4
data[:,:,1]=3
data[:,:,2]=2
data[:,:,3]=1
data[:,:,4]=0
This should create a cube which has a gradient in the upward direction (if the third axis is z).
Now, how can I plot this? I dont want a surface plot, or wireframe. Just Points on each coordinate, and maybe colorcoded or transperency by value.
As a test I tried plotting all coordinates using
ax.scatter(numpy.arange(5),numpy.arange(5),numpy.arange(5))
but this will only plot a line consisting of 5 dots.
So... how can I get the 125 dots, that I want to create?
Thx.
You can encode the value in color like this:
x = np.arange(5)
X, Y, Z = np.meshgrid(x,x,x)
v = np.arange(125)
ax.scatter(X,Y,Z, c=v)
See here for the documention.

Trying to plot some data in matplotlib with numpy

I'm trying to simulate Conway's Game of Life in python(here is some of the code), and now I need to handle the ouput. Right now, I'm just plotting points in matplotlib but I want something like what this guy did(That script shows error in my PC but it generates the images anyway). I understand that the code I am looking for is:
plt.imshow(A, cmap='bone', interpolation='nearest')
plt.axis('off')
and that A is a numpy array alike a matrix with just True and False as entries.
By the way, I've already realized that instead of True and False I can put 1's and 0's.
I have the data of living cells as a set of points ([(x1,y1),(x2,y2),....,(xn,yn)]) of the plane(coordinates all integers). As you can see, my script is finite(it uses a for loop until 30), so I preset the plots' axis before the loop...for example, the minimum x coordinate of the plots is the minimum coordinate of the initial points minus 30, assuring then that all the points are visible in the last image.
To represent each configuration, I had the idea to do:
SuperArray=np.zeros(maxx+30,maxy+30)
for (i,j) in livecells:
SuperArray[i,j]=1
But that idea won't work, because the indices of SuperArray are all positives, and my coordinates maybe negative. To solve this I was thinking in translate ALL of the points in livecells so their coordinates be positive. I would do that by adding |minx|+30 to the x coordinate and |miny|+30 to the y coordinate
of each (x,y) in livecells...I haven't put it in practice yet, but it seems too complicated and memory consuming...Do you guys have any suggestion?

Re-arrange the array contain endpoints to creat an closed polygon in Python

For some purpose, I want to plot an polygon based on several latitude and longitude as endpoints which combined together.
The example data shows like this:
fig=plt.figure()
ax = plt.gca()
x_map1, x_map2 = 114.166,114.996
y_map1, y_map2 = 37.798,38.378
map = Basemap(llcrnrlon=x_map1,llcrnrlat=y_map1,urcrnrlon=x_map2,urcrnrlat=y_map2)
map.drawparallels(np.arange(y_map1+0.102,y_map2,0.2),labels=[1,0,0,1],size=14,linewidth=0,color= '#FFFFFF')
map.drawmeridians(np.arange(x_map1+0.134,x_map2,0.2),labels=[1,0,0,1],size=14,linewidth=0)
bo_x = [114.4390022, 114.3754847, 114.3054522, 114.3038236, 114.2802081, 114.2867228, 114.3378847, 114.3888619, \
114.6288783, 114.6848733, 114.7206292, 114.7341219]
bo_y = [38.16671389, 38.14472722, 38.14309861, 38.10156778, 38.08853833, 38.06980889, 38.03587472, 37.96409056, \
37.84975278, 37.84840333, 37.9017, 38.16683306]
x, y = map( bo_x, bo_y )
xy = zip(x,y)
poly = Polygon( xy, facecolor='red', alpha=0.4 )
plt.gca().add_patch(poly)
The figure shows like this:
But when the Lons array and Lats array are not in the anticlockwise order, and the arrays contain many items that hard to adjust manually. The polygon output may show non-conformity.
Here, I disorganize the bo_x and bo_y as an suppositional situation.
bo_x_adjust = [114.4390022, 114.3754847, 114.3054522, 114.3038236, 114.6288783, 114.6848733, 114.7206292, 114.7341219,
114.2802081, 114.2867228, 114.3378847, 114.3888619, ]
bo_y_adjust = [38.16671389, 38.14472722, 38.14309861, 38.10156778, 37.84975278, 37.84840333, 37.9017, 38.16683306,
38.08853833, 38.06980889, 38.03587472, 37.96409056, ]
Figure shows like:
So, here is my question. Sometimes, the original endpoints are not in order which can output a closed polygon. Pre-organize the arrays is the way to go.
I think to adjust the order of arrays like bo_x and bo_y must follow two principles:
Elements in these two array should be adjust synchronously for the purpose to not break the endpoint pairs(X~Y)
The new arrays should be outlined in clockwise or anticlockwise order on 2-D space.
Any advice or guidelines would be appreciate.
Not an answer yet, but I needed the ability to attach images.
The problem may be ill defined. For example, these two legitimate polygons have the same vertices.
Do you want to get either one?
Here is a way to solve what you want by linear algebra. Sorry but I am writing just the general guidelines. Nonetheless it should work.
Write a function that accept two edges numbers j and k and check if there is an intersection. Note that you need to handle correctly the last to first vertices edge. You also need to make sure you give 'False' when adjacent edges are called since these always intersect by definition.
Now the way to know if two edges intersect is to follow a little algebra. Extract from each edge its straight line parameters a and b by y = a*x + b. Then solve for the two edges to find the intersection x by equating a1*x+b1==a2*x+b2. If the intersection x for both edges is between the x's of the edge's vertices, then the two edges indeed intersect.
Write a function that goes over all edges pairs and test for intersection. Only when no intersection exist the polygon is legitimate.
Next you can go in two approaches:
Comprehensive approach - Go over all possible permutations of the vertices. Test each permutation polygon for intersections. Note that when permutating you need to permutate x and y together. Note that there are a lot of permutations so this could be very time consuming.
Greedy approach - As long as there are still intersections, go over the edges pairs combinations and whenever there is an intersection simply switch the two last edge coordinates (unwind the intersection). Then restart going over all the edges pairs again . Repeat this until there are no more intersections. This should work pretty fast but will not give the best polygon (e.g. will not optimize the largest polygon area)
Hope this helps...

Categories