Clear Filters
Clear Filters

Plotted patch changes size

2 views (last 30 days)
Jan
Jan on 2 Apr 2024
Edited: Adam Danz on 2 Apr 2024
Dear all,
I am using a patch function to highlight some areas of the plotted figures. I plot more that 30 figures in a loop using this code:
% Identify parameters
firstResult = dTexport.results{find(lvRows, 1)}.oo_.posterior_mean.parameters;
paramNames = fieldnames(firstResult);
% Initialize structure to hold the difference between bounds
boundsDiff = struct();
% Extract parameter data and calculate bounds difference for filtered rows
for iParam = 1:length(paramNames)
paramName = paramNames{iParam};
boundsDiff.(paramName) = zeros(numQuarters, 1);
filteredQuarter = 1;
for iQuarter = 1:length(dTexport.results)
if lvRows(iQuarter)
lowerBound = dTexport.results{iQuarter,1}.oo_.posterior_hpdinf.parameters.(paramName);
upperBound = dTexport.results{iQuarter,1}.oo_.posterior_hpdsup.parameters.(paramName);
boundsDiff.(paramName)(filteredQuarter) = upperBound - lowerBound;
filteredQuarter = filteredQuarter + 1;
end
end
end
% Plot each parameter difference with recessions highlighted
for iParam = 1:length(paramNames)
figure;
paramName = paramNames{iParam};
plot(xAxis, boundsDiff.(paramName), 'LineWidth', 2);
hold on;
xlabel('Time');
ylabel(['Difference of ', paramName]);
title(['HPD Range of ', paramName]);
ax = gca;
ax.XTick = 1:8:numQuarters;
ax.XTickLabel = quarterDates(1:8:end);
ax.XTickLabelRotation = 45;
grid on;
% Highlight recession periods based on the specified indicator
recessionIndicator = dTexport.(recessionIndicatorName)(lvRows);
yLimits = ylim;
for i = 1:length(recessionIndicator)
if recessionIndicator(i) == 1
patch([i-0.5, i+0.5, i+0.5, i-0.5], [yLimits(1), yLimits(1), yLimits(2), yLimits(2)], [0.75 0.75 0.75], 'EdgeColor', 'none', 'FaceAlpha', 0.4);
end
end
hold off;
end
This runs without any error and most of the plotted figures look as expected. In some of them, however, patches don't reach the top of the plot or the bottom of it:
Which is strange, because I set patches according to yLimits. And again, most of the figures generated this way have patches all the way from the bottom to the top of the plot.
Any idea what could cause this?
In insight would be greatly appreaciated, thank you in advance!

Accepted Answer

Adam Danz
Adam Danz on 2 Apr 2024
Edited: Adam Danz on 2 Apr 2024
Cause of the problem
Indeed you are setting the patch location based on the ylimits but you are not setting the ylimits. After the patches are created, the ylimits change.
Solution 1 - freeze the y limits
First set the ylim so that it doesn't change, then create the patches.
ylim('manual') % Freeze the y limits
yLimits = ylim;
for i = 1:length(recessionIndicator)
...
end
Solution 2 - use xregion (R2023a or later)
This solution is even more robust because the patches will extend to the axes limits no matter what the limits are!
yLimits = ylim;
for i = 1:length(recessionIndicator)
if recessionIndicator(i) == 1
xregion(i-0.5, i+0.5,'FaceColor',[0.75 0.75 0.75],'FaceAlpha', 0.4);
end
end

More Answers (1)

Voss
Voss on 2 Apr 2024
"some patches don't reach the top of the plot or the bottom of it ... I set patches according to yLimits ... Any idea what could cause this?"
You create the patches based on the y-limits, but then later the y-limits change. In fact, the very act of creating the patches can cause the y-limits to change. Looking at your code, I'd say that's probably what's happening because there's nothing else happening after the patches are created.
To fix the problem, you can set the YLimMode to 'manual', which prevents auto-updating YLim. (Setting YLim has the side effect of setting YLimMode to 'manual', so that would also work).
For example:
for iParam = 1:length(paramNames)
% ...
% ... plot stuff ...
% ... set up xticks ...
% ...
% make sure ylim gets auto-updated once after plotting
drawnow()
% set ylimmode to manual to prevent further changes to ylim
ax.YLimMode = 'manual';
% make the patches
yLimits = ylim;
for i = 1:length(recessionIndicator)
if recessionIndicator(i) == 1
patch([i-0.5, i+0.5, i+0.5, i-0.5], yLimits([1, 1, 2, 2]), [0.75 0.75 0.75], 'EdgeColor', 'none', 'FaceAlpha', 0.4);
end
end
hold off;
end

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!