Empty Figures because of empty variables
Show older comments
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
Adam
on 18 Jul 2019
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.
Thomas Vescovini
on 18 Jul 2019
Edited: Thomas Vescovini
on 18 Jul 2019
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.
Guillaume
on 18 Jul 2019
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.
Thomas Vescovini
on 18 Jul 2019
Edited: Thomas Vescovini
on 18 Jul 2019
Steven Lord
on 18 Jul 2019
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.
Accepted Answer
More Answers (1)
Guillaume
on 18 Jul 2019
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
Thomas Vescovini
on 18 Jul 2019
Guillaume
on 18 Jul 2019
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.
Categories
Find more on Cell Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!