Is it possible to use the 'patch' function to display missing intervals in only one of the graphs created with the given code?
2 views (last 30 days)
Show older comments
I have uploaded the results of my work so far. Please check it out if you're interested.
From the tide level data of the Incheon Tide Observatory, tide level time series graphs are extracted on a monthly basis. It's almost done, but there's one thing that's not working out.
If you look at the graph in Figure 02__ of the compressed file, there will be a broken part in the 3rd graph, and this part is a 'missing section' where tide level data has not been measured. In this part, we wanted to use the patch function to display the missing interval as a translucent blue square, and display a legend for the missing interval in the 'northoutside' part. Like '21_03_Figure_Example.png'. The important thing is that what I just said applies only to the third graph.
Maybe I'm just too tired to think of a good solution... I'm waiting for a little help from you all.
Here's the code I've written so far:
clear; clc; close all;
% addpath(genpath('../../matlab_tool_box'));
inp.dir = fullfile(pwd,'01__Data');
addpath(genpath(inp.dir));
fig.dir = fullfile(pwd,'02__Figure');
% Create a file name and assign it to the fileID array.
fileID = cell(1, 12); % Create a cell array with 12 elements
for month = 1:12
% Create file name
filename = sprintf('Incheon_2021 %02d_hourly_Tide_level.txt', month);
% Assign to fileID by calling fopen with file path
fileID{month} = fopen(fullfile(inp.dir, filename), 'r');
end
formatSpec = '%s%s%f';
for i = 1:12
data{i} = textscan(fileID{i},formatSpec,'HeaderLines',4,'CommentStyle',{'*결측 구간*','위 결측 구간은 임의로 보간처리한 자료이므로 참고용으로만 사용하시기 바랍니다.'},'Delimiter',' ');
a{i} = data{i}{1}.';
b{i} = data{i}{2}.';
blank = {' '};
c{i} = strcat(a{i},blank,b{i});
DateStrings{i} = c{i}.';
date{i} = datetime(DateStrings{i},'InputFormat','yyyy/MM/dd HH:mm');
date{i}.Format = 'dd HH:mm';
T{i} = data{i}{3};
% Calculate the overall average water depth (cm). At this time, NaN values are excluded.
Tm = mean(T{i},'all','omitnan');
% Set the average water depth (cm) to the standard water depth of '0m', subtract the average water depth from the original water depth according to that standard, and then divide by 100 to change the unit of cm to m.
t{i} = (T{i}-Tm)/100;
d{i} = date{i}.';
end
dnMar = datenum(d{3});
d3New = NaN(1, 747); % Initialize the d3New array to the dictionary.
for kk = 1:716
if kk < 564 % Prevents the value of d3New from appearing as NaN in the range of 533 to 563.
d3New(kk) = dnMar(kk);
elseif (kk > 532) && (kk < 564) % Perform each comparison separately.
d3New(kk + 31) = NaN;
elseif kk >= 564
d3New(kk + 31) = dnMar(kk); % If kk is greater than 563, the index plus 31 is used.
else
d3New(kk) = dnMar(kk); % Otherwise, an existing index is used.
end
end
d3dt = datetime(d3New, 'ConvertFrom', 'datenum');
d3dt.Format = 'dd HH:mm';
tMar = t{3}.';
t3New = NaN(1, 747);
for kk = 1:716
if kk < 564 % Prevents the value of t3New from appearing as NaN in the range of 533 to 563.
t3New(kk) = tMar(kk);
elseif (kk > 532) && (kk < 564) % Perform each comparison separately.
t3New(kk + 31) = NaN;
elseif kk >= 564
t3New(kk + 31) = tMar(kk); % If kk is greater than 563, the index plus 31 is used.
else
t3New(kk) = tMar(kk); % Otherwise, an existing index is used.
end
end
t3dt = t3New.';
for i = 1:12
if i == 3
d{i} = d3dt;
t{i} = t3dt;
end
figure
graphColor = 'k';
plot(d{i},t{i}, graphColor);
xlim tight
xtickformat('MM/dd');
ylim([-6 6]);
yticks(-6:2:6)
yticklabels({'-6','-4','-2','0','2','4','6'})
ylabel('Tide level (m)')
grid on
midColor = '-r';
yline(0,midColor)
set( gcf, 'Position', [10 10 1300 300] ) ;
hold on
% Remove '2021년' label from x-axis
ax = gca;
ax.XAxis.TickLabels = cellstr(datestr(ax.XAxis.TickValues, 'MM/dd'));
fname = ['Tide_2021_', num2str(i), '.png'];
print(['02__Figure\',fname],'-dpng');
end
close all
1 Comment
Accepted Answer
Voss
on 5 Mar 2024
Edited: Voss
on 5 Mar 2024
EDIT to include OP's data, which I missed initially.
EDIT to include a patch face for missing data at the start or end of a file.
Here is an approach you can use:
% clear; clc; close all;
unzip('Incheon_Tides_21.zip')
files = dir(fullfile(pwd,'Incheon_Tides_21','01__Data','*.txt'));
filename = sort(fullfile({files.folder},{files.name}));
N = numel(filename);
C = cell(1,N);
for ii = 1:N
T = readtable(filename{ii}, ...
'HeaderLines',4, ...
'CommentStyle',{'*결측 구간*','위 결측 구간은 임의로 보간처리한 자료이므로 참고용으로만 사용하시기 바랍니다.'}, ...
'Delimiter',' ');
T.Properties.VariableNames = {'Day','Time','Depth'};
T.Time = datetime(string(T.Day)+" "+string(T.Time),'InputFormat','yyyy/MM/dd HH:mm');
T = removevars(T,'Day');
% Calculate the overall average water depth (cm). At this time, NaN values are excluded.
Tm = mean(T.Depth,'all','omitnan');
% Set the average water depth (cm) to the standard water depth of '0m', subtract the average water depth from the original water depth according to that standard, and then divide by 100 to change the unit of cm to m.
T.DiffFromAvg = (T.Depth-Tm)/100;
% convert to timetable and retime to introduce NaNs
% where data is missing
T = retime(table2timetable(T),'hourly');
C{ii} = T;
end
% plot
for ii = 1:N
figure('Position', [10 10 1300 300]);
plot(C{ii}.Time,C{ii}.DiffFromAvg,'k')
xlim(C{ii}.Time([1 end]))
xtickformat('MM/dd');
ylim([-6 6]);
yticks(-6:2:6)
ylabel('Tide level (m)')
grid on
midColor = '-r';
yline(0,midColor)
% Remove year label from x-axis
xsecondarylabel('');
% find bad data (NaN/Inf)
bad_idx = ~isfinite(C{ii}.DiffFromAvg).';
% find start and stop index of bad data regions
s_idx = strfind([false bad_idx],[false true]);
e_idx = strfind([bad_idx false],[true false]);
% adjust any bad data regions at the start or end of the data:
s_idx(s_idx == 1) = 2;
siz = size(C{ii},1);
e_idx(e_idx == siz) = siz-1;
% adjust the axes height to make room for a legend
ax = gca();
ax.Position(4) = ax.Position(4)-0.05;
% if there is any bad data region
if ~isempty(s_idx)
% make a patch for it (the patch has one face per bad data region)
x = C{ii}.Time([s_idx-1; e_idx+1; e_idx+1; s_idx-1; s_idx-1]);
y = repmat(6*[-1; -1; 1; 1; -1],1,numel(s_idx));
p = patch(x,y,'b','FaceAlpha',0.25);
% make a legend for the patch
lgd = legend(p,sprintf('Missing\nInterval'));
lgd.Position(2) = ax.Position(2)+ax.Position(4);
end
fname = sprintf('Tide_2021_%d.png',ii);
print(fullfile(pwd,'Incheon_Tides_21','02__Figure',fname),'-dpng');
end
% close all
8 Comments
More Answers (0)
See Also
Categories
Find more on Graphics Object Properties 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!