How can I prevent a function from creating a separate window when acting on a UIfigure handle?

2 vues (au cours des 30 derniers jours)
I have a script that reads in some data and a UI figure with uibuttons that change how it is plotted. I've stripped the non-essential parts that don't relate to the issue out of the code. This SHOULD create a UI window that has 2 UI slider elements and a push putton that reads the current value of the sliders and uses that to plot data in the same figure to an axes inside the window on the right created by UIaxes. It will plot the data as intended, BUT it also creates a new figure window with a blank axes in it when the "update" button is pressed. How do i get it to stop doing this? If the plot() function is called outside of a local function it will plot to the correct axes, but I need it to be inside the update function so that it can replot when UI elements are changed.
% some mock data to make the simplified code run
raw_spectra.ampl = [1 2 3];
raw_spectra.field = [1 2 3];
% make the uifigure and axes
fig = uifigure("Position", [50, 300, 1200, 900]);
Error using matlab.internal.lang.capability.Capability.require
This functionality is not available on remote platforms.

Error in matlab.ui.internal.uifigureImpl (line 32)
Capability.require(Capability.WebWindow);

Error in uifigure (line 26)
window = matlab.ui.internal.uifigureImpl(varargin{:});
ax = uiaxes(fig,'Position',[350, 40, 820, 820]);
% make an element in the uifigure that adjusts a parameter that affects how
% plotting is done.
fig.UserData.horizStagger = uislider(fig,"Limits",[0 7],"Position",[30, 250, 200 3],...
'Value', 0);
fig.UserData.vertStagger = uislider(fig,"Limits",[0 3],"Position",[30, 170, 200 3],...
'Value', 0.5);
% a ui button element that when pushed, plots or replots the data with the
% parameters selected with the other UI elements
update_btn = uibutton(fig, 'push', 'Position', [130, 450, 125, 22], ...
'Text', 'Update', 'ButtonPushedFcn', ...
@(update_btn, event) update(update_btn, fig, raw_spectra));
function update ( ~, fig, raw_spectra)
staggeredSpectra = stagger(raw_spectra, fig.UserData.horizStagger.Value, ...
fig.UserData.vertStagger.Value);
for i =1:numel(staggeredSpectra)
plot(fig.Children(end), staggeredSpectra(i).field, ...
staggeredSpectra(i).ampl);
hold on;
end
hold off;
end
function spectra = stagger (input_spectra, horizStagger, vertStagger)
for s = 1:numel(input_spectra)
%adjust center so that that maxima line up with staggering added for
%horizontal offset
spectra(s).field = input_spectra(s).field + horizStagger;
%scale relative to the largest spectrum height and apply vertical
%offset
spectra(s).ampl = input_spectra(s).ampl * vertStagger * (s-1);
end
end
  4 commentaires
Voss
Voss le 4 Août 2023
@Andrew Morris: Have you tried the modification given in my answer? I ran it, and it worked (version R2022a).
Andrew Morris
Andrew Morris le 4 Août 2023
yes! thank you. it requires making the plot first in this way outside of a function and then using the update callback to swap out the ax.Children.XData and ax.Children.YData vectors in place without using the plot function.

Connectez-vous pour commenter.

Réponse acceptée

Voss
Voss le 4 Août 2023
It's because of the
hold on
without specifying an axes.
Specify the axes explicitly, e.g.:
hold(fig.Children(end),'on');
Similarly for the hold off a couple lines later.

Plus de réponses (0)

Catégories

En savoir plus sur Develop uifigure-Based Apps dans Help Center et File Exchange

Tags

Produits


Version

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by