Shading below y=c in a semilogy plot

6 views (last 30 days)
Marguerite Lorenzo
Marguerite Lorenzo on 27 Jun 2023
Commented: Star Strider on 27 Jun 2023
I am working with this code for two adjacent semilog subplots (y axis is in log-scale, x axis is a time series). I would like the region of the plots below y = 10^-3 to be shaded in gray, but I am having trouble doing this with functions such as patch, fill, and area. I feel like it should not be complicated, but I think I am blocked by the fact that they are semilogy plots, and that the x axis has specific time formatting.
Thank you in advance for the support. I am using MATLAB 2019a
%% Wells
optW=detectImportOptions('wells');
optW.Sheet='Sheet7';
optW.DataRange='A3';
optW.VariableNamesRange='A2';
optW.VariableTypes(2:10)={'double'};
tW=readtable('20211110_longtermanalysis_wells_PA_ML',optW,'ReadVariableNames',1);
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(tW.Response==0)=3*0.0001; % reset zeros to a minimal value
tW=convertvars(tW,vartype('cellstr'),'categorical'); % use categorical variables where appropriate
hAxw=subplot(1, 2, 1) % it is the use of hold that stops semilogy() from setting yscale
hAxw.YScale='log'; % so, create the axes handle and set the log axis first
fnColor_w=@(t)char('b'*(t=='Gas')+'r'*(t~='Gas')); % a lookup table for the color
hLw=rowfun(@(x,y,t)semilogy(x(isfinite(y)),y(isfinite(y)),strcat('o--',fnColor_w(t(1)))),tW,'GroupingVariables','WellID','InputVariables',{'Date','Response','WellType'},'NumOutputs',1,'OutputFormat',"uniform");
isPlugged_W=rowfun(@(s)all(s=='Plugged'),tW,'GroupingVariables','WellID', ...
'InputVariables','PluggingStatus','OutputFormat','uniform'); % which lines are plugged
set(hLw(isPlugged_W),{'MarkerFaceColor'},num2cell(reshape([hLw(isPlugged_W).Color],3,[]).',2)) % set those markers
xlim([datetime(2013,1,1) datetime(2021,1,1)]);
ylim([1E-4, 1]);
box on;
%% Controls
optC=detectImportOptions('wells');
optC.Sheet='Sheet8';
optC.DataRange='A3';
optC.VariableNamesRange='A2';
optC.VariableTypes(2:10)={'double'};
tC=readtable('20211110_longtermanalysis_wells_PA_ML',optC,'ReadVariableNames',1);
tC.Properties.VariableNames(1)={'ControlID'};
t=tC(strlength(tC.ControlID)>0,:); % was extraneous stuff at bottom from the max() formula added...
tC=stack(tC,2:10,'NewDataVariableName',{'Response'},'IndexVariableName','Date'); % recast to put date into table
tC.Date=datetime(replace(string(tC.Date),'x',''),'InputFormat','dd_MMM_uuuu','Format','MMMyyyy'); % convert to datetime
tC.Response(tC.Response==0)=3*0.0001; % reset zeros to a minimal value
tC=convertvars(tC,vartype('cellstr'),'categorical'); % use categorical variables where appropriate
hAxc=subplot(1, 2, 2); hold on % it is the use of hold that stops semilogy() from setting yscale
hAxc.YScale='log'; % so, create the axes handle and set the log axis first
fnColor_c=@(t)char('b'*(t=='Gas')+'r'*(t~='Gas')); % a lookup table for the color
hLc=rowfun(@(x,y,t)semilogy(x(isfinite(y)),y(isfinite(y)),strcat('o--',fnColor_c(t(1)))),tC,'GroupingVariables','ControlID','InputVariables',{'Date','Response','WellType'},'NumOutputs',1,'OutputFormat',"uniform");
isPlugged_C=rowfun(@(s)all(s=='Plugged'),tC,'GroupingVariables','ControlID', ...
'InputVariables','PluggingStatus','OutputFormat','uniform'); % which lines are plugged
set(hLc(isPlugged_C),{'MarkerFaceColor'},num2cell(reshape([hLc(isPlugged_C).Color],3,[]).',2)) % set those markers
xlim([datetime(2013,1,1) datetime(2021,1,1)]);
ylim([1E-4, 1]);
set(0, 'defaultLineMarkerSize', 11) % increase marker size
% xes = [735235 738157 738157 735235]; yes = [5E-4 5E-4 0.2 0.2];
% patch(xes,yes,'red')
box on
  1 Comment
Star Strider
Star Strider on 27 Jun 2023
In general, all of those functions work on logarithmically-scaled plots and datetime scaled plots, although the most robust (over several releases) in my experience is fill. The correct approach is to first plot them using linear scaling, then do the logarithmic transformation (this of course requires that the coordinates exist under logarithmic transformation, so they must all be finite and greater than zero, since the patch objects will not work with non-finite values).
That aside, I cannot make any of them work with your code, at least in part because it is so difficult to figure out what you’re doing.
Example —
x = datetime(2023,01,01) + calmonths(0:6).'; % Assume Column Vectors
y = 2 + sin((0:numel(x)-1)*2*pi*1.2/numel(x)).';
figure
patch([x; flip(x)], [zeros(size(y))+1; flip(y)], 'b')
Ax = gca;
Ax.YScale = 'log';
.

Sign in to comment.

Answers (0)

Community Treasure Hunt

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

Start Hunting!