kakearney / plotboxpos-pkg

Return the position of the plotted region of a Matlab axis
MIT License
8 stars 1 forks source link

Conflict with Colorbar #4

Closed dwschmid closed 4 years ago

dwschmid commented 6 years ago

Hi, excellent function that helps solving a problem that Mathworks should have a long time ago!

My use case is that I have a main axes to which I attach some secondary axes. They are supposed to fit perfectly even when the figure is resized and I would like to use plotboxpos to give me exact position to which I have to move the secondary axes when the figure is resized. This does not work if I have a colorbar attached to the main axes. I provide an example below. Just run it and then extend the figure vertically. The plot disappears very quickly. This although I only use plotboxpos to query the main axes position.

Cheers,

Dani

function test_plotboxpos() h_f = figure; h_uc = uicontainer(h_f); h_a = axes(h_uc); plot(h_a, rand(1,10)) axis equal; colorbar h_uc.SizeChangedFcn = @size_changed;

function size_changed(~, ~)
    pos = plotboxpos(h_a);
end

end

kakearney commented 6 years ago

I'm not sure the example you posted is complete... I only see one axis created there, and the size_changed function doesn't seem to do anything after querying plotboxpos. (When I run it and try to resize the figure, I just get an error saying the h_a is never defined in the subfunction).

However, the basic concept should work fine once you've adjusted a few inputs and added in the appropriate code to resize the axes. I modified your example below to add a second axis that is always 20% the size of the first axis, pinned to the lower right corner of the first axis. Is this the sort of behavior you're looking for?

h_f = figure;
h_uc = uicontainer(h_f);
h_a(1) = axes(h_uc);
plot(h_a(1), rand(1,10));
axis equal;
colorbar;

h_a(2) = axes(h_uc, 'color', 'yellow', 'box', 'on');
syncsizes([],[],h_a);

h_uc.SizeChangedFcn = @(a,b) syncsizes(a,b,h_a);

function syncsizes(~,~,ha)
    pos = plotboxpos(ha(1));
    set(ha(2), 'position', [pos(1)+pos(3)-pos(3)*0.2 pos(2) pos(3)*0.2 pos(4)*0.2]);
end
dwschmid commented 6 years ago

Hi, thanks for the feedback!

My test function works for me if function header and all the end statements are included. I attach it (as a .txt file since github does not allow .m attachments). Both your and my tests show the same problem on my Matlab 2017a (Windows). When I resize the figure window the plot disappears. I attach an animated gif that shows this behavior.

Cheers,

Dani

test_plotboxpos.txt test_plotboxpos

kakearney commented 6 years ago

Well, that's odd... and I can't reproduce that behavior on my computer (Mac, R2018a).

Do you see the same behavior if you comment out the call to plotboxpos in the subfunction? The plotboxpos function shouldn't affect the existing axis at all; it's purpose is just to calculate the position, and as written you haven't actually done anything with that output yet.

Do you see any errors or warning messages in the command window when you perform the resize?

dwschmid commented 6 years ago

No errors or warnings in the command window. BUT... when I run this in Matlab 2018a (Windows) then the problem does not exist. Time to upgrade.... Thanks for your help.

dwschmid commented 6 years ago

Little add-on. While I was profiling the performance of plotboxpos I noticed that most of the time is spent in the following lines

set(h, 'units', 'pixels');
axisPos = get(h, 'Position');
set(h, 'Units', currunit);

These can be replaced with

axisPos = getpixelposition(h);

This is not only faster but also the problem with 2017a does not appear.