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?

 採用された回答

Tessa Kol
Tessa Kol 2020 年 9 月 28 日

0 投票

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.

その他の回答 (1 件)

Adam Danz
Adam Danz 2020 年 9 月 22 日
編集済み: Adam Danz 2020 年 9 月 24 日

1 投票

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 件のコメント

Tessa Kol
Tessa Kol 2020 年 9 月 24 日
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 2020 年 9 月 24 日
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.
Tessa Kol
Tessa Kol 2020 年 9 月 25 日
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 2020 年 9 月 25 日
編集済み: Adam Danz 2020 年 9 月 25 日
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 2020 年 9 月 25 日
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 2020 年 9 月 25 日
N_run, col, and possibly other variables are also not defined.
Tessa Kol
Tessa Kol 2020 年 9 月 25 日
N_run = 2 and length(col) = 7
Adam Danz
Adam Danz 2020 年 9 月 25 日
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.
Tessa Kol
Tessa Kol 2020 年 9 月 25 日
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.

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeData Type Identification についてさらに検索

製品

リリース

R2020b

質問済み:

2020 年 9 月 22 日

回答済み:

2020 年 9 月 28 日

Community Treasure Hunt

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

Start Hunting!

Translated by