ConstantLine always on the top

조회 수: 82 (최근 30일)
Adib Yusof
Adib Yusof 2020년 11월 29일
편집: Adam Danz 2023년 5월 11일
I have been noticing that ConstantLine, which is plotted by xline() or yline() functions, always located on the top of other objects in an axes, no matter whether I plot the ConstantLine before or after other objects (e.g., Line, Scatter)
Even rearranging it by using uistack() like this did nothing:
uistack(ConsLine, 'bottom')
I have checked that all objects are the children of the axes, therefore, I should be able to rearrange it by uistack(), right?
I have also tried setting the HandleVisibility property to 'on' before uistack-ing, but nothing happened:
set(allchild(gca), 'HandleVisibility', 'on');
uistack(ConsLine, 'bottom')
I could not find anything on the documentation or here on MATLAB Answers regarding this behaviour.
Please help. I'm using MATLAB R2020b. Thank you so much.

채택된 답변

Adam Danz
Adam Danz 2020년 11월 29일
편집: Adam Danz 2023년 5월 11일
It's undocumented but here's now to set the ConstantLine to the back of the uistack (Nov 2020). As @Yi-xiao Liu points out, this will not work in Live Scripts.
% Set up example
clf()
plot(magic(5),'LineWidth',5)
xh = xline(3,'LineWidth',8,'Alpha',1);
% Set ConstantLine to 'back'
% Temporarily disable the warning that appears when accessing
% the undocumented properties.
warnState = warning('off','MATLAB:structOnObject');
cleanupObj = onCleanup(@()warning(warnState));
Sxh = struct(xh); % Get undocumented properties (you'll get a warning)
clear('cleanupObj') % Trigger warning reset
Sxh.Edge.Layer = 'back'; % Set ConstantLine uistack
Update: documented workaround
(May 2023) Here's an alternative that doesn't rely on undocumented features which could change at any time. This solution uses plot() along with a LimitsChangedFcn to update the bounds of the line any time the axis limits change.
% Plot data
v = 1:20;
plot(v,v.^2,'-c','LineWidth',6)
ax = gca();
hold on
% Add x-line
x = 10;
xl = plot([x,x],ylim(ax), 'k--', 'LineWidth', 4);
% Add y-line
y = 100;
yl = plot(xlim(ax), [y, y], 'k--', 'LineWidth', 4);
% Send x and y lines to the bottom of the stack
uistack([xl,yl],'bottom')
% Update the x and y line bounds any time the axes limits change
ax.XAxis.LimitsChangedFcn = @(ruler,~)set(xl, 'YData', ylim(ancestor(ruler,'axes')));
ax.YAxis.LimitsChangedFcn = @(ruler,~)set(yl, 'XData', xlim(ancestor(ruler,'axes')));
  댓글 수: 7
Rohit Kumar
Rohit Kumar 2021년 6월 14일
I should have asked the question in a separate thread. It is a different question altogether.
Yi-xiao Liu
Yi-xiao Liu 2022년 3월 29일
I found a interesting behavior that this trick does not work in live scripts (mlx) but in command window (2019b)

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

추가 답변 (1개)

Patrick Otto
Patrick Otto 2021년 12월 17일
In matlab 2019b this workaround doesn't work.
My simple workaround is:
% Set up example
clf()
hold on
plot(magic(5),'LineWidth',5)
cLineOwn(gca, 3, 'x', {'color', [0.5,0.5,0.5]});
cLineOwn(gca, 15, 'y', {'color', [0.5,0.5,0.5]});
hold off
% Helper function
function cLineOwn(h, val, ax, opts)
if ax == 'x'
Lim = ylim;
p = plot(h ,[val,val], Lim, opts{:});
uistack(p, "bottom");
elseif ax == 'y'
Lim = xlim;
p = plot(h, Lim, [val,val], opts{:});
uistack(p, "bottom");
end
end
  댓글 수: 1
Adam Danz
Adam Danz 2021년 12월 17일
If you're refering to the solution in my answer on this page, it does work in R2019b (see below).
Regarding your solution, the difference between xline and using plot() to create a line is that the xline (or yline) creates a ConstantLine object that updates its position when the axis limits change whereas your plot line does not have that behavior.

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

카테고리

Help CenterFile Exchange에서 Introduction to Installation and Licensing에 대해 자세히 알아보기

제품


릴리스

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by