Effacer les filtres
Effacer les filtres

How to plot observations against season and time of day?

6 vues (au cours des 30 derniers jours)
abdur rauf
abdur rauf le 23 Mar 2018
Commenté : abdur rauf le 29 Nov 2018
Hello every one,
DayMonth = datetime('12/06/2004');
T = {'19:04 - 19:51:02'};
%T = {'10:10 - 10:30:02'};
%DayMonth = datetime('15/06/2004');
%T = {'03:20 - 03:45:06'};
%DayMonth = datetime('15/07/2005');
%T = {'07:10 - 07:50:07'};
% split to start and end times
startEndTimes = cellfun(@(str) strsplit(str,' - '),T,'UniformOutput',0);
startTimes = cellfun(@(c) c{1},startEndTimes,'UniformOutput',0);
endTimes = cellfun(@(c) c{2},startEndTimes,'UniformOutput',0);
% % add seconds where missing
missingSecondsIdx = cellfun(@length,startTimes) == 5;
startTimes(missingSecondsIdx) = cellfun(@(str) [str ':00'],startTimes(missingSecondsIdx),'UniformOutput',0);
missingSecondsIdx = cellfun(@length,endTimes) == 5;
endTimes(missingSecondsIdx) = cellfun(@(str) [str ':00'],endTimes(missingSecondsIdx),'UniformOutput',0);
% % convert time strings to numbers
startTimeNums = datenum(startTimes,'HH:MM:SS');
EPS = 1e-4;
endTimeNums = datenum(endTimes,'HH:MM:SS') - EPS;
contTime = linspace(startTimeNums(1),endTimeNums(end),200);
repDayMonth = repmat(DayMonth,[2 1]);
repDayMonth = repDayMonth(:);
allTimes = [startTimeNums';endTimeNums'];
allTimes = allTimes(:);
contDayMonth = interp1(allTimes,repDayMonth,contTime);
p=plot([DayMonth(1),DayMonth(1)],[startTimeNums(1),endTimeNums(1)],'b-','Markersize',5,'LineWidth',1);
datetick('x','dd/mm')
datetick('y','HH:MM')
This code gives me the plot given below
Now the plot gives me the correct information's (time and day of month). Now the question is that how to plot the other observations on the same figure?. I tried hold on, but i did not work. I want to get the plot as:
Any help will be appreciated.
Thanks
  6 commentaires
abdur rauf
abdur rauf le 25 Mar 2018
Modifié(e) : Walter Roberson le 25 Mar 2018
@dpb,
thank you sir so much for spending your precious time.
I do not claim that what i have done for getting the plot is correct. This is just to show what i have tried at least.
My PMSE observations time for different years are given below.
12 July 2004 T= 09:02:52 - 09:52:01
13 July 2004 T= 08:00:04 - 08:57:23
T= 09:26:53 - 09:28:18
14 July 2004 T= 09:34:04 - 09:35:18
09 July 2005 T= 08:04:08 - 08:05:54
T= 09:41:52 - 09:43:06
12 July 2007 T= 09:15:00 - 09:27:01
16 July 2007 T= 07:30:58 - 07:31:56
06 July 2008 T= 14:42:42 - 14:46:58
07 June 2010 T= 11:27:12 - 11:33:24
05 July 2011 T= 11:04:50 - 11:07:28
11 July 2011 T= 09:15:40 - 09:19:26
21 July 2011 T= 07:35:02 - 07:54:00
02 July 2012 T= 10:12:14 - 10:21:07
21 June 2013 T= 09:15:26 - 09:16:43
22 June 2013 T= 09:57:07 - 09:58:57
T= 10:41:16 - 10:59:55
T= 11:21:02 - 11:57:55
T= 12:09:31 - 12:55:45
23 June 2013 T= 10:06:00 - 10:20:00
T= 12:32:24 - 12:48:48
26 July 2013 T= 11:40:28 - 11:53:45
17 July 2015 T= 05:48:04 - 05:59:12
T= 06:00:14 - 06:29:55
T= 07:17:21 - 07:50:00
I wish you ignore what i have done to get the required plot. You do it your own way to get a plot showing my PMSE observation time on the corresponding day of month and year.
Thanks
dpb
dpb le 25 Mar 2018
Well, to date (so to speak :) ) that code is all there's been to look at so what else were we to do?
This is a start; we do finally have the datapoints of interest in front of us. Now where's your code that reads those data and tries to create the plot from them? As recommended earlier, I'd suggest to start by normalizing that set of data so can read it conveniently into an array of dates/times (having missing dates in first column can be dealt with, but makes the reading more complicated than just duplicating the date for no more than there are).
Then, insert a NaN between each element in the time vector of start:stop times to stop the line (that's how PLOT() works in Matlab; when it sees NaN in a sequence of points it lifts the pen until the next non-NaN element is reached). If you use a fairly wide line width and format the time on 24hr clock, I'm guessing you'll get a reasonable approximation of the paper's figure.
If you use the builtin datetime object, it will interpret the times axes on its own albeit you may need to set the limits to make presentation look desirable.
The X vector will be the date of the observation for each time period while the Y vector will be the start/stop times. Note you'll have to duplicate the "double-up" the days to match the length of the Y vector.
With so many of your observation times being so short, your plot isn't going to be nearly as solid as the Figure; many of those are just barely going to even show up -- 1 minute out of a day is only 1/1440th of the length of the y axis; don't be surprised if it doesn't show up at all unless you make the marker larger.
At least give it a go on your own; don't expect somebody else to solve your problem for you entirely...

Connectez-vous pour commenter.

Réponse acceptée

dpb
dpb le 28 Mar 2018
Modifié(e) : dpb le 28 Mar 2018
Well, here's a (not quite so) crude second pass...
Incorporated comments from last night -- good luck! :)
timedata=readtable('abdur.dat');
refdate=clock; % use current year for the reference
yr=refdate(1); mo=refdate(2); da=refdate(3);
dates=datetime(timedata.Date,'InputFormat','ddMMMMyyyy','Format','ddMMMM'); % dates, without year
timedata.Start=datetime(timedata.Start,'InputFormat','HH:mm:ss','Format','HH:mm:ss'); % start time; will be relative today's date
timedata.Stop=datetime(timedata.Stop,'InputFormat','HH:mm:ss','Format','HH:mm:ss'); % stop time...
timedata.Date=datetime(strcat(cellstr(dates),num2str(yr)),'InputFormat','ddMMMMyyyy');
% now we've got the necessary data into a table; need to construct line segments to plot
% start by getting unique years and separate list by year
[u,ia]=unique(year(dates)); % unique years, location in dates array first of each year
ib=cumsum([1;3*diff(ia)]); % location in full X,Y vector of start,stop,NaT sets of 3
% each record in start/stop fields is one line segment; introduce NaT to break lines
X=[timedata.Date.'; timedata.Date.'; NaT(1,height(timedata))]; X=X(:);
Y=[timedata.Start.'; timedata.Stop.'; NaT(1,height(timedata))]; Y=Y(:);
H=datenum(Y); H=24*(H-fix(H)); % convert to 0:24 hours for plotting
figure
ib=[ib;length(X)]; % augment index array with final index
plot(X(ib(1):ib(2)),H(ib(1):ib(2)),'linewidth',3) % first year segment
hold on % so can add on
for i=2:length(ib)-1 % and the rest...
plot(X(ib(i):ib(i+1)),H(ib(i):ib(i+1)),'linewidth',3)
end
% dress up plot a little and annotate; much room here for creativity... :)
xlim([datetime(yr,5,1) datetime(yr,8,1)])
legend(num2str(u),'location','southwest')
ylabel('UTC')
This places a line at the correct position on the axes; the width of that line is arbitrary so doesn't actually reflect the time taken by the observation relative to the axis scale.
The "exercise for the student" to do that if this for a published paper or thesis or dissertation would be to convert from using PLOT() and the line to PATCH() or FILL() such that the area actually is representative of the length of a day on the x-axis. That may have the effect of making the data almost invisible, however owing to the extremely short time periods of many of the observations so you may be forced to using a much shorter axis range or other technique to actually be able to visualize your real data as compared to that in the reference paper that had much more observation time.
  12 commentaires
dpb
dpb le 28 Nov 2018
The error message gave you the suggestion... :)
Where are you located so what is the local time zone name/language?
What does the input data you're using look like?
abdur rauf
abdur rauf le 29 Nov 2018
Dear dpb,
Thanks

Connectez-vous pour commenter.

Plus de réponses (2)

abdur rauf
abdur rauf le 30 Mar 2018
Modifié(e) : abdur rauf le 30 Mar 2018
This plot I get by simply using the number of days and start and end time in hours.
Credit goes to my supervisor Li Hailong, who helped me.
%%%For the year 2004
plot([194 194],[9.04 9.87],'r','linewidth',3); %%%194 represents 12 July 2004 and [9.04 9.87] represents the start and end time in hours.
hold on;
plot([195 195],[8.00 8.96],'r','linewidth',3);
hold on;
plot([195 195],[9.44 9.47],'r','linewidth',3);
hold on;
plot([196 196],[9.57 9.59],'r','linewidth',3);
hold on;
%%%For year 2007
plot([193 193],[9.25 9.45],'b','linewidth',3); %%%193 represents 12 July 2007
hold on;
plot([197 197],[7.52 7.54],'b','linewidth',3);
hold on;
%%%For year 2013
plot([172 172],[9.26 9.28],'g','linewidth',3);
hold on;
plot([173 173],[9.95 9.99],'g','linewidth',3);
hold on;
plot([173 173],[10.68 11.00],'g','linewidth',3);
hold on;
plot([173 173],[11.35 11.97],'g','linewidth',3);
hold on;
plot([173 173],[12.16 12.93],'g','linewidth',3);
hold on;
plot([174 174],[10.10 10.33],'g','linewidth',3);
hold on;
plot([174 174],[12.54 12.81],'g','linewidth',3);
hold on;
plot([207 207],[11.68 11.89],'g','linewidth',3);
hold on;
%%%For year 2015
plot([198 198],[5.80 5.98],'m','linewidth',3);
hold on;
plot([198 198],[6.00 6.50],'m','linewidth',3);
hold on;
plot([198 198],[7.29 7.83],'m','linewidth',3);
set(gca,'xlim',[153 214]);%%%Day number '153' represents 1 June and day number '213' represents 31 July
set(gca,'ylim',[0 24]);
set(gca,'XTick',[153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214]);
set(gca,'XTickLabel',{'Jun','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','Jul','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','Aug'})
text(154,10,'\fontsize{07}\fontname{Arial}2004')
text(154,8,'\fontsize{07}\fontname{Arial}2007')
text(154,6,'\fontsize{07}\fontname{Arial}2013')
text(154,4,'\fontsize{07}\fontname{Arial}2015')
end
  4 commentaires
abdur rauf
abdur rauf le 31 Mar 2018
Thank you sir,
I am putting things together for your new answer and try to understand it. I come across many commands which i have not seen before.
Once again, thanks for spending your precious time for helping me.
dpb
dpb le 31 Mar 2018
Glad to help as long as see evidence of trying; just can't always find the time immediately at the time of the question.
The number of available functions in Matlab can be overwhelming initially, granted; it takes "time in grade" to begin to become familiar with the various families of functions for graphics, string/character variables, input/output functions, time/date handling, etc., etc., etc., ... The key is that to learn your way around and to get started one must use the the documentation relentlessly and keep looking for things that might be related to what one is trying to accomplish.
One tool that doesn't get much recognition nor mention any longer with the change to having the documentation webpage-based are the venerable lookfor and help commands. 'help' by itself will list all the various areas and then drilling down to a section will list all the functions of that type on one page with a one-line description of what they do. This is an invaluable way to see what functions exist that may be useful for a given problem area before digging into the details of any particular one that looks like might be useful.
While TMW keeps trying to make things easier for newbies by introducing more high-level abstractions for data types and i/o functions and the like, it also does expand the number of functions to make the maze even more complex from that standpoint -- it's a catch-22 kind of deal or "there is no free lunch"...
Good luck, this should get you on your way; will be interested in seeing your final result...

Connectez-vous pour commenter.


dpb
dpb le 30 Mar 2018
Modifié(e) : dpb le 30 Mar 2018
Somewhat more enhanced...turned into a function with some input parameters to control some features; uses the same input data file I created before; we've beat that subject to death; use whatever format you choose...just fix up the 'InputFormat' format string to match whatever your chosen form looks like.
function rauf(file,fixLeap,minObs)
% Plot observation durations as season of year grouped by year
% RAUF(file, fixLeap, minObsLength)
% file - input data file
% fixLeap - flag for leap year day adjustment; T--> Do
% minObs - minimum length of observation to plot, seconds
timedata=readtable(file);
refdate=clock; % use current year for the reference
yr=refdate(1); mo=refdate(2); da=refdate(3);
dates=datetime(timedata.Date,'InputFormat','ddMMMMyyyy','Format','ddMMMM'); % dates, display without year
% fix up for leap year if desired; add one to day if after Feb and is leap year
if fixLeap % if ask to make fixup
is=isleapyr(dates) & month(dates)>2; % find in leap year and7 after February
dates(is)=dateshift(dates(is),'start','day','next'); % shift those to next day
end
timedata.Start=datetime(timedata.Start,'InputFormat','HH:mm:ss','Format','HH:mm:ss'); % start time; relative to day's date
timedata.Stop= datetime(timedata.Stop, 'InputFormat','HH:mm:ss','Format','HH:mm:ss'); % stop time...
timedata.Date=datetime(strcat(cellstr(dates),num2str(yr)),'InputFormat','ddMMMMyyyy'); % date in reference year
timedata.ObsTime=timedata.Stop-timedata.Start; % add in observation duration
% now here's the place to introduce a minimum observation time to consider...
isLong=seconds(timedata.ObsTime)>minObs; % logical addressing if long enough
plotdata=timedata(isLong,:); % subset only those long enough to plot
dates=dates(isLong); % original dates to match so have year
% construct line segments to plot
% start by getting unique years and separate list by year
[u,ia]=unique(year(dates)); % unique years, location in dates array first of each year
ib=cumsum([1;3*diff(ia)]); % location in full X,Y vector of start,stop,NaT sets of 3
% each record in start/stop fields is one line segment; introduce NaT to break lines
X=[plotdata.Date.'; plotdata.Date.'; NaT(1,height(plotdata))]; X=datenum(X(:));
Y=[plotdata.Start.'; plotdata.Stop.'; NaT(1,height(plotdata))]; Y=datenum(Y(:));
Y=24*(Y-fix(Y)); % convert to 0:24 hours for plotting
figure
ib=[ib;length(X)]; % augment index array with final index
plot(X(ib(1):ib(2)),Y(ib(1):ib(2)),'linewidth',3) % first year segment
hold on
for i=2:length(ib)-1
plot(X(ib(i):ib(i+1)),Y(ib(i):ib(i+1)),'linewidth',3)
end
% dress up plot a little and annotate; much room here for creativity... :)
hAx=gca; % get axis handle to local variable
xlim([datenum(yr,6,1) datenum(yr,8,1)]) % set axis limits; fixup as wanted
datetick('x','mmm,'keeplimits') % set abbreviated month as label
xtk=hAx.XTick; % retrieve tick values
hAx.XAxis.MinorTickValues=xtk(1):xtk(end); % set minor tick values for day markers
hAx.XMinorTick='on' % turn minor ticks on so show up
ylim([0 24]) % 24-hr scale
hAx.YTick=(0:4:24); % show even tick marks
legend(num2str(u),'location','southwest'),legend('boxoff')
ylabel('UTC')
Call something like
file='abdur.dat';
fixLeap=1;
rauf(file,fixLeap,10*60)
to use the leapyear fixup and set the observation length to 10 minutes (in seconds). The above generated the following--
%
  3 commentaires
dpb
dpb le 30 Mar 2018
And one last comment regarding the leap year controversy -- the reference year should really be chosen to be a non-leap year or if were to run the code in a leap year as is it would have the axis already drawn for the "plus one" position of March and all months past. Probably just remove the reference to clock and pick an arbitrary year to use; it really has no bearing on anything other than the Matlab variables need something for a year; the code pays no never mind to what that year is but the syntax needs it.
dpb
dpb le 30 Mar 2018
Modifié(e) : dpb le 30 Mar 2018
Just glanced over the Answer to see if caught any typos or other foo-pahs after a little while away and one additional comment may be worthwhile -- when building X, Y for plotting, it may not be clear as to why introduced the NaT between each pair of start/stop times when each pair is a line and so one could draw each pair individually just looping "two-at-a-time". The trouble there is as you ran into doing every line individually is that each new line is a new PLOT() line object and therefore the default color will cycle unless you keep track of other things to decide when it should/should not change and what it should change to. By using the NaT/NaN between, as mentioned very early on, PLOT() "raises the pen" at each resulting in a broken line but all elements in the x, y vectors for each call to PLOT() are still the same line object and so have the same color...it is much easier to thus find those elements within each year to plot at the same time if one thought ahead to set the data up so that there would be line breaks where wanted.
Again, what seems arcane or perhaps much effort without appreciating "why" has a very simple reason behind it and a little more work up front saves a lot later on.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Holidays / Seasons dans Help Center et File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by