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

7 Ansichten (letzte 30 Tage)
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 Kommentare
Stephen23
Stephen23 am 13 Jun. 2023
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 am 14 Jun. 2023
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.

Melden Sie sich an, um zu kommentieren.

Antworten (2)

Les Beckham
Les Beckham am 13 Jun. 2023
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 Kommentare
Stephen23
Stephen23 am 14 Jun. 2023
"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 am 14 Jun. 2023
"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').

Melden Sie sich an, um zu kommentieren.


Stephen23
Stephen23 am 15 Jun. 2023
Bearbeitet: Stephen23 am 16 Jun. 2023
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.

Kategorien

Mehr zu Discrete Data Plots finden Sie in Help Center und File Exchange

Produkte


Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by