Velocity vector plot with empty cell array

With the following code I made a velocity vector plot over time.
%% Velocity vector plot
close all
x_cent = mean(X(1,1:2));
z_cent = mean(Z(1:2,1));
Nx2 = 49;
Nz2 = 49;
bins_x2 = linspace(x_cent,-x_cent,Nx2);
% Bins defined over the height of the silo
bins_z2 = linspace(0.6-z_cent,z_cent,Nz2);
[X2,Z2] = meshgrid(bins_x2,bins_z2);
for i = 1:N_run
for t = 1:length(col)
vx_avr{t,i} = cellfun(@(x)mean(x(:,1)),iwant2(:,:,t,i));
vz_avr{t,i} = cellfun(@(x)mean(x(:,2)),iwant2(:,:,t,i));
end
end
for i = 1:N_run
for t = 1:5
vx_rot{t,i} = rot90(vx_avr{t,i},2);
vz_rot{t,i} = rot90(vz_avr{t,i},2);
end
end
for i = 1:N_run
figure(i)
hold on
for t = 1:length(col)
quiver(X2,Z2,vx_rot{t,i},vz_rot{t,i})
end
end
Below you see an example of a velocity vector plot at t = 4 (which represents 2 seconds)
However, when t = 6 (representing 3 seconds) there are no velocity vectors left resulting in an empty iwant2. When I use the function cellfun to take the mean I get of course an error, because it's empty. How can I make sure that matlab ignores the empty iwant2 and just plot an empty quiver instead?

 Akzeptierte Antwort

Tessa Kol
Tessa Kol am 28 Sep. 2020

0 Stimmen

Solved it myself with an if else statement, see code below.
for i = 1:N_run
for t = 1:length(col)
if cellfun(@isempty,iwant2(:,:,t,i))
vx_avr{t,i} = zeros(Nz2,Nx2);
vz_avr{t,i} = zeros(Nz2,Nx2);
else
vx_avr{t,i} = cellfun(@(x)mean(x(:,1)),iwant2(:,:,t,i));
vz_avr{t,i} = cellfun(@(x)mean(x(:,2)),iwant2(:,:,t,i));
end
end
end
Thank you Adem Danz for your suggestions, it really helped me in finding the final solution to this problem.

Weitere Antworten (1)

Adam Danz
Adam Danz am 22 Sep. 2020
Bearbeitet: Adam Danz am 24 Sep. 2020

1 Stimme

We can't run your code due to missing variables but here are two general suggestions.
Before before we get to that,
  • always preallocate loop variables as shown below
  • use numel() instead of length()
1. If iwant2 is empty, just skip to the next loop and check for empties on all other loops, too. See the 3 conditionals that check for empty arrays.
% Pre allocate loop vars!
vx_avr = cell(numel(col), N_run);
vz_avr = vx_avr;
vx_rot = vx_avr;
vz_rot = vx_avr;
for i = 1:N_run
for t = 1:numel(col)
%if isempty(iwant2(:,:,t,i)); update: this won't work
% continue
%end
vx_avr{t,i} = cellfun(@(x)mean(x(:,1)),iwant2(:,:,t,i));
vz_avr{t,i} = cellfun(@(x)mean(x(:,2)),iwant2(:,:,t,i));
end
end
for i = 1:N_run
for t = 1:5
if isempty(vx_avr{t,i})
continue
end
vx_rot{t,i} = rot90(vx_avr{t,i},2);
vz_rot{t,i} = rot90(vz_avr{t,i},2);
end
end
for i = 1:N_run
figure(i)
hold on
for t = 1:numel(col)
if isempty(vz_rot{t,i})
continue
end
quiver(X2,Z2,vx_rot{t,i},vz_rot{t,i})
end
end
2. If you want to plot "empty" quiver objects, use the same example above but change the last condition to
for i = 1:N_run
figure(i)
hold on
for t = 1:numel(col)
if isempty(vz_rot{t,i})
quiver(nan,nan)
else
quiver(X2,Z2,vx_rot{t,i},vz_rot{t,i})
end
end
end

9 Kommentare

Thank you for helping me and the usefull suggestions of preallocate and numel. However, I did not use
numel(col)
because it counts all the elements of the 7x2 array. Thus, this will give me a value of 14 instead of the value 7 I acquired with using
length(col)
But I understand that numel works faster than length.
I did got an error when implementing your piece of code as follow:
vx_avr = cell(length(col), N_run);
vz_avr = vx_avr;
for i = 1:N_run
for t = 1:length(col)
if isempty(iwant2(:,:,t,i))
continue
end
vx_avr{t,i} = cellfun(@(x)mean(x(:,1)),iwant2(:,:,t,i));
vz_avr{t,i} = cellfun(@(x)mean(x(:,2)),iwant2(:,:,t,i));
end
end
Index in position 2 exceeds array bounds.
Error in SiloV1_results (line 158)
vx_avr{t,i} = cellfun(@(x)mean(x(:,1)),iwant2(:,:,t,i));
Error in SiloV1_results (line 158)
vx_avr{t,i} = cellfun(@(x)mean(x(:,1)),iwant2(:,:,t,i));
Instead of using continue I used a while loop:
vx_avr = cell(length(col), N_run);
vz_avr = vx_avr;
for i = 1:N_run
for t = 1:length(col)
while isempty(iwant2(:,:,t,i))
vx_avr{t,i} = cellfun(@(x)mean(x(:,1)),iwant2(:,:,t,i));
vz_avr{t,i} = cellfun(@(x)mean(x(:,2)),iwant2(:,:,t,i));
end
end
end
But this code returns empty cell array, which are not supposed to be empty
Adam Danz
Adam Danz am 24 Sep. 2020
I guessed that col was a vector. If col is a matrix, use szdim = size(A,dim) instead of length().
Also, I commented-out the first conditional in my answer because I realized iwant2 is a cell array and that conditional test will not work with cell arrays.
There are too many undefined variables. I can troubleshoot further if you provide something I can run on my end.
iwant2 is created with the following code:
% Number of bins over the x-axis
Nx = 75;
% Number of bins over the z-axis
Nz = 67;
% Bins defined over the width of the silo
bins_x = linspace(-0.3077,0.2964,Nx);
% Bins defined over the height of the silo
bins_z = linspace(0.224,0.7628,Nz);
[X,Z] = meshgrid(bins_x,bins_z);
for i = 1:N_run
for t = 1:length(col)
% Plotting the figures is optional and only serves as visualisation purpose
% figure()
xc{t,i} = expData_struc{1,i}{1,row(t,i)}(:,1);
zc{t,i} = expData_struc{1,i}{1,row(t,i)}(:,3);
vx{t,i} = velData_struc{1,i}{1,row(t,i)}(:,1);
vz{t,i} = velData_struc{1,i}{1,row(t,i)}(:,3);
% plot(X,Z,'r',X',Z','r')
% hold on
for m = 1:Nz-1
for n = 1:Nx-1
P = [X(m,n) Z(m,n) ;
X(m,n+1) Z(m,n+1) ;
X(m+1,n+1) Z(m+1,n+1) ;
X(m+1,n) Z(m+1,n)] ;
idx = inpolygon(xc{t,i}(:),zc{t,i}(:),P(:,1),P(:,2));
iwant{m,n,t,i} = [xc{t,i}(idx) zc{t,i}(idx)] ;
iwant2{m,n,t,i} = [vx{t,i}(idx) vz{t,i}(idx)];
% plot(xc{t,i}(idx),zc{t,i}(idx),'.')
% drawnow
end
end
end
end
I results in a 4D-cell. When it comes to
iwant2(:,:,7,1)
the cell array is empty (see pictures)
Unfortunatly, I can't provide the whole code nor can I transfer the big data files. I hope this is enough information.
Adam Danz
Adam Danz am 25 Sep. 2020
Bearbeitet: Adam Danz am 25 Sep. 2020
If I could work with a minimal working example that reproduces the problem it would probably take a couple of minutes to see the problem. But without that, I'm required to read lines of code, guess the values of variables and their sizes, and I have to reverse engineer what you're doing which takes much more time that I unfortunately don't have today.
Tessa Kol
Tessa Kol am 25 Sep. 2020
I realized that you only need the data of iwant2 (attached to this post), which is not a big .mat file. I should have realized it sooner, thus sorry for the inconvenience. Is that enough to serve as a working example?
Adam Danz
Adam Danz am 25 Sep. 2020
N_run, col, and possibly other variables are also not defined.
Tessa Kol
Tessa Kol am 25 Sep. 2020
N_run = 2 and length(col) = 7
Adam Danz
Adam Danz am 25 Sep. 2020
There are other missing vars, too. One example is expData_struc.
You could clear your workspace and try to run only the code you provided so you can see which vars are not defined.
expData_struc is very big (over 1 GB), so that is problematic. I thought that sending the iwant2 in the .mat file iit could reproduce the problem enough. Since I get errors with the following code:
vx_avr = cell(length(col), N_run);
vz_avr = vx_avr;
for i = 1:N_run
for t = 1:length(col)
if isempty(iwant2(:,:,t,i))
continue
end
vx_avr{t,i} = cellfun(@(x)mean(x(:,1)),iwant2(:,:,t,i));
vz_avr{t,i} = cellfun(@(x)mean(x(:,2)),iwant2(:,:,t,i));
end
end
For that piece of code I thought you only need the vars iwant2, length(col) and N_run.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Data Type Identification finden Sie in Hilfe-Center und File Exchange

Produkte

Version

R2020b

Gefragt:

am 22 Sep. 2020

Beantwortet:

am 28 Sep. 2020

Community Treasure Hunt

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

Start Hunting!

Translated by