Plotted patch changes size
3 ビュー (過去 30 日間)
古いコメントを表示
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!
0 件のコメント
採用された回答
Adam Danz
2024 年 4 月 2 日
編集済み: Adam Danz
2024 年 4 月 2 日
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
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
0 件のコメント
その他の回答 (1 件)
Voss
2024 年 4 月 2 日
"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
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Annotations についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!