How to use datetime to plot a range of dates
Show older comments
I am looking to plot data from a range of dates, the code used to plot the data begins after the first for loop, which covers everything until the end of the code. I can use the datetime function to print out all of the days but I am not sure how to implement it in my code to actually plot the entire range of days, which in this case goes from 3-15-17 to 4-4-17. The gauge data is in excel files and the satellite data is in text files which both have the same mm-dd-yr name format. I have an example plot at the bottom of the code for reference. I can clarify anything if needed.
%This code will plot data from a range of dates
%Convert variable year from integer to string
yr=num2str(17);
dy=num2str(15);
mn=num2str(3);
yr2 = num2str(17);
dy2 = num2str(4);
mn2 = num2str(4);
%Create a MMDDYY string
date_str=[mn '-' dy '-' yr];
date_str2=[mn2 '-' dy2 '-' yr2];
for day = datetime(17, 3, 15):datetime(17, 4, 4)
day = datestr(day, 'mm-dd-yy');
%Gauge data location.
gauge_data='C:\Users\bbush\Desktop\Matlab Code\Excel Rain Gauge Data\Daily Rain Accumulation\';
%GOES data location
GOES_loc='C:\Users\bbush\Desktop\Matlab Code\Satellite Rainfall Data\';
%Find GOES data
GOES_fn=[GOES_loc,date_str,'.txt'];
%Find gauge data
gauge_fn=[gauge_data,date_str,'.xlsx'];
%Read in gauge data
[num,raw] = xlsread(gauge_fn); %Reads all data from excel file where num will eventually just be the RNFL totals
latG = num(:,1);
lonG = num(:,2);
RNFLG = num(:,3);
Gauge = cat(2,latG,lonG);
% read in Satellite data
fid = fopen(GOES_fn);
data = textscan(fid,'%f%f%f%f','HeaderLines',0,'CollectOutput',1);
data = data{:};
fid = fclose(fid);
% retrieve columns
data(:,:);
latS = data(:,1);
lonS = data(:,2);
RNFLS = data(:,3);
Satellite = cat(2,latS,lonS);
gLon =-83.275:0.025:-82.85;
gLat = 35.3:0.025:35.8;
Z = griddata(lonS,latS,RNFLS,gLon,gLat');
z = log2(Z);
%Plotting
figure
clf;
load rainmap
cmap = colormap(rainmap);
rainmap = rainmap(2:2:end,:); %Gets ten RGB triplets
levels = 2.^(-3:7); %11 levels
%Plot satellite contours
contourf(gLon,gLat,z,'LineStyle','None')
hold on
caxis([-3 7])
%Plot the Gauge data on top
%Plot No RNFL
idx = find(RNFLG==0);
plot(lonG(idx),latG(idx),'o','Color','k','LineWidth',0.5,'MarkerFaceColor','w','MarkerSize',6); %Empty circle
%Plot Small amount of RNFL
idx = find(RNFLG>0 & RNFLG<0.1250);
plot(lonG(idx),latG(idx),'o','Color','k','MarkerFaceColor','k','MarkerSize',6); %Black circle
for r=1:10 %Ten RGB triplets for coloring rainfall totals
idx = find(RNFLG>levels(r) & RNFLG<levels(r+1)); %Find rainfall totals between level ranges
clr = rainmap(r,:);
plot(lonG(idx),latG(idx),'o','Color','k','MarkerFaceColor',clr,'MarkerSize',6,'LineWidth',1);
end
idx = find(RNFLG>levels(r+1)); %Find rainfall totals greater than the level range
clr = rainmap(r,:);
plot(lonG(idx),latG(idx),'o','Color',clr,'MarkerFaceColor',clr,'MarkerSize',6,'LineWidth',3);
hold off
cbh = colorbar ; %Create Colorbar
cbh.Ticks = linspace(-3, 7, 11) ; %Create 11 ticks from -3 to 7
cbh.TickLabels = num2cell(levels); %Replace the labels of the ticks with the values in level
xlabel('Lon')
ylabel('Lat')
title([date_str,' RNFL Comparison'])
c = load('coast');
hold on;
u = load('us_state_map.mat');
plot(c.long,c.lat,'k')
plot(u.state_lon,u.state_lat)
xlim([-83.27 -82.88])
ylim([35.33 35.77])
end

Ive also attached three rain gauge files and three satellite files if anyone is interested in trying themselves.
4 Comments
dpb
on 20 Jul 2018
I'd suggest converting from xlsread, textscan and the resulting cell arrays to readtable and the resulting table objects that have much to commend for ease in accessing.
As for the date selection, read the dates from the spreadsheet as datetimes and then you can simply do indexing operations on that variable to select the range wanted.
To plot a range, simply create a logical vector of those elements wanted and call plot with the indexed array...
ix=(t>=t1 & t<=t2); % logical vector of those between t1, t2
scatter(long(ix),lat(ix),c) % plot selected w/ color vector
If data files aren't humongous and you can, attach and somebody may have time to look at in more detail...
Read up on the details of using datetime for calculations with dates and times for more background on the above comparisons and also search for "logical addressing" for more on how that works.
dpb
on 20 Jul 2018
Brandon Bush Answered
"Thanks for your answer, I appreciate you having the patience to look through my mess up there. I will certainly try your method. "
dpb
on 23 Jul 2018
Ah! I see the attached files...on reflection I see that's what you described but not quite what I imagined. :) However, it's not that far off to do what I had in mind I think, let me play for a few minutes or so...
Brandon Bush
on 23 Jul 2018
Accepted Answer
More Answers (1)
Try this as outline to retrieve the files desired between two dates...
D1=datetime("3/15/2017"); D2=datetime("3/16/2017"); % set the desired date range
d=dir('*-*-*.xlsx'); % return the list of all files
dn=datetime(extractBefore(cellstr(char(d.name)),'.'),'InputFormat','M-d-yy'); % get datetime array
d=d(ismember(dn,datetime(D1:D2))); % save only those between D1, D2
for i=1:length(d) % iterate over those desired only
g=readtable(d(i).name); % read into a table..
g.RG_=categorical(g.RG_); % turn the RG# into categorical
end
For illustration in going forward, the above leaves you with
>> g(1:4,:)
ans =
4×4 table
RG_ Lat Lon Accumulation
_____ ______ _______ ____________
RG002 35.425 -82.971 0
RG003 35.385 -82.916 0
RG004 35.368 -82.99 0
RG005 35.409 -82.965 4.6595
>>
on each step; I'm not sure precisely what to do inside the loop for each day??? Now, again, this presently is overwriting the variable g ( for "gauge", original huh? :) ) so 'splain zackly what it is that is being plotted; are all of these points on one figure for all times or just what?
If get that clear, then it's probably pretty simple to do what needed...
NB: The D1, D2 values are simply the user-set limits desired; set them in whatever input format is wanted for the UI.
NB2: The same idea works for the .txt files with same naming scheme, of course. You could make the presumption that if you find one set you'll find the other and just open the alternate by changing extension but it's probably more robust to do the directory scan up front and compare first for the user if aren't commensurate sets.
5 Comments
Brandon Bush
on 23 Jul 2018
dpb
on 23 Jul 2018
But what's to be done with each day; a new figure, add to the first or what? I'm not sure where the issue is, precisely about the days.
I guess on re-reading the initial, it isn't to plot a range within the overall set; I thought that's what was the Q?.
But, I still don't know what is to be done by day, precisely...is it just do the same thing for every day with a new figure for each or what?
The first would seem essentially trivial to just add a call to "figure" before beginning to plot; maybe I'm trying to make more out of it than there is???
Brandon Bush
on 23 Jul 2018
dpb
on 23 Jul 2018
OK....I'm beginning to get the picture... :) I was totally off-base from the git-go here of what the issue(s) were, sorry for the distractions.
In that case I will go look at the function; I thought it was basically immaterial to the problem at hand; I think some factoring there may help but probably it can work almost as is...
Brandon Bush
on 23 Jul 2018
Categories
Find more on Annotations 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!
