Getting a Basemap projection as a numpy array - python

This must be possible but I am unsure as to how to approach it.
I have a geographical domain, with a set number of lat and lons. Using these, I am able to plot a simple Basemap of the domain:
fp_mhd = name.footprints('path/to/file')
domain_lon = fp_mhd.lon
domain_lat = fp_mhd.lat
### Construct Basemap ###
m = Basemap(resolution='c',projection='gall',
llcrnrlat=(np.min(domain_lat)),
urcrnrlat=(np.max(domain_lat)),
llcrnrlon=(np.min(domain_lon)),
urcrnrlon=(np.max(domain_lon)))
What I need is someway of distinguishing countries from oceans within this domain, and returning the results as an array i.e. 1s for land and 0s for ocean (though these values don't matter). The array needs to be 2-D where each point corresponds to a specific lat and lon. So say there were 100 lats and 200 lons, there would be 20000 1s and 0s. I wondered if there was some way to convert the Basemap object to an array, but failed to achieve this. Is it possible?
Thanks in advance!

Have a look at the following function. You should be able to extract the mask as it returns a numpy masked array.
.mask returns a Boolean array.
mpl_toolkits.basemap.maskoceans(lonsin, latsin, datain, inlands=True,
resolution='l', grid=5)
returns a masked array the same shape as datain with “wet” points
masked.
Basemap documentation
Numpy Masked Array Documentation

Related

Pyvista plotting 3D numpy array, always blank

I am trying to plot a 3D numpy array (256 x 256 x 256) as essentially an array of points, which should be colored by their value. I keep getting something like this
if I multiply by data by 1000, I get this:
My data is a 3D np array composed of slices, and the slices look like this:
There are about 50 or so slices, so the 3D visualization should be showing a sphere. I can visualize the slices just fine
My code is a modified example of this example: https://docs.pyvista.org/examples/02-plot/volume.html using the technique given here in this link to make a pyvista.UniformGrid object out of a 3D numpy array: https://docs.pyvista.org/examples/00-load/create-uniform-grid.html
def plot_3d_pyvista(self):
import pyvista as pv
values = self.reconstructed_source_3D
# Create the spatial reference
grid = pv.UniformGrid()
# Set the grid dimensions: shape because we want to inject our values on the
# POINT data
grid.dimensions = values.shape
# Edit the spatial reference
#grid.origin = (1, 1, 1) # The bottom left corner of the data set
#grid.spacing = (1, 1, 1) # These are the cell sizes along each axis
# Add the data values to the cell data
grid.point_data["values"] = values.flatten(order="F")
p = pv.Plotter()
p.add_volume(grid)
p.show()
If I use a sphere, eg, a 3D numpy array of zeros with only the center spherical elements set to 1, I get something like this which clearly shows a sphere but is way too transparent:
Alternatively, if anyone knows a way using a different package to plot a volume like this, I could use that. I just need a way to visualize what the 3D looks like.

Plot 3D mesh using 3D numpy array and 2D numpy array

I have a 3D numpy array Lattice[][][], and a 2D numpy array Trajectory[][].
I want the indices i/j/k of Lattice to be the coordinate axes and the value contained in the tensor element to be plotted as a colored dot, making a 3D mesh maybe
and I want to plot Trajectory where the Trajectory[p][0]/[1]/[2] contains the coordinates, and the index p is the iteration number - so this I want to plot as a 3D line, hopefully inside the mesh. I have no idea from where to start, is it possible in matplotlib?
You could definetly use matplotlib. Check this link: https://matplotlib.org/2.0.2/mpl_toolkits/mplot3d/tutorial.html
But you could also try a different package, like Plotly: https://plotly.com/python/3d-charts/

Is there a way to plot Matplotlib's Imshow against a specific array rather than the indices?

I'm trying to use Imshow to plot a 2-d Fourier transform of my data. However, Imshow plots the data against its index in the array. I would like to plot the data against a set of arrays I have containing the corresponding frequency values (one array for each dim), but can't figure out how.
I have a 2D array of data (gaussian pulse signal) that I Fourier transform with np.fft.fft2. This all works fine. I then get the corresponding frequency bins for each dimension with np.fft.fftfreq(len(data))*sampling_rate. I can't figure out how to use imshow to plot the data against these frequencies though. The 1D equivalent of what I'm trying to do us using plt.plot(x,y) rather than just using plt.plot(y).
My first attempt was to use imshows "extent" flag, but as fas as I can tell that just changes the axis limits, not the actual bins.
My next solution was to use np.fft.fftshift to arrange the data in numerical order and then simply re-scale the axis using this answer: Change the axis scale of imshow. However, the index to frequency bin is not a pure scaling factor, there's typically a constant offset as well.
My attempt was to use 2d hist instead of imshow, but that doesn't work since 2dhist plots the number of times an order pair occurs, while I want to plot a scalar value corresponding to specific order pairs (i.e the power of the signal at specific frequency combinations).
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
f = 200
st = 2500
x = np.linspace(-1,1,2*st)
y = signal.gausspulse(x, fc=f, bw=0.05)
data = np.outer(np.ones(len(y)),y) # A simple example with constant y
Fdata = np.abs(np.fft.fft2(data))**2
freqx = np.fft.fftfreq(len(x))*st # What I want to plot my data against
freqy = np.fft.fftfreq(len(y))*st
plt.imshow(Fdata)
I should see a peak at (200,0) corresponding to the frequency of my signal (with some fall off around it corresponding to bandwidth), but instead my maximum occurs at some random position corresponding to the frequencie's index in my data array. If anyone has any idea, fixes, or other functions to use I would greatly appreciate it!
I cannot run your code, but I think you are looking for the extent= argument to imshow(). See the the page on origin and extent for more information.
Something like this may work?
plt.imshow(Fdata, extent=(freqx[0],freqx[-1],freqy[0],freqy[-1]))

Determine Coordinates on Gridded Data to Find Lengths of Objects

I'm in the process of identifying objects whose float value is greater than a certain threshold in a 2-D numpy array. I then need to determine the length of the major axis of each object and make sure that the object's major axis length satisfies a certain threshold in kilometers.
I am able to identify the objects I want in my 2-D numpy array by using the scipy.ndimage.measurements.label module. I then am able to determine the length of each object's major axis using the scikit-image regionprops module (skimage.measure.regionprops).
However, I am unsure about what the units of the object's length are as the 2-D numpy array by itself does not have any information about coordinates. The 2-D numpy array is essentially a dataset that maps to a subdomain on the surface of the globe. Additionally, I have two other 2-D numpy arrays that are the same size as my data array with one array containing the latitude coordinates for each grid point and the other containing the longitude coordinates. I believe I somehow need to use the lat/lon arrays to determine the length of the major axis of my objects but I have no idea how.
This is the code I have so far:
from scipy import ndimage
from skimage.measure import regionprops
import numpy as np
# 2-D numpy array with data.
data
# 2-D numpy arrays with latitude and longitude coordinates that are same grid as data array.
lat
lon
# Allow label module to have diagonal object matching.
struct = np.ones((3,3), dtype=bool)
# Find objects in data array.
labl, n_features = ndimage.measurements.label(data>=35,structure=struct)
# Find major axis length in labl array for each object found.
props = regionprops(labl)
# Loop through each object.
for p in props:
# Find object's major axis length.
length = p.major_axis_length
(some code to compute major axis length in kilometers?)
if length < 125: #(125 is in km)
(keep object)
Any help would be greatly appreciated. Thanks!

Create 2D projection of 3D matrix in python

Short version: I have a NxNxN matrix full of different values. I want to create a 2D projection of it looking exactly like this: http://tinyurl.com/bellfkn (3D if possible too!)
Long version: I have made a density matrix of dimension NxNxN with the following loop:
ndim = 512
massmat = np.zeros((ndim,ndim,ndim))
for i in range(0,npoints):
massmat[int(x1[i]),int(y1[i]),int(z1[i])] = massmat[int(x1[i]),int(y1[i]),int(z1[i])] + mpart
densemat = massmat/volumeofcell
massmat is a numpy array.
So basically I now have a NxNxN matrix with certain cells containing in this case, a density (units of g/cm^3). Is there a way to turn this into a 2D projection - a side-on view of the densities with a colorbar indicating dense areas and less dense areas?
In Matlab I would just do:
imageArray2Dmesh = mean(densemat, 3);
figure
sc(imageArray2Dmesh, 'pink')
And it gives me a density projection - I'd like to do the same but in Python. Is there a way to view the whole NxNxN matrix in a 3D projection too? Just like the link but in 3D. That would be great.
You can use a very similar code in numpy and matplotlib:
import numpy as np
import pylab as plt
imageArray2Dmesh = np.mean(mesh_reshape, axis=2);
plt.figure()
plt.pcolor(imageArray2Dmesh, cmap = ,cmap=plt.cm.pink)
plt.colorbar()
plt.show()
you have a couple of more command, but this is just due to different approaches for the grafics in matlab and matplotlib (hint: in the long run, the matplotlib way is way better)
If you want the project from another direction just change the axis parameter (remember that python has the indices from 0 and not from 1 like matlab).
For a projection from a generic direction...well, that is quite more difficult.
By the way, if you need to look at some 3D data I strongly suggest you to lose some time to explore mayavi. It's still a python library, and it's really powerful for 3d imaging:
http://docs.enthought.com/mayavi/mayavi/auto/examples.html

Categories

Resources