Semilog plotting in loop

조회 수: 17 (최근 30일)
Marguerite Lorenzo
Marguerite Lorenzo 2023년 6월 22일
편집: dpb 2023년 6월 29일
Hello,
I want to plot my data set on a semiy log plot according to 4 different legend categories, and I want the points of each series to be connected by a dashed line.
I am able to plot all the points with the looping below, but the lines connecting each serie are for some reason not coming out on the plot.
Any help would be appreciated, thank you!
[NUM_w,TXT_w,RAW_w] = xlsread("wells");
MATLABDate = NUM_w(1,1:9) + 693960 % convert from excel # dates to MATLAB # dates
dates = datetime(MATLABDate,'ConvertFrom','datenum') % convert dates to day-month-year format
values_w = NaN(14,9);
for i = 2:14
for j = 1:9
if NUM_w(i,j) > 0
values_w(i,j) = NUM_w(i,j)
elseif NUM_w(i,j) == 0
values_w(i,j) = 0.0001 % well matrix for ND ratios
end
end
end
m=10
for i = 2:14
% if statements here to plot accordingly to well attribute: type and plugging status
if TXT_w(i+1,11) == "Plugged" % Plugged | filled circle
if TXT_w(i+1, 12) == "Gas" % Plugged, Gas | blue filled circle
semilogy(dates,values_w(i,1:9),'--ob','MarkerFaceColor','b','MarkerSize',m); hold on
else % Plugged, Non Gas | red filled circle
semilogy(dates,values_w(i,1:9),'--or','MarkerFaceColor','r','MarkerSize',m); hold on
end
else % Unplugged | outline circle
if TXT_w(i+1, 12) == "Gas" % Unplugged, Gas | blue outline circle
semilogy(dates,values_w(i,1:9),'--ob','MarkerSize',m); hold on
else % Unplugged, Non Gas | red outline circle
semilogy(dates,values_w(i,1:9),'--or','MarkerSize',m); hold on
end
end
xlim([datetime(41275+693960,'ConvertFrom','datenum'),datetime(44197+693960,'ConvertFrom','datenum')]); % set x axis scale
ylim([10^-5,2*10^0]); % set y axis scale
end
  댓글 수: 2
Dyuman Joshi
Dyuman Joshi 2023년 6월 22일
You are trying to access 11th and 12th column of TXT_w, which only has 2 columns, so you might want to adjust the indices (which are based on the excel data).
Similarly, there are 14 rows of each data, and you are trying to access the 15th row, which is not possible.
Do you want club all the points together for pairs? Such as plot all the points for "Plugged" and "Gas" together on a single line? Or do you want plot for each row individually?
Marguerite Lorenzo
Marguerite Lorenzo 2023년 6월 22일
I uploaded an incorrect data sheet, please forgive the mistake. Attached is a version that should work: indexation is not the problem I am having, but rather that the dashed lines in between my data points are not displaying. I want to plot each row individually (and the data points of each line are connecting, it is a time series), and each row is sorted by color and fill according to the attribute (p/u and gas/nongas).
Switching to plot instead of semilogy is not working for me, and either way I would like the plot to be in log scale.
Thank you in advance!

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

채택된 답변

dpb
dpb 2023년 6월 22일
편집: dpb 2023년 6월 22일
Well, let's try a little different tack, using some other MATLAB features...
opt=detectImportOptions('wells.xlsx');
opt.DataRange='A3';
opt.VariableNamesRange='A2';
opt.VariableTypes(2:10)={'double'};
tW=readtable('wells.xlsx',opt,'ReadVariableNames',1);
Warning: Column headers from the file were modified to make them valid MATLAB identifiers before creating variable names for the table. The original column headers are saved in the VariableDescriptions property.
Set 'VariableNamingRule' to 'preserve' to use the original column headers as table variable names.
tW.Properties.VariableNames(1)={'WellID'};
tW=tW(strlength(tW.WellID)>0,:); % was extraneous stuff at bottom from the max() formula added...
tW=stack(tW,2:10,'NewDataVariableName',{'Response'},'IndexVariableName','Date'); % recast to put date into table
tW.Date=datetime(replace(string(tW.Date),'x',''),'InputFormat','dd_MMM_uuuu','Format','MMMyyyy'); % convert to datetime
%tW.Response(isnan(tW.Response))=0.0001; % remove the NaN
tW.Response(tW.Response==0)=0.0001; % reset zeros to a minimal value
figure, hold on
hL=rowfun(@(x,y)semilogy(x,y,'x--'),tW,'GroupingVariables','WellID','InputVariables',{'Date','Response'});
hAx=gca;
hAx.YScale='log'; % not sure why, but didn't set log scale even using semilogy()
xlim([datetime(2013,1,1) datetime(2021,1,1)])
ylim([5E-5, 0.2])
box on
grid on
There's everything all on one axes; is pretty cluttered as yet without the varying markers/colors...but, there is only one line; the problem is that all your data points are scattered with NaN values between points except for WA-06 does have two adjacent date values as shows up above.
MATLAB plot routines silently ignore NaNs and so there's only a point to be drawn at those non-touch points.
So, let's see about adding those amenities...
Well, I've got to go attend to some other business right now, but that's the reason the lines don't show up; you can either do the same thing for the NaN values as for 0 (although I don't recommend; it makes data where there are none), or only select the non-NaN values for each subset instead of all.
ADDENDUM:
Added the additional fixups to handle the missing values and finish annotation. What's a good variable name for whatever the response data are?
I'll add the corrections/additions below to the original above just to keep the continuity of the conversation --
tW=convertvars(tW,vartype('cellstr'),'categorical'); % use categorical variables where appropriate
figure, hAx=axes; hold on % it is the use of hold that stops semilogy() from setting yscale
hAx.YScale='log'; % so, create the axes handle and set the log axis first
fnColor=@(t)char('b'*(t=='Gas')+'r'*(t~='Gas')); % a lookup table for the color
hL=rowfun(@(x,y,t)semilogy(x(isfinite(y)),y(isfinite(y)),strcat('o:',fnColor(t(1)))),tW,'GroupingVariables','WellID','InputVariables',{'Date','Response','WellType'},'NumOutputs',1,'OutputFormat',"uniform");
isPlugged=rowfun(@(s)all(s=='Plugged'),tW,'GroupingVariables','WellID', ...
'InputVariables','PluggingStatus','OutputFormat','uniform'); % which lines are plugged
set(hL(isPlugged),{'MarkerFaceColor'},num2cell(reshape([hL(isPlugged).Color],3,[]).',2)) % set those markers
xlim([datetime(2013,1,1) datetime(2021,1,1)])
ylim([5E-5, 0.2])
box on
grid on
  댓글 수: 3
dpb
dpb 2023년 6월 28일
편집: dpb 2023년 6월 29일
Try variations on
tfill=[xlim flip(xlim)];
yfill=[5E-5 5E-5 1E-3 1E-3];
hF=fill(tfill,yfill,0.9*[1 1 1],'FaceAlpha'=0.3,'LineStyle'='none');
I didn't check latest release, but as of R2020b that I'm using locally, fill() seems the only one that has been extended to handle the datetime class.
Marguerite Lorenzo
Marguerite Lorenzo 2023년 6월 29일
This works great! Thank you very much

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

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Annotations에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by