Accessing (interpolating?) data in 3D array

I have been using Matlab for many years but this is my first time working with a 3D array. My data is 290x480x90 in the format latitude x longitude x frequency. So it contains sound pressure data for a range of locations at different frequencies. I am wondering if I could then create a separate array e.g. 10x2x1 of lat/lon locations at a particular freq of interest that lie within the main array, and pull those data points out? Those specific locations of interest therefore don't necessarily occur as points of the 3D array but they are within it... hopefully that makes sense.

5 comentarios

Mathieu NOE
Mathieu NOE el 25 de Nov. de 2021
hello Louise (welcome back !)
yes , I think you can achieve your goal by
  • extracting a 2D array (290x480) from your 3D array (290x480x90 ) out = in(:,:,k); where k is your frequency index
  • use either interp2 or griddata for 2D interpolation
  • griddata : Interpolate 2-D or 3-D scattered data
  • interp2 : Interpolation for 2-D gridded data in meshgrid format
all the best
Hi Mathieu! Thank you.
The first part
out=in(:,:,k)
actually gives me out = 1 * 480 * 290, which is weird, because what you suggested makes sense to me.
Louise Wilson
Louise Wilson el 26 de Nov. de 2021
Just realised squeeze() is needed! I will proceed with the other steps :)
yes , squeeze may be needed , even thought on my matlab release (R2020b) it seems not to be required (?)
i did this simple test and the output array dimension is like we wanted
>> a = randn(30,10,3);
>> b = a(:,:,1);
>> whos
Name Size Bytes Class Attributes
a 30x10x3 7200 double
b 30x10 2400 double
Louise Wilson
Louise Wilson el 28 de Nov. de 2021
I have two devices, one with 2020b and one with 2021a (University issues...), it works the same as you in 2020b but in 2021a squeeze is needed.

Iniciar sesión para comentar.

 Respuesta aceptada

Matt J
Matt J el 25 de Nov. de 2021
Editada: Matt J el 25 de Nov. de 2021
You could use griddedInterpolant()
array=rand(290,480,90);
F=griddedInterpolant(array);
extract=F({linspace(4,8,10), 400:401, 80.1}) %10x2 area extracted at frequency=80.1

4 comentarios

Louise Wilson
Louise Wilson el 26 de Nov. de 2021
Editada: Louise Wilson el 26 de Nov. de 2021
This allows me to extract data of a certain size, but I can't see where I would input the coordinates of interest? I was thinking that I would manually create a list of positions of interest (which exist within the 3d array) and use that list to pull the data from those positions in the 3d array. So, I don't want to end up with the 10*2 array without defining the locations of interest.
The locations of interest in my example were
{linspace(4,8,10), 400:401, 80.1}
but you could replace these with anything you want. See also the documentation for usage of griddedInterpolant objects
Louise Wilson
Louise Wilson el 27 de Nov. de 2021
Oh, I see! Thank you!
Hi Matt, I understand that you created an array of 10 values and two rows as data points to extract for the frequency 80.1.
I understand that for my purposes I would want to replace these values with lat and lon
linspace(4,8,10) %becomes lat
400:401 %becomes lon
%vardata available at https://drive.google.com/file/d/1wnIFacUnRgkvSHy0MARsRUe1UBUxVsEr/view?usp=sharing
vardata=ncread('TL__Map1_15C_sand1__20mres_-36.265137N_174.790466','TLdata');
H_latdata=ncread('TL__Map1_15C_sand1__20mres_-36.265137N_174.790466','H_latdata');
H_londata=ncread('TL__Map1_15C_sand1__20mres_-36.265137N_174.790466','H_londata');
H_freqdata=ncread('TL__Map1_15C_sand1__20mres_-36.265137N_174.790466','H_freqdata');
whos vardata
Name Size Bytes Class Attributes
vardata 91x489x280 49838880 single
%where 91 is frequency, 489 is longitude, 280 is latitude (I got this wrong
%in OP sorry)
%x2 is a 7200x1 array of longitude of interest (attached)
%y2 is a 7200x1 array of latitude of interest (attached)
F=griddedInterpolant(vardata);
%vardata (freq, lon, lat)
extract=F({30,x2,y2});
extract=squeeze(extract);
[row,col]=find(~isnan(extract));
row =
0×1 empty double column vector
col =
0×1 empty double column vector
and whilst this 'works', it returns NaN for all values.
I have attached a visual display of what I am trying to do. The vardata array is illustrated by the pcolor plot where the colorbar is data for the frequency '30'. On top of this I have displayed the dummy data points which I would like to extract data for (x2,y2). For every blue point, I want to know the value in the pcolor plot. The white area is land so I expect that to be NaN.
Here is the code for the figure
% Plot map
[p,m,n] = size(vardata) ;
for i = 30 %for frequency 30
pcolor(H_londata,H_latdata,squeeze(vardata(i,:,:))');
shading interp
drawnow
end
hold on
mapshow(x2,y2) %points of interest for which to extract data
colorbar
caxis([0 100])

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Geographic Plots en Centro de ayuda y File Exchange.

Productos

Versión

R2021a

Etiquetas

Preguntada:

el 25 de Nov. de 2021

Comentada:

el 28 de Nov. de 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by