Resizing Callbacks with invisible figures

I'm running into an issue where I've attached the following to a figure:
figHandle.SizeChangedFcn = @(src,event) set(src.Children(3),'Position',get(src.Children(end),'Position'));
The goal of this is to move a specific element (in this case, a legend), in line with a second element (another legend for the primary axes). If relevant, the idea is to move the legend of an invisible axes in line with the legend already associated with the visible one. I have two questions:
  1. The invisible axes don't scale like the other axes. The first is one with many lines plotted on it, while the second is a bar plot, drawn with the intention of creating a color code for an img plotted on the same space. the reason for this legend related callback is because for whatever reason, I can't make the axes scale identically. Is there some content I can load into the invisible axes that will solve this?
  2. In the event I can't get the two axes to scale identically, I need to make this callback work slighty differently. At the moment, making the function invisible leads to the callback being disabled for some reason - is there another callback which I may be able to take advantage of, which is triggered in the event of a resizing (or which I can enable to be so) which is not influenced by figure visibility.
Any help would be appreciated

11 commentaires

Jan
Jan le 26 Juin 2019
Relying on a children with a specific index is not stable. Prefer to use the real handle instead of src.Children(3).
Please explain, what you observe. "The invisible axes don't scale like the other axes." Mentioning, what you not observe is less useful.
"while the second is a bar plot, drawn with the intention of creating a color code for an img plotted on the same space." - Too many details are confusing. A minimal working example as code would be more clear here.
"In the event I can't get the two axes to scale identically, I need to make this callback work slighty differently." - In which event and what does "scale" mean exactly? Which Units do the axes have?
What ist "making the function invisible"? "leads to the callback being disabled for some reason" - which callback and why do you assume, that it is "disabled"?
Hello Jan! I've read many of your answers, thanks a lot for the help.
So the issue is I need this figure to rescale, even if the files which created it are unavailable - this is why I'm using this compact function handle. If I give the legend handles names, will those variables automatically show up in the environment when I open the figure? This is the reason for pointing to the child number.
I wrote a callback (attached above) to transfer the position (position and size) of the visible axes to the invisible axes, so that the legend attached to the invisible axes moves appropriately, doesn't end up sitting on the visible axes.
Preperation: I attached this callback:
figHandle.SizeChangedFcn = @(src,event) set(src.Children(3),'Position',get(src.Children(end),'Position'));
to the figure and save it as a '.fig',
Observations:
When I run the following code
figHand(ii) = openfig(figsToPlot{ii});
figHand(ii).Units = 'inches';
figHand(ii).Position(3:4) = pageLayout{ii}.*pageSize;
I see the behavior shown in 'VisibleResize' and 'VisibleResize_Numbers', which is what I want. The invisible axes are exactly the same size as the visible ones, allowing the two legends to align. Given that I want to do this in bulk, I don't want to waste processing power drawing the figures If I can avoid it, so...
If I use the following:
figHand(ii) = openfig(figsToPlot{ii}, 'invisible');
figHand(ii).Units = 'inches';
figHand(ii).Position(3:4) = pageLayout{ii}.*pageSize;
I get the attached figure "InvisibleResize" and "InvisibleResize_Numbers". The only difference is the figure is opened as invisible. The code to recreate these figures would be hard to share due to dependencies, but you can basically ignore everything which isn't the visible axes, the invisible axes, and their two respective legends. When the figure is visible, the callback appears to work as intended, when invisible, the callback no longer performs its function. I am infering that the callback isn't called, and figured it may be related to this - https://undocumentedmatlab.com/blog/enabling-user-callbacks-during-zoom-pan
Please let me know if I can clarify anything.
Walter Roberson
Walter Roberson le 26 Juin 2019
There are some internal values including resize related, which are not recalculated until the relevant object is made visible. This is for efficiency, so that you can change a number of properties in sequence, including temporarily having inconsistent properties, without triggering a recalculation after every change.
aboharbf
aboharbf le 1 Juil 2019
Is there a way around this? I placed 'drawnow' inside the loop and after the loop to no effect. Any addition to 'drawnow' seems to stop callbacks from being called.
Walter Roberson
Walter Roberson le 1 Juil 2019
Is there a way around this?
There is no documented away around it.
Everything about how these things are calculated is hidden inside built-ins or inside .p files, so it is rather difficult to figure out what is happening internally.
aboharbf
aboharbf le 1 Juil 2019
That is mighty unfortunate. I had briefly messed around with solutions found on undocumented MATLAB (https://undocumentedmatlab.com/blog/enabling-user-callbacks-during-zoom-pan), but it seems like it would take more tinkering and be an ultimately far less stable solution than opening them visible, changing the size, than setting them to invisible. Unfortunate there is no clear work around. Thanks a lot for the help, Walter.
Jan
Jan le 2 Juil 2019
Instead of an invisible figure, I use a figure outside the visible area of the screens sometimes. This enables some rendering, but e.g. screenshots of this figure do not work with standard methods.
Yair Altman
Yair Altman le 5 Juil 2019
In my experience, callbacks and rendering often work better and in a more consistent manner when the figure is placed off-screen while being visible (for example, hFig.Position=[-1000,-1000,100,100]), rather than being non-visible. When the rendering changes are done, you can bring the figure back to its visible position in the main monitor.
aboharbf
aboharbf le 7 Juil 2019
Hey Jan, Yair,
That sounds like a great strategy, but sadly since I'm using openfig, it doesn't seem like it accepts arguments pairs, which means I'd have to make it visible on screen, then move and resize vs. make it visible, resize, then invisible. After doing tic toc on both strategies, it seems like moving it alongside the resize is much quicker than the resize/invisible option, so I may stick with this. Thanks for the suggestion.
Jan
Jan le 8 Juil 2019
"it doesn't seem like it accepts arguments pairs" - Please post the code and show us, what let you assume, that arguments are not accepted. openfig() does not do any magic and you can inspect the code and modify a copy to satisfy your needs.
I do not understand the difference between: "make it visible on screen, then move and resize" and "make it visible, resize, then invisible". It is also not clear to me, why tic/toc matters here: If a code does not do, what you need, why does its speed play any rule? Did you include a drawnow insice the tic/toc?
Code below:
for ii = 1:length(figsToPlot)
figHand(ii) = openfig(figsToPlot{ii});
figHand(ii).Units = 'inches';
figHand(ii).Position = [24 24 pageLayout{ii}.*pageSize];
end
I'd rather avoid modifying openfig, insofar as If I download a new version of MATLAB on another machine, I'd rather this not break. Ultimately, the reason I wanted to open the figures invisibly was to save time when I'm running this on many figures.
What I meant by the sequence of explanations was the code above is faster than the code below.
for ii = 1:length(figsToPlot)
figHand(ii) = openfig(figsToPlot{ii});
figHand(ii).Units = 'inches';
figHand(ii).Position(3:4) = [pageLayout{ii}.*pageSize];
figHand(ii).Visible = 'off'
end
both fragments of code achieve something very similar, but the former is faster. I don't mind the figures being visible as long as it doesn't slow down anything, which seems to be the case when you place them off the screen.

Connectez-vous pour commenter.

Réponses (0)

Catégories

En savoir plus sur Graphics Performance dans Centre d'aide et File Exchange

Question posée :

le 26 Juin 2019

Commenté :

le 10 Juil 2019

Community Treasure Hunt

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

Start Hunting!

Translated by