MATLAB Answers

pltoting a variable with dates on horizontial axis

조회 수: 5(최근 30일)
Muhammad Ramzan
Muhammad Ramzan 5 Sep 2018
댓글: jonas 13 Sep 2018
Hello,
I am importing a data from excel by clicking on excel file and than click import.
the first column in my data is date, that is year , quarter. I want to create a plot of the variables. that i have done but in the figure i want to have date on the horizontal axis. I am having trouble in having date on the horizontal axis.
and i want to shade some of the periods in my plot. like from 1948 to 1950.
Please help me how i can do that.

  댓글 수: 2

jonas
jonas 5 Sep 2018
Please upload the file
Stephen Cobeldick
Stephen Cobeldick 6 Sep 2018
Muhammad Ramzan's "Answer" moved here:
I want to get the picture like this. Please let me now who i can do this. thanks

Sign in to comment.

답변(2개)

jonas
jonas 5 Sep 2018
편집: jonas 12 Sep 2018
Here is something you can work from. I used a trick with the stairs and area functions to make the shaded bars. It may have been a bit overkill to use datetime in this case, but I could not resist. You can skip the first part if you'd prefer to use fraction years.
% load data
data=xlsread('MacroData.xlsx');
t=data(:,1);
y=data(:,7)
% Convert to datetime
year = floor(t);
fyear = years(mod(t,1));
ts=datetime(year,1,1)+fyear;
%Plot data
figure
hold on
h=plot(ts,y)
% fancy some shading? write list of [start time1; end time1; start time2; end time2...] and so on:
t2=[11 1948;10 1949;7 1953;5 1954;6 1957;4 1958;4 1960;2 1961;12 1969;11 1970;11 1973;3 1975;1 1980;7 1980;7 1981;11 1982;7 1990;3 1991;3 2001;11 2001;12 2007;6 2009]
t2=datetime(0,t2(:,1),1)+years(t2(:,2))
y2=zeros(1,length(t2))
y2(1:2:end)=1e6
% Fix shading
[xs,ys]=stairs(t2,y2)
ha=area(xs,ys,'facecolor',[0 0 0],'facealpha',.5,'edgecolor','none')
ylim([min(y) max(y)])
EDIT: Fixed an error found by Peter Perkins

  댓글 수: 11

표시 이전 댓글 수: 8
Muhammad Ramzan
Muhammad Ramzan 9 Sep 2018
@ Walter Roberson I want to have years on x-axis like from 1948 to 2011. Please help
Walter Roberson
Walter Roberson 9 Sep 2018
mydata = xlsread('MacroData.xlsx');
t = mydata(:,1);
TIME = datenum([floor(t), round(mod(t,1)*30-2), 0*t+1]); %converts quarters from .1, .2, .3, .4 into appropriate months
y = mydata(:,2);
myrecessions = {'November 1948' , 'October 1949' ; 'July 1953', 'May 1954' ; 'August 1957', 'April 1958' ; 'April 1960' , 'February 1961' ; 'December 1969', 'November 1970' ; 'November 1973', 'March 1975' ; 'January 1980', 'July 1980' ; 'July 1981' , 'November 1982' ; 'July 1990' , 'March 1991' ; 'March 2001' , 'November 2001' ;
'December 2007' , 'June 2009' };
recessions_datenum = reshape(datenum(myrecessions(:), 'mmmm yyyy'),size(myrecessions));
figure(3)
plot(TIME,y)
recessionplot('recessions', recessions_datenum);
datetick('x','yyyy')
xlim(datenum([1948 1 1; 2011 12 31]))
Tested. But you should re-check which column of data you want to plot: before it was column 7 but you seem to have switched to column 2.

Sign in to comment.


Peter Perkins
Peter Perkins 12 Sep 2018
If possible, use datetimes, not datenums. Jonas' answer seems good, except I think it isn't correct when dealing with the non-standard way that quarters are encoded as fractional years (as tenths!). I thik this would do it:
y = floor(t);
q = 10*years(mod(t,1)); % maybe even round this?
ts = datetime(y,1,1) + calquarters(q);

  댓글 수: 4

표시 이전 댓글 수: 1
Peter Perkins
Peter Perkins 13 Sep 2018

I interpreted "my data is date, that is year , quarter" as meaning .1 for Q1, .2 for Q2, etc. I may be wrong.

But in any case, adding a numeric value to a datetime treats the number as a datenum. You code, I think, wants to treat it as a fractional year, and that's problematic, because how long is one tenth of 2018 and how long is one tenth of 2020? That's why calyears requires integer values as inputs. You've used the years function, which does allow fractions, but it does not account for leap days, and in fact:

   Y = years(X) returns an array of durations with each element equal to the
   number of exact fixed-length (i.e. 365.2425 day) years in the corresponding
   element of X. Y is the same size as X. X may contain non-integer values.
   To create an array of calendar years that account for leap days when used in
   calendar calculations, use the CALYEARS function.

years is really meant as a convenience when you are dealing with very long time spans -- if you want a fixed-length unit of time to express a long duration, 100 "standard" years is easier to understand than 3.1557e+09 seconds. If you are doing a calculation that requires exact numbers, then "three calendar years" doesn't cut it -- the exact length depends on which three years you are talking about. So years(3) is an exact length of time, while calyears(3) is a sort of lazy evaluation that has no unique meaning until you add it to a date.

If you are dealing with calendar arithmetic calyears (and for the same reason, caldays) is what you want to use.

Walter Roberson
Walter Roberson 13 Sep 2018
The input data had year numbers and .1 .2 .3 .4 but no .5 or higher fraction, and the question stated "quarters".
jonas
jonas 13 Sep 2018

Thanks guys, I did not realize the fraction refered to quarter.

@Peter: Thanks a lot for the elaborate explanation. Did not know about calyear, which seems great for dealing with those annoying leap years!

Sign in to comment.

태그


Translated by