Bar3 crahes by plotting a cell array in a loop

Hi,
I have a M, which is a cell Array M, which is 1×1 cell array of {1×292 cell}. Each of the 292 consits again of cells different sizes
. M{1}=ans
1×292 cell array
Columns 1 through ...292
{1×288 cell} {1×288 cell} {1×287 cell} ...{1x260}.
Each of these cells consits of doubles with different number of rows but fixes amount of columns(15).
m{1}{1}= ans
1×288 cell array
Columns 1 through ...288
{34×15 double} {36×15 double} {37×15 double}.. {95x15}.
I would like to plot M with bar3. My code:
figure();
Az=(1:1:15);
for t1=1:292
for t2=1:length( M{1}{t1})
bar3(Az,(cell2mat(M{1}{t1}(t2))');
hold on;
end
end
After ~2h matlab has crahesd (killed)
Is there another way to plot it?

 채택된 답변

I think it is not quite clear what your result should be. One of your "doubles"-matrecies is already enough to plot a 3D-Bar plot. What you do is plotting multiple plots in the same figure. If this is your desired solution I don't think it is possible to remove the for-loop.
Still your (wanted solution) should result in a very messy figure. I made a simplified example in the form of your data below. You can see that the bars intersect each other and it is not really good to use as a visualization.
You can check the 'grouped' option in the documentation, which allows different bars at the same position. This would obviously need code adaptation. And on a datasize of yours the bars would probably be very hard to see.
As a tipp, you should create a small example with your data and work with this first, to avoid long loading times.
PS: The bracket "(" in front of cell2mat in your code is to much
N = {{[1,2,3,4,5; 6,7,8,9,10]},
{[1,2,3,4,5; 6,7,8,9,10]*2},
{[1,2,3,4,5; 6,7,8,9,10]*3},
{[1,2,3,4,5; 6,7,8,9,10]*4}};
M = {N};
figure(1); clf; hold on;
Az = (1:1:5);
for t1 = 1:length(M{1})
for t2 = 1:length( M{1}{t1} )
bar3(Az, cell2mat(M{1}{t1}(t2))');
end
end
view([-25.10 33.53])

댓글 수: 7

CSCh
CSCh 2023년 5월 3일
Thank you Nathan for you answer.
You are right, the results becomes overloaded, but for my pupose it is enough to indicate peaks, not each single bar. it is a pitty, that there is not a workaround to the loop.Thanks!
If you only need the peaks there should be a faster way to do this. "Plotting" is normally time expensive when compared to calculating numbers.
You should use the for-loops to create a new temporary matrix first. Always compare the temporary matrix (temp) with the current matrix (A) and choosing the largest one. This is done with the max() function:
temp = [1 2 3 4 5 6;
2 3 4 7 8 9];
A = [3 2 1 4 4 7;
1 2 3 7 7 6];
temp = max(temp, A)
temp = 2×6
3 2 3 4 5 7 2 3 4 7 8 9
This only works with identical matrix sizes so you have to pad the matrix A. And in your case the temp-matrix has to be large enough to fit the "biggest" data.
Then you only need the bar3()-function to run once at the end, using the temp-matrix. This should also be much more performant when plotting the figure.
PS: It should be possible to remove the for-loops with this and just use indexing, but this is in my opinion very prone to error
CSCh
CSCh 2023년 5월 4일
Hi Nathan,Thank you for your solution. However, I do not fully understand the "temp" matrix. In your example, matrix A should be the matricies of my array M (m{1}{1}), right? "temp" should of the same size of A, randomly filled? The result "temp" is not clear to me.
Yes A is M{1}{1}, or rather M{1}{t1} and is therefore different in every loop. The temp variable gets initialized once at the beginning. If your maximum values are all positive, you should initialize with zeros.
temp has size (?, 15) where ? is the maximum numbers of rows in your data. If you do not know that you can find it out by itterating over the data once in the beginning. The 15 comes from the "fixes amount of columns" you know.
And since your data is not all the same size you have to pad the A-matrix. So A should be the size of temp and not temp should be the size of A. Hope you know what i mean.
Here is some code that should work on your data. note I'm using N instead of M{1} for readability.
N = {{[ 1,2,3,4,5;
6,7,8,9,10;
9,8,7,6,5]}
{[ 1,2,3,4,5;
6,7,8,9,10
9,8,7,6,5;
1,2,3,4,5]*2}
{[ 1,2,3,4,5;
6,7,8,9,10]*3}
{[ 1,2,3,4,5;
6,7,8,9,10]*4}};
M = {N};
N = M{1}; % using N to read the code easier
% find maximum number of rows
maxRows = 0;
for t1 = 1:length(N)
[row, colum] = size(N{t1}{1});
maxRows = max(maxRows, row);
end
% find maximum for every position
temp = zeros(maxRows, colum);
for t1 = 1:length(N)
A = N{t1}{1};
[rowA, ~] = size(N{t1}{1});
A = padarray(A, maxRows-rowA, 0, 'post');
temp = max(temp, A);
end
Az = (1:colum);
figure(1); clf; hold on;
bar3(Az, temp'); % plotting
view([-25.10 33.53])
CSCh
CSCh 2023년 5월 4일
Thank you very much Nathan for the code, now I just need a workaround for padarray.
This should work, instead of the row with the padarray()-function:
A = [A; zeros(maxRows-rowA, colum)];
And remember to accept the answer if you are satisfied.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

CSCh
CSCh 2023년 5월 5일

0 개 추천

Works great. Thank you.

댓글 수: 3

CSCh
CSCh 2023년 5월 8일
Dear Nathan, just again a question, how can I get the mean values for all my matrices, so that I have at the end a single meanMatrix of (maxRowsx colum) for the entire 1x292cell array.
I would use the same loop and pad with NaNs:
B = [N{t1}{1}; nan(maxRows-rowA, colum)];
Then store all B matrecies in one 3 dimensional matrix
C = nan(maxRows, colum, 0) % define outside of loop
C(1:maxRows, 1:colum, end+1) = B; % inside of loop
Then just take the mean in the third axis and omit the NaN values.
mean(C,3,"omitnan")
This is not the optimal solution, but should be enough for one calculation.
It is really weird why the data is stored in the way it is when it is useful to take the mean of all values. Just wondering.
CSCh
CSCh 2023년 5월 9일
The data are stored daywise, each day has several amount of data. Thank you.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Logical에 대해 자세히 알아보기

제품

릴리스

R2022b

질문:

2023년 5월 2일

댓글:

2023년 5월 9일

Community Treasure Hunt

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

Start Hunting!

Translated by