How to use retime to get the plot of mean and stdev in continous time series
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
Hello there,
I have a datasets containing y-values in multi-years time series. My intention is getting the plot of monthly mean and its shaded error bars. The datasets contain long span of months which crossing the following year, i.e. in my datasets (attached) there from February, 2020 until December 2022.
But, at first, I want to get the data cleaned by selecting only y-value with a certain range. Here is my first sight code:
T = readtable('datamine');
Tr = table2timetable(T, 'RowTimes','time');
Tx = table(Tr.time,Tr.value_y,'VariableNames',{'time_a','val'});
idx = Tx.val>= 12 & Tx.val< 13.4; % selecting only y-value with a certain range
Tx_mean = retime(Tx(idx,:),'monthly','mean'); % get monthly averaged values ==> Failed
Tx_std = retime(Tx(idx,:),'monthly',@std); % get monthly stdev values ==> Failed
I tried to use directly retime function but it failed. Anyone know to get continous monthly mean and its shaded error bars properly?
More or less, the plot should be like this. The x-axis is continous months, crossing the following years:

Thanks!
採用された回答
The correct way to express the deviation of cata around the mean is to use the standard error of the mean, given by:
where σ is the standard deviation and N are the number of data used to calculate it.
T1 = readtable('datamine.xlsx')
T1 = 147152x2 table
value_y time
_______ ____________________
12.887 15-Feb-2020 09:50:00
13.136 15-Feb-2020 10:00:00
13.127 15-Feb-2020 10:09:59
12.894 15-Feb-2020 10:20:00
12.816 15-Feb-2020 10:30:00
12.355 15-Feb-2020 10:39:59
12.317 15-Feb-2020 10:50:00
12.922 15-Feb-2020 10:59:59
13.162 15-Feb-2020 11:10:00
13.163 15-Feb-2020 11:19:59
13.109 15-Feb-2020 11:30:00
13.139 15-Feb-2020 11:39:59
13.148 15-Feb-2020 11:50:00
12.937 15-Feb-2020 12:00:00
12.387 15-Feb-2020 12:10:00
12.695 15-Feb-2020 12:20:00
TT1 = table2timetable(T1)
TT1 = 147152x1 timetable
time value_y
____________________ _______
15-Feb-2020 09:50:00 12.887
15-Feb-2020 10:00:00 13.136
15-Feb-2020 10:09:59 13.127
15-Feb-2020 10:20:00 12.894
15-Feb-2020 10:30:00 12.816
15-Feb-2020 10:39:59 12.355
15-Feb-2020 10:50:00 12.317
15-Feb-2020 10:59:59 12.922
15-Feb-2020 11:10:00 13.162
15-Feb-2020 11:19:59 13.163
15-Feb-2020 11:30:00 13.109
15-Feb-2020 11:39:59 13.139
15-Feb-2020 11:50:00 13.148
15-Feb-2020 12:00:00 12.937
15-Feb-2020 12:10:00 12.387
15-Feb-2020 12:20:00 12.695
SEM = @(x) std(x)/sqrt(numel(x));
TT1momean = retime(TT1, 'monthly', 'mean')
TT1momean = 35x1 timetable
time value_y
___________ _______
01-Feb-2020 12.949
01-Mar-2020 12.659
01-Apr-2020 12.587
01-May-2020 12.393
01-Jun-2020 12.535
01-Jul-2020 12.77
01-Aug-2020 12.802
01-Sep-2020 12.6
01-Oct-2020 12.585
01-Nov-2020 13.011
01-Dec-2020 12.637
01-Jan-2021 12.353
01-Feb-2021 12.727
01-Mar-2021 12.884
01-Apr-2021 12.835
01-May-2021 12.701
TT1mosem = retime(TT1, 'monthly', SEM)
TT1mosem = 35x1 timetable
time value_y
___________ _________
01-Feb-2020 0.0093507
01-Mar-2020 0.0067858
01-Apr-2020 0.00657
01-May-2020 0.0067406
01-Jun-2020 0.0038461
01-Jul-2020 0.0050221
01-Aug-2020 0.0055277
01-Sep-2020 0.0039343
01-Oct-2020 0.0054015
01-Nov-2020 0.0074985
01-Dec-2020 0.0082383
01-Jan-2021 0.0049619
01-Feb-2021 0.0080578
01-Mar-2021 0.004472
01-Apr-2021 0.0032843
01-May-2021 0.0033188
TT1monum = retime(TT1, 'monthly', 'count');
[Nmin,Nmax] = bounds(TT1monum{:,1})
Nmin = 331
Nmax = 4464
% TT1Time = TT1mosem.time;
% TT1SEM = TT1mosem{:,1};
figure
plot(TT1momean.time, TT1momean{:,1}, '-k')
hold on
patch([TT1mosem.time; flip(TT1mosem.time)], [TT1momean{:,1}-TT1mosem{:,1}*1.96; flip(TT1momean{:,1}+TT1mosem{:,1}*1.96)], 'r', 'FaceAlpha',0.25, 'EdgeColor','r')
hold off
grid
xlabel('Time')
ylabel('Value')
title('Mean ±95% CI')

The SEM values are quite small when compared to the mean values (on the order of
) so they are barely visible. I did a separate accumulation for the number of values in each month, and since they were all above 330, using the 95% confidence intervals from the normal distribution is a safe estimate. It is not necessary to use the t-distribution, since it will closely approximate the normal distribution with this many degrees-of-freedom.
) so they are barely visible. I did a separate accumulation for the number of values in each month, and since they were all above 330, using the 95% confidence intervals from the normal distribution is a safe estimate. It is not necessary to use the t-distribution, since it will closely approximate the normal distribution with this many degrees-of-freedom. .
12 件のコメント
Adi Purwandana
2024 年 10 月 19 日
編集済み: Adi Purwandana
2024 年 10 月 19 日
Thank you @Star Strider! Anyway, where should I put my line below as I need to focus on a certain range of values?
OK, I can put it after the first line. Done.
idx = Tx.val>= 12 & Tx.val< 13.4; % selecting only y-value with a certain range
I have one more question please @Star Strider if you don't mind... Is it possible to get the boxchat plot for those continous monthly retime mean? Thank you
As always, my pleasure!
My apologies — I forgot about the restriction.
I included it and the boxchart here —
T1 = readtable('datamine.xlsx')
T1 = 147152x2 table
value_y time
_______ ____________________
12.887 15-Feb-2020 09:50:00
13.136 15-Feb-2020 10:00:00
13.127 15-Feb-2020 10:09:59
12.894 15-Feb-2020 10:20:00
12.816 15-Feb-2020 10:30:00
12.355 15-Feb-2020 10:39:59
12.317 15-Feb-2020 10:50:00
12.922 15-Feb-2020 10:59:59
13.162 15-Feb-2020 11:10:00
13.163 15-Feb-2020 11:19:59
13.109 15-Feb-2020 11:30:00
13.139 15-Feb-2020 11:39:59
13.148 15-Feb-2020 11:50:00
12.937 15-Feb-2020 12:00:00
12.387 15-Feb-2020 12:10:00
12.695 15-Feb-2020 12:20:00
idx = (T1.value_y >= 12) & (T1.value_y < 13.4); % selecting only y-value with a certain range
T1 = T1(idx,:)
T1 = 121962x2 table
value_y time
_______ ____________________
12.887 15-Feb-2020 09:50:00
13.136 15-Feb-2020 10:00:00
13.127 15-Feb-2020 10:09:59
12.894 15-Feb-2020 10:20:00
12.816 15-Feb-2020 10:30:00
12.355 15-Feb-2020 10:39:59
12.317 15-Feb-2020 10:50:00
12.922 15-Feb-2020 10:59:59
13.162 15-Feb-2020 11:10:00
13.163 15-Feb-2020 11:19:59
13.109 15-Feb-2020 11:30:00
13.139 15-Feb-2020 11:39:59
13.148 15-Feb-2020 11:50:00
12.937 15-Feb-2020 12:00:00
12.387 15-Feb-2020 12:10:00
12.695 15-Feb-2020 12:20:00
TT1 = table2timetable(T1);
SEM = @(x) std(x)/sqrt(numel(x));
TT1momean = retime(TT1, 'monthly', 'mean');
TT1mosem = retime(TT1, 'monthly', SEM);
TT1monum = retime(TT1, 'monthly', 'count');
[Nmin,Nmax] = bounds(TT1monum{:,1})
Nmin = 256
Nmax = 4443
% TT1Time = TT1mosem.time;
% TT1SEM = TT1mosem{:,1};
figure
plot(TT1momean.time, TT1momean{:,1}, '-k')
hold on
patch([TT1mosem.time; flip(TT1mosem.time)], [TT1momean{:,1}-TT1mosem{:,1}*1.96; flip(TT1momean{:,1}+TT1mosem{:,1}*1.96)], 'r', 'FaceAlpha',0.375, 'EdgeColor','r', 'EdgeAlpha',0.5)
hold off
grid
xlabel('Time')
ylabel('Value')
title('Mean ±95% CI')

[GV, ID1, ID2] = findgroups(year(T1.time), month(T1.time)); % Grouping Variable For ‘boxchart’
% [b1,b2] = bounds(ID1)
xtl = compose("%s",datetime(ID1,ID2,ones(size(ID1)), Format="MMM yyyy")); % Cell Array Of Time Values
% disp(xtl)
figure
hb = boxchart(GV, T1.value_y);
hb.JitterOutliers = "on";
hb.MarkerStyle = ".";
hb.Notch = "on";
hb.BoxMedianLineColor = "r";
Ax = gca;
xt = Ax.XTick;
Ax.XTick = [1 xt];
Ax.XTickLabel = xtl(Ax.XTick);
Ax.XTickLabelRotation = 45;
xlabel("Time")
ylabel("Value")
title("T1: Boxchart")
axis("padded")

% get(hb)
The boxchart took a bit of time because I do not use it frequently. It uses the original ‘T1’ with the ‘idx’ constraint, not any of the derived timetable arrays.
I defined the XTick locations as:
Ax.XTick = [1 xt];
to include thee first element. It needs to be integers from 1 to 35, within that constraint you can define it however you want. You can change the XTickLabel format by changing the Format string in the ‘xtl’ assignment. (That is the easiest way to do it in this instance.)
.
Great! But, I don't know it didn't work on my 2022a:
- the Xtick label shown as integer instead of MMM yyy
- the BoxMedianLineColor red doesn't show

Are the date time axis and BoxMedianLineColor working only on 2024b, as what you did?
clear all;
clc
T1 = readtable('datamine.xlsx')
idx = (T1.value_y >= 12) & (T1.value_y < 13.4); % selecting only y-value with a certain range
T1 = T1(idx,:)
TT1 = table2timetable(T1);
SEM = @(x) std(x)/sqrt(numel(x));
TT1momean = retime(TT1, 'monthly', 'mean');
TT1mosem = retime(TT1, 'monthly', SEM);
TT1monum = retime(TT1, 'monthly', 'count');
[Nmin,Nmax] = bounds(TT1monum{:,1})
% TT1Time = TT1mosem.time;
% TT1SEM = TT1mosem{:,1};
figure
plot(TT1momean.time, TT1momean{:,1}, '-k')
hold on
patch([TT1mosem.time; flip(TT1mosem.time)], [TT1momean{:,1}-TT1mosem{:,1}*1.96; flip(TT1momean{:,1}+TT1mosem{:,1}*1.96)], 'r', 'FaceAlpha',0.375, 'EdgeColor','r', 'EdgeAlpha',0.5)
hold off
grid
xlabel('Time')
ylabel('Value')
title('Mean ±95% CI')
[GV, ID1, ID2] = findgroups(year(T1.time), month(T1.time)); % Grouping Variable For ‘boxchart’
% [b1,b2] = bounds(ID1)
xtl = compose("%s",datetime(ID1,ID2,ones(size(ID1)), Format="MMM yyyy")); % Cell Array Of Time Values
% disp(xtl)
figure
hb = boxchart(GV, T1.value_y);
hb.JitterOutliers = "on";
hb.MarkerStyle = ".";
hb.Notch = "on";
hb.BoxMedianLineColor = "r";
Ax = gca;
xt = Ax.XTick;
Ax.XTick = [1 xt];
Ax.XTickLabel = xtl(Ax.XTick);
Ax.XTickLabelRotation = 45;
xlabel("Time")
ylabel("Value")
title("T1: Boxchart")
axis("padded")
% get(hb)
Adi Purwandana
2024 年 10 月 19 日
編集済み: Adi Purwandana
2024 年 10 月 19 日
Also, if possible... (I tried but still got no solution), can we put a mean value plot connecting the boxplot? There's likely I need groupsummary.
Just like:

Thank you and sorry for so many following questions.
Everything in my previous code should have worked in R2022a. I checked — all those functions existed from at least R2020b, most earlier. Apparently boxchart wasn’t compatible with string arrays then, so we’ll see if a cell array works with it this time. Adding the mean line to the boxchart is straightforward. I added a legend as well to both plots. You can reposition each as desired, or not use it if you don’t want it.
Try this —
T1 = readtable('datamine.xlsx')
T1 = 147152x2 table
value_y time
_______ ____________________
12.887 15-Feb-2020 09:50:00
13.136 15-Feb-2020 10:00:00
13.127 15-Feb-2020 10:09:59
12.894 15-Feb-2020 10:20:00
12.816 15-Feb-2020 10:30:00
12.355 15-Feb-2020 10:39:59
12.317 15-Feb-2020 10:50:00
12.922 15-Feb-2020 10:59:59
13.162 15-Feb-2020 11:10:00
13.163 15-Feb-2020 11:19:59
13.109 15-Feb-2020 11:30:00
13.139 15-Feb-2020 11:39:59
13.148 15-Feb-2020 11:50:00
12.937 15-Feb-2020 12:00:00
12.387 15-Feb-2020 12:10:00
12.695 15-Feb-2020 12:20:00
idx = (T1.value_y >= 12) & (T1.value_y < 13.4); % selecting only y-value with a certain range
T1 = T1(idx,:)
T1 = 121962x2 table
value_y time
_______ ____________________
12.887 15-Feb-2020 09:50:00
13.136 15-Feb-2020 10:00:00
13.127 15-Feb-2020 10:09:59
12.894 15-Feb-2020 10:20:00
12.816 15-Feb-2020 10:30:00
12.355 15-Feb-2020 10:39:59
12.317 15-Feb-2020 10:50:00
12.922 15-Feb-2020 10:59:59
13.162 15-Feb-2020 11:10:00
13.163 15-Feb-2020 11:19:59
13.109 15-Feb-2020 11:30:00
13.139 15-Feb-2020 11:39:59
13.148 15-Feb-2020 11:50:00
12.937 15-Feb-2020 12:00:00
12.387 15-Feb-2020 12:10:00
12.695 15-Feb-2020 12:20:00
TT1 = table2timetable(T1);
SEM = @(x) std(x)/sqrt(numel(x));
TT1momean = retime(TT1, 'monthly', 'mean');
TT1mosem = retime(TT1, 'monthly', SEM);
TT1monum = retime(TT1, 'monthly', 'count');
[Nmin,Nmax] = bounds(TT1monum{:,1})
Nmin = 256
Nmax = 4443
% TT1Time = TT1mosem.time;
% TT1SEM = TT1mosem{:,1};
figure
hplt = plot(TT1momean.time, TT1momean{:,1}, '-k', "DisplayName",'Monthly Mean');
hold on
hpch = patch([TT1mosem.time; flip(TT1mosem.time)], [TT1momean{:,1}-TT1mosem{:,1}*1.96; flip(TT1momean{:,1}+TT1mosem{:,1}*1.96)], 'r', 'FaceAlpha',0.375, 'EdgeColor','r', 'EdgeAlpha',0.5, "DisplayName","±95% Confidence Interval");
hold off
grid
xlabel('Time')
ylabel('Value')
title('Value Mean & ±95% CI')
legend("Location","NE")

[GV, ID1, ID2] = findgroups(year(T1.time), month(T1.time)); % Grouping Variable For ‘boxchart’
% [b1,b2] = bounds(ID1)
xtl = compose('%s',datetime(ID1,ID2,ones(size(ID1)), Format="MMM yyyy")); % Cell Array Of Time Values
% disp(xtl)
figure
hb = boxchart(GV, T1.value_y, "DisplayName","Boxchart of Monthly Data");
hold on
plot((1:height(TT1momean)), TT1momean{:,1}, '.-r', "DisplayName","Monthly Mean")
hold off
hb.JitterOutliers = "on";
hb.MarkerStyle = ".";
hb.Notch = "on";
hb.BoxMedianLineColor = "r";
Ax = gca;
xt = Ax.XTick;
Ax.XTick = [1 xt];
Ax.XTickLabel = xtl(Ax.XTick);
Ax.XTickLabelRotation = 45;
xlabel("Time")
ylabel("Value")
title("Boxchart of Monthly Data")
hlgnd = legend("Location","northoutside", "Orientation","horizontal");
axis("padded")

% get(hb)
That should work.
.
I really appreciate your help. FYI, I just installed 2024b and it works fine, but not for the 2022a.

It is mostlikely those (adjustable BoxMedianLineColor and date format syntax) are not available in 2022a. I don't know. Anyway, thank you for such very helpful solution. The best as always!
As always, my pleasure!
I did not consider that the other options for boxchart could have been the problem. The ‘Version History’ in the boxchart documentation did not mention any changes.
Sorry @Star Strider, is it possible to adjust the time increment of the x-axis for this latest boxchart plot? For example with regular space every 3 months or 6 months. Thanks!
Yes.
Create a vector using the colon, : operator, with the second (‘increment’ or ‘step’) value being whatever integer value you want. Here, it needs to be an integer since it will be used as a subscript, however that is the only constraint:
Ax.XTick = [1 : 3 : xt(end)]; % Every 3 Months
Ax.XTick = [1 : 6 : xt(end)]; % Every 6 Months
In this code, I commented the every 6 month line so it would not run.
It can also be whatever months you want to display, for example:
Ax.XTick = [2 3 4 7 10 17 22 28 33]; % Specific Months
The only constraint is that they be integers from 1 to 35 (in this instance).
Try this —
T1 = readtable('datamine.xlsx')
T1 = 147152x2 table
value_y time
_______ ____________________
12.887 15-Feb-2020 09:50:00
13.136 15-Feb-2020 10:00:00
13.127 15-Feb-2020 10:09:59
12.894 15-Feb-2020 10:20:00
12.816 15-Feb-2020 10:30:00
12.355 15-Feb-2020 10:39:59
12.317 15-Feb-2020 10:50:00
12.922 15-Feb-2020 10:59:59
13.162 15-Feb-2020 11:10:00
13.163 15-Feb-2020 11:19:59
13.109 15-Feb-2020 11:30:00
13.139 15-Feb-2020 11:39:59
13.148 15-Feb-2020 11:50:00
12.937 15-Feb-2020 12:00:00
12.387 15-Feb-2020 12:10:00
12.695 15-Feb-2020 12:20:00
idx = (T1.value_y >= 12) & (T1.value_y < 13.4); % selecting only y-value with a certain range
T1 = T1(idx,:)
T1 = 121962x2 table
value_y time
_______ ____________________
12.887 15-Feb-2020 09:50:00
13.136 15-Feb-2020 10:00:00
13.127 15-Feb-2020 10:09:59
12.894 15-Feb-2020 10:20:00
12.816 15-Feb-2020 10:30:00
12.355 15-Feb-2020 10:39:59
12.317 15-Feb-2020 10:50:00
12.922 15-Feb-2020 10:59:59
13.162 15-Feb-2020 11:10:00
13.163 15-Feb-2020 11:19:59
13.109 15-Feb-2020 11:30:00
13.139 15-Feb-2020 11:39:59
13.148 15-Feb-2020 11:50:00
12.937 15-Feb-2020 12:00:00
12.387 15-Feb-2020 12:10:00
12.695 15-Feb-2020 12:20:00
TT1 = table2timetable(T1);
SEM = @(x) std(x)/sqrt(numel(x));
TT1momean = retime(TT1, 'monthly', 'mean');
TT1mosem = retime(TT1, 'monthly', SEM);
TT1monum = retime(TT1, 'monthly', 'count');
[Nmin,Nmax] = bounds(TT1monum{:,1})
Nmin = 256
Nmax = 4443
% TT1Time = TT1mosem.time;
% TT1SEM = TT1mosem{:,1};
figure
hplt = plot(TT1momean.time, TT1momean{:,1}, '-k', "DisplayName",'Monthly Mean');
hold on
hpch = patch([TT1mosem.time; flip(TT1mosem.time)], [TT1momean{:,1}-TT1mosem{:,1}*1.96; flip(TT1momean{:,1}+TT1mosem{:,1}*1.96)], 'r', 'FaceAlpha',0.375, 'EdgeColor','r', 'EdgeAlpha',0.5, "DisplayName","±95% Confidence Interval");
hold off
grid
xlabel('Time')
ylabel('Value')
title('Value Mean & ±95% CI')
legend("Location","NE")

[GV, ID1, ID2] = findgroups(year(T1.time), month(T1.time)); % Grouping Variable For ‘boxchart’
% [b1,b2] = bounds(ID1)
xtl = compose('%s',datetime(ID1,ID2,ones(size(ID1)), Format="MMM yyyy")); % Cell Array Of Time Values
% disp(xtl)
figure
hb = boxchart(GV, T1.value_y, "DisplayName","Boxchart of Monthly Data");
hold on
plot((1:height(TT1momean)), TT1momean{:,1}, '.-r', "DisplayName","Monthly Mean")
hold off
hb.JitterOutliers = "on";
hb.MarkerStyle = ".";
hb.Notch = "on";
hb.BoxMedianLineColor = "r";
Ax = gca;
xt = Ax.XTick;
xt = 1×7
5 10 15 20 25 30 35
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Ax.XTick = [1 : 3 : xt(end)]; % Every 3 Months
% Ax.XTick = [1 : 6 : xt(end)]; % Every 6 Months
Ax.XTickLabel = xtl(Ax.XTick);
Ax.XTickLabelRotation = 45;
xlabel("Time")
ylabel("Value")
title("Boxchart of Monthly Data")
hlgnd = legend("Location","northoutside", "Orientation","horizontal");
axis("padded")

% get(hb)
.
Ah, yes. Add ":" for the spacing. Thank you very much!
As always, my pleasure!
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Time Series Events についてさらに検索
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
