How to interpolate 2D function over a large curvilinear mesh? - python

I have some surface data given as x_mesh, y_mesh, z_mesh.
x_mesh and y_mesh were generated from steps by longitude and latitude on a geotiff (so, their shapes are equal and regular but steps by x and y are not).
z_mesh is the height from tangential plane to Earth ellipsoid at the center of map.
I can easily plot the surface with matplotlib.pyplot.pcolormesh(x_mesh, y_mesh, z_mesh). It works.
Now I want to set a line by mouse and somehow take a Z profile under this line. I need some interpolator to make xy --> z, but don't know which one to use.
I tried to do this:
scipy.interpolate.interp2d(x_mesh, y_mesh, z_mesh)
But it gives me an error: OverflowError: Too many data points to interpolate
Don't you have any ideas how to interpolate such data?
P.S. The geotiff is not very big, it is 6K x 6K pixels. And I see that pcolormesh somehow interpolates the color value between pixels if I zoom in.

Related

Quiver polar plot returns scatterplot instead of arrows, when it shouldn't

r = np.linspace(0.1,1,11)
theta = np.linspace(-alpha,alpha,11)
radius_matrix, theta_matrix = np.meshgrid(r,theta)
u_radial = -q*(1/radius_matrix)*u_sol[0]
u_theta = theta_matrix*[0 for x in range(len(u_sol[0]))]
ax = plt.subplot(111, polar=True)
ax.plot(theta_matrix, radius_matrix, u_radial, u_theta) #color='r',
ls='none', marker='.'
plt.show()
I am trying to make a plot of a velocity field (same as vector field) using numpys quiver function. The velocity field is written
where q is just an arbitrary constant and r is the distance to the origin. Now, to plot this in a polar coordinate system I create two meshgrids radius_matrix and theta_matrix, as seen in my code (line three). Together these meshgrids form a polar coordinate plane, with r on the horizontal axis and theta on the vertical axis (at least I think) and each point should have a vector arrow corresponding to the equation above.
So for that to happen I define u_radial and u_theta, which are the vector components in radial and angluar direction, resp.. The variable u_sol[0] contains f(theta) (as seen in the equation) for 11 different theta points, and I thought that this would give the correct vectorcomponent, but it doesnt. Why not?
I am expecting something like this, that the arrow shrinks when I get close to the edge for a single value of r. I just want this but for more values of r. This is the data of my u_sol[0] vector:
u_sol[0] = [4.68520269e-26 1.54380741e+00 2.74550730e+00 3.60503630e+00
4.12217780e+00 4.29651250e+00 4.12741184e+00 3.61407419e+00
2.75560427e+00 1.55113610e+00 3.84028608e-18]
When I plot this, I get something worse, see the figure below. What happend to the arrows? And why are there colors all of a sudden?
Best regards SimpleP.

How to change the center of a stereographic projection?

Right now I am plotting a streographic projection with a center at the z axis by getting a P vector (Px, Py, Pz) from different directional indices in a unit sphere. The following process converts these to 2d coordinates.
(Python)
x2,y2,z2=P
theta2=np.arccos(abs(z2)/(x2**2+y2**2+z2**2)**.5)
phi2=np.arctan((y2/x2))
xp=theta2*np.cos((phi2))
yp=theta2*np.sin((phi2))
Plot xp,yp
What transformations do I apply in order to change the P vector (or a different aspect of the code) so that the center is on a different direction (x-axis for example)?
Thanks.

How to project 3D scatter points onto the xy-plane?

this is the graph in question and the dots should appear in the bottom plane, not "above" the plane like i manged to.
bx.scatter(xs,ys,zs, zdir=zs,c=plt.cm.jet(np.linspace(0,1,N))) # scatter points
for i in range(N-1):
bx.plot(xs[i:i+2], ys[i:i+2], zs[i:i+2], color=plt.cm.jet(i/N), alpha=0.5)
#plots the lines between points
bx.scatter(xs,ys,zs=732371.0,zdir="z",c=plt.cm.jet(np.linspace(0,1,N)),depthshade=True)
bx.set_zlim3d(732371.0,) #limit is there so that we can project the points onto the xy-plane
as youll notice the points are drawn above the xy-grid and I had to set a lower limit for the z-axis so that the first projected point will not interfere with the first scatter point
I would prefer the points be in 2d and less hacky since I got 50 other graphs to do like this and fine tune each one would be cumbersome.
Got some simpler method you want to share?
There are many options, and ultimately, it depends on the range of your data in the other plots.
1) Offset the projection point by a fixed amount
You could calculate the minimum Z value, and plot your projection a fixed offset from that minimum value.
zs=min(zs)-offset
2) offset the projection by a relative amount that depends on the range of your data.
You could take into account the range of your data (i.e. the distance from min to max Z) and calculate an offset proportional to that (e.g. 10-15%).
zs=min(zs)-0.15*(max(zs)-min(zs))

Contouring non-uniform 2d data in python/matplotlib above terrain

I am having trouble contouring some data in matplotlib. I am trying to plot a vertical cross-section of temperature that I sliced from a 3d field of temperature.
My temperature array (T) is of size 50*300 where 300 is the number of horizontal levels which are evenly spaced. However, 50 is the number of vertical levels that are: a) non-uniformly spaced; and b) have a different starting level for each vertical column. As in there are always 50 vertical levels, but sometimes they span from 100 - 15000 m, and sometimes from 300 - 20000 m (due to terrain differences).
I also have a 2d array of height (Z; same shape as T), a 1d array of horizontal location (LAT), and a 1d array of terrain height (TER).
I am trying to get a similar plot to one like here in which you can see the terrain blacked out and the data is contoured around it.
My first attempt to plot this was to create a meshgrid of horizontal distance and height, and then contourf temperature with those arguments as well. However numpy.meshgrid requires 1d inputs, and my height is a 2d variable. Doing something like this only begins contouring upwards from the first column:
ax1 = plt.gca()
z1, x1 = np.meshgrid(LAT, Z[:,0])
plt.contourf(z1, x1, T)
ax1.fill_between(z1[0,:], 0, TER, facecolor='black')
Which produces this. If I use Z[:,-1] in the meshgrid, it contours underground for columns to the left, which obviously I don't want. What I really would like is to use some 2d array for Z in the meshgrid but I'm not sure how to go about that.
I've also looked into the griddata function but that requires 1D inputs as well. Anyone have any ideas on how to approach this? Any help is appreciated!
For what I understand your data is structured. Then you can directly use the contourf or contour option in matplotlib. The code you present have the right idea but you should use
x1, z1 = np.meshgrid(LAT, Z[:,0])
plt.contourf(x1, Z, T)
for the contours. I have an example below
import numpy as np
import matplotlib.pyplot as plt
L, H = np.pi*np.mgrid[-1:1:100j, -1:1:100j]
T = np.cos(L)*np.cos(2*H)
H = np.cos(L) + H
plt.contourf(L, H, T, cmap="hot")
plt.show()
Look that the grid is generated with the original bounding box, but the plot is made with the height that has been transformed and not the initial one. Also, you can use tricontour for nonstructured data (or in general), but then you will need to generate the triangulation (that in your case is straightforward).

Interpolating Scattered Data from a Volume that has Empty Space

I have 3d data produced from mesh points. The structure that was meshed is complex enough that interpolation using griddata is lacking. Specifically, there are regions without data points which are being given values by griddata that are not the fill_value. I need these hollow regions to have the value of 0.0, which I set fill_value to.
A simplified version of this is illustrated below:
The area occupied by the cylinder has no data points but the rest of the cube volume does. There will be data points from interpolation inside the cylinder but I need them to be zero.
Below is a slice parallel to the xy plane of the actual interpolated data with a black oval that approximates the edge 'cylinder'. The red an blue 'bleed' in to the void after interpolation. The fill value of 0.0 can be seen in the upper left corner:
Any ideas on how I can achieve the goal of setting those values to 0.0? Note that the 'cylinder' is not of constant shape.
I thought about going z layer by z layer and finding a polygon that gives the cylinder shape and then setting points inside the polygon to zero.
I also thought about partitioning the volume so a portion of the cylinder ends up in corners of the partion (for each z layer) and hoping that the interpolator would not try to extrapolate into the void region.
The first option seems better, but I would like to know if Python provides some sort of functionality which would work better.
EDIT: Here are some actual points from the data set:
The z scale is much smaller than x or y. You can see that the regions I'm interested in are pretty well defined. But, again, how do I identify them for the purposes of setting grid points to 0.0?

Categories

Resources