Empty Figures because of empty variables

Hello, I made a code to create time series et climatological graphics but my figure remain empty, I've noticed that I have some of my matrix how are filled with "NaN" but i don't really know where the problem come from, or at least how to fix it... Here is the code : (titles are in french sorry for that)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CREATION DES SERIES MENSUELLES DES PIXELS.%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Chargement des données brutes.
%-------------------------------
T = Morocco0218
% parse dates
[y,m,d] = datevec(T.acq_date);
Tdate = table(y,m,d,'VariableName',{'year','month','day'});
% Create new table
CAD_FEUX = [Tdate,T(:,{'latitude','longitude'})];
MAT=CAD_FEUX;
MAT_YEAR=CAD_FEUX(:,1);
MAT_MOIS=CAD_FEUX(:,2);
MAT_JOURS=CAD_FEUX(:,3);
% Série mensuelle.
%-----------------
SM_TPS1(2002,2018);
load('time.mat')
u=0;
for j=2002:2018
u=u+1;
BLOC_1=find(isequal((MAT_YEAR(:,1)),j));
BLOC_ANNEE_T=MAT(BLOC_1,:);
k=0;
for t=1:12
k=k+1;
x1=find(isequal((MAT_MOIS(BLOC_1,1)),t));
if numel(x1)==0;
MOY_J=NaN;
else
MOY_J1=numel(BLOC_ANNEE_T(x1,1));
MOY_J=MOY_J1;
end
MOY_T(k,1)=MOY_J;
end
Matrice(:,u)=MOY_T;
end
r1=numel(Matrice(1,:)); % Stockage des valeurs de "Valeur" dans une matrice colonne.
o1=0;
for m1=1:r1
for m11=1:numel(Matrice(:,1));
o1=o1+1;
values11=cat(1,Matrice(m11,m1));
PIX_MENS(o1,:)=values11;
end
end
MAT_PIX=cat(2,MAT_TPS,PIX_MENS);
clear u r1 o1 x1 m1 m11 BLOC_1 values11 Matrice k t MOY_T MOY_J j BLOC_ANNEE_T
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Série climatologique globale.%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
c=0;
for j=1:12;
c=c+1;
x=find(MAT_PIX(:,2)==j);
MOY_MAT=nanmean(MAT_PIX(x,3));
STD_MAT=nanstd(MAT_PIX(x,3));
CLIMATO_PIX(c,1)=MOY_MAT;
DISP_PIX(c,1)=STD_MAT;
end
clear x j c
save MAT_PIX_SA.mat MAT_PIX CLIMATO_PIX DISP_PIX
%%%%%%%%
%FIGURE%
%%%%%%%%
%SERIE CLIMATO
%--------------
scrsz=get(0,'ScreenSize');
figure1 = figure('Position',[1 1 scrsz(3)/2.2 scrsz(4)/2.4]); %[ left bottom largeur hauteur]
TPS2=1:length(CLIMATO_PIX(:,1));
errorbar(TPS2,CLIMATO_PIX,DISP_PIX,'o--')
xlim([0 13])
set(gca,'xtick',1:1:12,'xtickLabel',{'J';'F';'M';'A';'M';'J';'J';'A';'S';'O';'N';'D'},'fontweight','bold');
xlabel('Month','fontweight','bold')
ylabel('PIXELS','fontweight','bold')
grid on
%SERIE MENSUELLE
%---------------
scrsz=get(0,'ScreenSize');
figure5 = figure('Position',[1 1 scrsz(3)/2.2 scrsz(4)/2.4]); %[ left bottom largeur hauteur]
TPS=1:length(MAT_PIX(:,1));
plot(TPS,MAT_PIX(:,3),'o--')
fin=numel(MAT_PIX(:,1));
xlim([0 fin+10])
set(gca,'xtick',1:24:fin,'xtickLabel',{'2002';'2004';'2006';'2008';'2010';'2012';'2014';'2016';'2018'},'fontweight','bold');
xlabel('Year','fontweight','bold')
ylabel('PIXELS','fontweight','bold')
grid on
PIX_MENS, CLIMATO_PIX and DISP_PIX are empty as well as MAT_PIX where only the third variable of the table is empty. They are all needed to plot to graph but I have no clue about how to fix the problem...
If anyone can help me...
Have a good day,
Thomas V.

7 Comments

Simplest option is just to step through line by line with the debugger, checking your variables contain what you expect.
At a glance:
T = Morocco0218
doesn't make any sense. You attach a .mat file with this name, but this is not valid syntax to load it. If Morroco0218 is a script or another function then it is anyone's guess what it returns into T. Also we have no idea what is in 'time.mat' which you just load directly into the workspace so it will dump whatever it contains into the workspace, overwriting anything that may have the same name as these variables.
Morocco0218 is the table contained in Morocco0218.mat. Why you would rename a perfectly good and meaningful name to the completely meaningless T, I have no idea.
That Morocco0218 table contains date stored as datetime. Converting that to anything else, in particular date vectors is also a complete waste of time.
We don't know what the intent of the code is as it's not commented (why?) and we're not told anything about the other inputs, but it looks like the intent of the code is calculating monthly and yearly statistics of something. This can be done in just one line of code and we can show how to do it if we know what the something is.
edit: looking a bit more at the code. We have lots of pointless renaming and recreation of data that already exist. Thomas, you need to be more rigorous when writing code. We have
T = Morocco0218
MAT=CAD_FEUX;
MOY_J=MOY_J1;
Choose one name and stick to it. Morocco0218 is a lot better than T, at least we know the data has something to do with Morocco. Similarly, CAD_Feux has got something to do with fires (or traffic lights?).
And then we have:
Tdate = table(y,m,d,'VariableName',{'year','month','day'});
CAD_FEUX = [Tdate,T(:,{'latitude','longitude'})];
MAT=CAD_FEUX;
MAT_YEAR=CAD_FEUX(:,1);
MAT_MOIS=CAD_FEUX(:,2);
MAT_JOURS=CAD_FEUX(:,3);
So, MAT_YEAR is the first column of the table. Why extract it in the first place. Use the table. But in addition, you know that the first column of the table is y because that's how you created it. So really, this was just a very roundabout way of doing:
MAT_YEAR = y;
Again, we have two variables holding the same thing.
As for
find(isequal((MAT_YEAR(:,1)),j))
I can tell with absolute confidence that this will always find nothing unless MAT_YEAR has only one row since for things to be equal with isequal they must be exactly the same size and j is scalar.
find(MAT_YEAR(:, 1) == j)
would work better (but completely unnecessary)
Thomas, please explain in more details what you're trying to do, so we can show you how to do it a lot more simply.
Ok so i'm trying to plot the timeseries (monthly means climatology and month by month climatology of fire pixels amount in a region). After using the debuging tool I found that the problem is here :
Apparently, values11 is filled with NaN and so PIX_MENS end to finally be filled with NaN...
Also as you ask, time.mat contain the month and the years nothing that really matter at this point...
EDIT :
Yes, I obviously know there is a lot of mistakes in my code, or line that serve to nothing... I just started working with matlab so I'm still discovering the language! Thanks for your advices! So yes, if you have any easier way to plot timeseries of the fire pixels i'm listening! I need the Monthly climatology and the monthly mean climatology over the years (2002 to 2018).
Well, Matrice doesn't get altered since line 46 so if it has NaNs on line 55 then it will have then on line 46. Which then leads you to look at MOY_T to see what that contains.
Looking further up you have this block:
if numel(x1)==0;
MOY_J=NaN;
and MOY_T is assigned from MOY_J so you should immediately be looking at that condition as it would appear your code always enters that block rather than the else of the statement. Then this would lead you back to investigate x1, etc, etc...
That is how you need to go about your debugging. Keep working upwards to the root of the problem, unless you are able to locate the root of the problem on the first debugging pass and eliminate the need to start so far down.
Apparently, values11 is filled with NaN
Yes, as I've explained your find will never find anything because you're using isequal. You fill your matrices with NaN when find doesn't find anything.
I need the Monthly climatology and the monthly mean climatology over the years (2002 to 2018)
What's the difference between Monthly climatology and monthly mean climatology? And the mean of what? The table you've attached only has latitude and longitude, is that what you want to average?
Please explain in more details what the inputs are.
That is how you need to go about your debugging. Keep working upwards to the root of the problem, unless you are able to locate the root of the problem on the first debugging pass and eliminate the need to start so far down.
Ok I'll look deeper in the problem!
Yes, as I've explained your find will never find anything because you're using isequal. You fill your matrices with NaN when find doesn't find anything.
In the first place I put "==j" but matlab reported a bug so i change it the isequal and it worked like that... obviously it lead to new problems...
Undefined operator '==' for input arguments of type 'table'.
What's the difference between Monthly climatology and monthly mean climatology? And the mean of what? The table you've attached only has latitude and longitude, is that what you want to average?
When I said monthly mean climatology I meant Monthly mean evolution like the mean of each january from 2002 to 2018 of the fire pixels etc till december! And Monthly climatology like each month over the years from 2002 to 2018!
Ideally you shouldn't need to convert your table into an array. You may need to index into the table to extract the data from it, but converting the whole thing smells funny.
Can you describe in more detail in words, not code what your table contains (what are the names of its variables and what does each represent), what processing you want to perform on each of those columns (again in words not code), and what quantities you want to visualize? That may help us understand your goal better than reading through the code.
In addition, perhaps the variable names you're using have some meaning in climatology with which I'm not familiar but I'd err on the side of using longer, more descriptive names. If you define the table in the base workspace then you can use tab completion while writing your script in the Editor to complete those longer, more descriptive names. That'll help you save some typing.

Sign in to comment.

 Accepted Answer

It's all right I've found the solution, I just needed to do a table2array on MAT_YEAR so I could use the operator "==".
Thanks for your help and if you have any idea to simplify the code I would be glad to ear it!
Have a good day!

1 Comment

I just needed to do a table2array on MAT_YEAR
Or you need to learn how to access data in table,i.e
MAT_YEAR{:, 1} == j
instead of
MAT_YEAR(:, 1) == j
Nonetheless, as I keep saying your whole code can be replaced by a few simple lines which would be a lot easier to read, debug, etc. If only you'd explained what you're trying to do as I asked....

Sign in to comment.

More Answers (1)

Right, since we're not getting the required explanation of what you're trying to do, here is how to calculate monthly latitude and longitude for the only data you've given us (the morocco mat file). I doubt that's what you're trying to do, but that's the only thing we've got to work with.
One of the many ways to get a monthly mean and standard deviation is:
%this assume that you have the morocco2018 table
Morocco0218.month = month(Morocco0218.acq_date);
monthlymean = varfun(@mean, Morocco0218, 'GroupingVariables', 'month', 'InputVariables', {'latitude', 'longitude'})
That's it. Note that in newer versions of matlab, it would be even easier.

2 Comments

More clearly, I wanted to plot the amount of fire pixels (climatology and time serie) in a specific region.
Each line of the table represent one fire pixel and so I needed to count the number of fire per month and plot them... The geographical coordonates in the table are not needed!
Sorry I though it was clear... But I realized my explaination were very vague. But again, as I said, I just started working with matlab so I have a very limited knowledge about it.
Ah, ok. In that case:
year = Morocco0218.acq_date.Year;
month = Morocco0218.acq_date.Month;
[yearmonth, ~, uid] = unique([year, month], 'rows');
count = accumarray(uid, 1);
monthlycount = array2table([yearmonth, count], 'VariableNames', {'Year', 'Month', 'Count'})
Again, it would be even easier in newer versions of matlab than R2016a.

Sign in to comment.

Categories

Products

Release

R2016a

Community Treasure Hunt

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

Start Hunting!