How to Remove Extra Subplot When Custom Plotting with 'particleswarm'?

1 visualizzazione (ultimi 30 giorni)
Hello MATLAB Community,
I’m working on implementing a custom plot function for the particleswarm function in the Global Optimization Toolbox. However, I’m encountering an issue where an extra empty subplot is being generated along with the intended plots. I would like to know how to remove this extra subplot.
Here is my full code:
fun = @(x) 3*(1-x(1)).^2.*exp(-(x(1).^2)-(x(2)+1).^2)...
- 10*(x(1)/5 - x(1).^3 - x(2).^5).*exp(-x(1).^2-x(2).^2)...
- 1/3*exp(-(x(1)+1).^2 - x(2).^2);
xbounds = [-3, 3, -3, 3]; % [xmin xmax ymin ymax]
fconvert = @(x1, x2) fun([x1, x2]); % for fsurf, fun should be defined as fun = @(x1,x2,...,xn) but for PSO, fun = @(x)
myfig = fsurf(fconvert, xbounds,'ShowContours','on', 'FaceAlpha', 0.7);
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
xlabel('x1');
ylabel('x2');
zlabel('f(x1, x2)');
box on
plotFcnWithHandle = @(optimValues, state) myplot(optimValues, state, myfig);
rng default % For reproducibility
nvars = 2;
lb = [xbounds(1), xbounds(3)];
ub = [xbounds(2), xbounds(4)];
options = optimoptions('particleswarm', ...
'SwarmSize', 50,...
'Display','iter',...
'DisplayInterval', 1,...
'FunctionTolerance', 0.01,...
'MaxIterations', 500,...
'MaxStallIterations', 20,...
'PlotFcn', {'pswplotbestf',plotFcnWithHandle});
[x,fval] = particleswarm(fun,nvars,lb,ub,options);
Best Mean Stall Iteration f-count f(x) f(x) Iterations 0 50 -3.125 0.2354 0 1 100 -4.816 -0.01958 0 2 150 -4.816 -0.1168 1 3 200 -5.126 0.3103 0 4 250 -5.126 -0.09306 1 5 300 -5.126 0.1349 2 6 350 -5.126 -0.1219 3 7 400 -5.13 -0.4775 0 8 450 -6.214 -0.3121 0 9 500 -6.214 -0.04419 1 10 550 -6.231 -0.3444 0 11 600 -6.231 -0.07217 1 12 650 -6.231 0.07298 2 13 700 -6.231 -0.05866 3 14 750 -6.522 -0.3749 0 15 800 -6.522 -0.1125 1 16 850 -6.522 -0.2032 2 17 900 -6.522 0.1049 3 18 950 -6.522 -0.5952 4 19 1000 -6.522 -1.623 5 20 1050 -6.53 -3.121 0 21 1100 -6.544 -4.368 0 22 1150 -6.549 -5.2 0 23 1200 -6.551 -5.562 0 24 1250 -6.551 -5.864 0 25 1300 -6.551 -6.009 1 26 1350 -6.551 -6.302 0 27 1400 -6.551 -6.358 1 28 1450 -6.551 -6.468 0 29 1500 -6.551 -6.526 0 30 1550 -6.551 -6.536 0 Best Mean Stall Iteration f-count f(x) f(x) Iterations 31 1600 -6.551 -6.538 1 32 1650 -6.551 -6.55 0 33 1700 -6.551 -6.551 0 Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
function stop = myplot(optimValues, state, myfig)
stop = false;
ax = get(myfig,'Parent');
positions = optimValues.swarm;
hold(ax, 'on');
delete(findall(ax, 'Tag', 'particles'));
scatter3(ax, positions(:,1), positions(:,2), optimValues.swarmfvals, ...
'r', 'filled', 'MarkerEdgeColor','k', 'Tag', 'particles');
% Update the figure
drawnow;
pause(1); % Pause for 1 second
end
In the code above, an extra empty subplot is generated in addition to the intended plot in the figure titled as "particleswarm". I would like to know how to prevent or remove this extra subplot. Thank you for your help!

Risposte (1)

Walter Roberson
Walter Roberson il 23 Ago 2024
'PlotFcn', {'pswplotbestf',plotFcnWithHandle})
Plotting is generating one subplot for each plot function specified in the 'PlotFcn' option. You have specified two plot functions, so it generates two subplots.
To get around this, you will need to create a single new plot function that combines the effect of pswplotbestf and plotFcnWithHandle .
plotFcnWithHandle = @(optimValues, state) dual_plots(optimValues, state, myfig);
%...
'PlotFcn', plotFcnWithHandle )
%...
function dual_plots(optimValues, state, myfig)
pswplotbestf(optimValues, state);
myplot(optimValues, state, myfig)
end
  2 Commenti
Farshina Nazrul Shimim
Farshina Nazrul Shimim il 26 Ago 2024
Hi! Thanks so much for your comment. I tried editing the code as per your suggestion. This is what the overall code looks like right now
clear all
close all
clc
%% function definition
fun = @(x) 3*(1-x(1)).^2.*exp(-(x(1).^2)-(x(2)+1).^2)...
- 10*(x(1)/5 - x(1).^3 - x(2).^5).*exp(-x(1).^2-x(2).^2)...
- 1/3*exp(-(x(1)+1).^2 - x(2).^2);
xbounds = [-3, 3, -3, 3]; % [x1min x1max x2min x2max]
%% function visualization
fconvert = @(x1, x2) fun([x1, x2]); % for fsurf, fun should be defined as fun = @(x1,x2,...,xn) .... but for PSO, fun = @(x)
myfig = fsurf(fconvert, xbounds,'ShowContours','on', 'FaceAlpha', 0.7);
xlabel('x1');
ylabel('x2');
zlabel('f(x1, x2)');
box on
%% plot preprocessing for PSO
% Create an anonymous function to pass the handle
plotFcnWithHandle = @(optimValues, state) dual_plots(optimValues, state, myfig);
%% PSO parameters definition
rng default % For reproducibility
nvars = 2;
lb = [xbounds(1), xbounds(3)];
ub = [xbounds(2), xbounds(4)];
options = optimoptions('particleswarm', ...
'SwarmSize', 50,...
'Display','iter',...
'DisplayInterval', 1,...
'FunctionTolerance', 0.01,...
'MaxIterations', 500,...
'MaxStallIterations', 20,...
'PlotFcn', plotFcnWithHandle);
%% PSO implementation
[x,fval] = particleswarm(fun,nvars,lb,ub,options);
%% custom plot
function dual_plots(optimValues, state, myfig)
pswplotbestf(optimValues, state);
myplot(optimValues, state, myfig)
end
function stop = myplot(optimValues, state, myfig)
stop = false; % Control stopping the algorithm if needed
ax = get(myfig,'Parent');
% Access the current position of particles
positions = optimValues.swarm;
% Clear the previous particles plot
hold(ax, 'on'); % Keep the surface plot
delete(findall(ax, 'Tag', 'particles'));
% Plot the current positions of particles on the surface
scatter3(ax, positions(:,1), positions(:,2), optimValues.swarmfvals, ...
'r', 'filled', 'MarkerEdgeColor','k', 'Tag', 'particles');
% Update the figure
drawnow;
% Pause for a moment to hold the figure
pause(1); % Pause for 1 second
end
Here's the error that I'm getting.
Please let me know if I missed something or should try something differently. Thank you so much for your time and help!
Walter Roberson
Walter Roberson il 27 Ago 2024
Modificato: Walter Roberson il 27 Ago 2024
functions stop = dual_plots(optimValues, state, myfig)
stop = pswplotbestf(optimValues, state);
if ~stop
stop = myplot(optimValues, state, myfig);
end
end

Accedi per commentare.

Prodotti


Release

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by