How to plot weeknumbers (integers) in a graph without leaving gaps for weeks that do not exist

조회 수: 7 (최근 30일)
In my project it is customary to plot certain observed events as a function of week number, where the week number is registered in datafiles as integers using the syntax YYWW (YY = last two digits of the year, WW = week number); for example, week 3 for year 2023 is stored as 2303.
Reading this data from the source datafile and plotting it is easy. However, since every year has 52 weeks, there is obviously no data for week 53 to 00. This means that there will be large gaps in the plot. See attachment for an example.
Aside from the fact this simply does not look nice, it is also a problem when using the plot to perform a trend analysis and/or fitting the data.
As such I am looking for a way to exclude non-existing weeks from the graph (while keeping weeks that do exist but for which no data has been accumulated) so that the gaps disappear and I have a continuous plot, but which still shows the weeknumbers on the x-axis.
  댓글 수: 4
Stephen23
Stephen23 2023년 6월 13일
Question: do you require the plots to also use exactly that format or is it acceptable for the plots to use e.g. Y:M:D (or any other format currently supported by DATETIME). Because the simplest general solution would be to convert those dates to DATETIME, and then simply plot with those. This has the benefit that it will scale, adjust the ticks, etc automatically with your data, i.e. the plotting would then be trivially easy.
But only you can tell us, if that would be acceptable.
Otherwise, if that exact format must be used, then there will be quite a bit of fiddling about with tickmarks...
Raoul de Rooij
Raoul de Rooij 2023년 6월 14일
I would not say it is 'required'; the most important thing is that I plot a certain value for each week of the year, and plotting that as a date is not forbidden. However, plotting it as a weeknumber is the norm in my project and thus preferred.

댓글을 달려면 로그인하십시오.

답변 (2개)

Les Beckham
Les Beckham 2023년 6월 13일
Maybe you can adapt this approach to your situation.
dt = datetime(2023,1,[1 8 15 22 4*22+3*[7 14 21]]) % example datetime values
dt = 1×7 datetime array
01-Jan-2023 08-Jan-2023 15-Jan-2023 22-Jan-2023 19-Apr-2023 10-May-2023 31-May-2023
y = rand(size(dt)); % example data
plot(dt, y, 'o'); % plot data against actual datetime -- results in a gap in the x axis
grid on
wk = week(dt); % find the week numbers
figure
plot(1:(numel(dt)), y, 'o'); % plot against index -- without a gap
grid on
xticklabels(string(100*(year(dt)-2000) + wk)); % label the x axis with the actual week in YYMM format
xlabel('week (YYWW)')
  댓글 수: 5
Stephen23
Stephen23 2023년 6월 14일
"Seems odd that Jan-01 is considered week 52"
At first sight, yes.
But ISO 8601 makes it clear that week numbering years are not the same as calender years.
Different week definitions for different years... thus my question here:
Only the OP can advise, which definition their project uses.
Les Beckham
Les Beckham 2023년 6월 14일
"Do I understand correctly that this code excludes all the non-exisiting weeks, but also the weeks that exist but for which I have no data?"
It creates the plot such that there is no gap for weeks that have no data. In the example above it skips the missing weeks between 22-Jan-2023 and 19-Apr-2023 -- weeks 2304 through 2315 (in the modified example using 'iso-weekofyear').

댓글을 달려면 로그인하십시오.


Stephen23
Stephen23 2023년 6월 15일
편집: Stephen23 2023년 6월 16일
This turns out to be surprisingly difficult without DATETIME et al supporting ISO 8601 weeknumbers.
The rules for ISO 8601 week numbers and the corresponding years are not a trivial thing to implement:
Here is an alternative approach using the CATEGORICAL class:
First lets create some random fake data (I selected these years to match some examples on that wiki page):
[Y0,M0] = meshgrid(80:81,1:52); % some dates 1980W01 - 1981W52
YW = double(compose("%02d%02d",Y0(:),M0(:))); % integers YYWW
YW([3:6,17:32]) = []; % remove some random dates, because data is never complete
YW = [7952;YW;8201] % add 1979W52 and 1982W01
YW = 86×1
7952 8001 8002 8007 8008 8009 8010 8011 8012 8013
M = rand(numel(YW),3); % random data to plot
Now we can convert to categorical and try some different plots.
The simplest approach only plots the dates that exist in your data. If your data contains all dates between the start and end dates or you are happy to miss the dates that your data does not contain, then this might be sufficient for your needs:
X0 = categorical(YW);
plot(X0,M)
Hmm, it appears that by default the axes show all categories. We could explicitly specify a subset of those ticks:
plot(X0,M)
axh = gca;
idx = mod(double(string(axh.XTick)),10)~=0;
axh.XTick(idx) = [];
However the spacing is not even due to the missing dates (except between YY50 and YY10, where a larger step is expected!)
So we need to filll in the gaps. We can do this by creating every category for every week between the end dates... the complication is that we have to consider the fact that ISO 8601 week-numbering years may have either 52 or 53 weeks in them. Hmmm, not so trivial either.
Here is one approach. We generate every Thursday for those years:
YY = 1900+fix(YW/100); % you need to handle centuries, pivot years, etc.
DW = dateshift(datetime(min(YY),1,1),'dayofweek','Thursday'):calweeks(1):datetime(max(YY),12,31);
Y2 = mod(year(DW),100);
W2 = week(DW,'iso-weekofyear');
Now we can generate all categories, with the correct number of weeks for each year:
C2 = compose("%02d%02d",Y2(:),W2(:))
C2 = 209×1 string array
"7901" "7902" "7903" "7904" "7905" "7906" "7907" "7908" "7909" "7910" "7911" "7912" "7913" "7914" "7915" "7916" "7917" "7918" "7919" "7920" "7921" "7922" "7923" "7924" "7925" "7926" "7927" "7928" "7929" "7930"
Then add those categories to the existing data using SETCATS:
X2 = setcats(X0,C2);
plot(X2,M)
axh = gca;
idx = mod(double(string(axh.XTick)),10)~=0;
axh.XTick(idx) = [];
axh.XLim = X0([1,end]);
Done. The plot shows all data with chronologically correctly spaced weeks, and all expected tick marks.
Hopefully this inspires you to experiment with the CATEGORICAL class... and get something working for you.

카테고리

Help CenterFile Exchange에서 Discrete Data Plots에 대해 자세히 알아보기

제품


릴리스

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by