MATLAB Answers

Plotting on GUI and navigate between the figures

99 views (last 30 days)
Pedro Augusto de Castro e Castro
Pedro Augusto de Castro e Castro on 14 Jan 2020 at 21:41
Commented: Adam Danz on 16 Jan 2020 at 17:34
Hello everyone,
So, I want to plot some graphs in my GUI, but using the same axes object. And then, I'll have two buttons to navigate between the figures. Something like what is shown in the fig below.
graphs.PNG
Any ideas on how to do this?
I tried creating a sequence with all the graphs that will be created, and assign a signal to the two buttons of the fig. above (-1 and 1).
function manageGraphs(handles, hObject, sinal)
% Define the sequences of graphs, for each topology
sequence = {'perdas_ripple', 'volume_ripple', ...
'perdas_fsw','volume_fsw', ...
'pareto_ripple', 'pareto_fsw'};
dim_sequence = length(sequence);
start_graphs = 1;
end_graphs = 6;
% Get the current index_sequence from handles
index_sequence = 4;
fsw = handles.fsw;
delta_i = handles.delta_i;
if (sinal == -1)
% If the user pressed the left button, i.e., sinal = -1
if(index_sequence ~= start_graphs)
% If the user did not reach the first element
% index_sequence ~= start_current_graphs
% Sweep to the previous graph, if the user did not reach the
% beginning of the list
index_sequence = index_sequence + sinal;
else
% index_sequence == start_losses_graphs
% If the user reaches the start, returns to the end
index_sequence = end_graphs;
end
% If the sequence ends, return to the start
elseif sinal == 1
% If the user pressed the right button, i.e., sinal = 1
if(index_sequence ~= end_graphs)
index_sequence = index_sequence + sinal;
else
% If the user reached the last element in the sequence of graphs
% of losses, returns to the start of this list
index_sequence = start_graphs;
end
end
seq = sequence{index_sequence};
% Make 'grafico_corrente' the current graph
axes(handles.graphs);
% Plot the graphs
switch seq
case 'perdas_ripple'
plot(handles.x_ripple, handles.PerdasT_ripple); hold on;
plot(handles.x_ripple, handles.PerdasL_ripple); hold on;
plot(handles.x_ripple, handles.PerdasTotais_ripple);
xlabel('Ripple de Corrente');
ylabel('Perdas [W]');
title('Perdas nos Transistores, Indutores e Totais');
legend('Perdas nos Transistores', 'Perdas nos Indutores', 'Perdas Totais');
case 'volume_ripple'
plot(handles.x_ripple, handles.VolL_ripple); hold on;
plot(handles.x_ripple, handles.VolHS_ripple); hold on;
plot(handles.x_ripple, handles.VolumeTotal_ripple);
xlabel('Ripple de Corrente');
ylabel('Volume [dm³]'); % Verificar se é dm³ msm
title('Volume dos Indutores, Dissipadores e Total');
legend('Volume dos Indutores', 'Volume dos Dissipadores', 'Volume Total');
case 'perdas_fsw'
plot(handles.x_fsw, handles.PerdasT_fsw); hold on;
plot(handles.x_fsw, handles.PerdasL_fsw); hold on;
plot(handles.x_fsw, handles.PerdasTotais_fsw);
xlabel('Frequência de Chaveamento');
ylabel('Perdas [W]');
title('Perdas nos Transistores, Indutores e Totais');
legend('Perdas nos Transistores', 'Perdas nos Indutores', 'Perdas Totais');
case 'volume_fsw'
plot(handles.x_fsw, handles.VolL_fsw); hold on;
plot(handles.x_fsw, handles.VolHS_fsw); hold on;
plot(handles.x_fsw, handles.VolumeTotal_fsw);
xlabel('Frequência de Chaveamento');
ylabel('Volume [dm³]'); % Verificar se é dm³ msm
title('Volume dos Indutores, Dissipadores e Total');
legend('Volume dos Indutores', 'Volume dos Dissipadores', 'Volume Total');
case 'pareto_ripple'
for k = 1 : length(delta_i)
plot(handles.DenPot(k,1:end), handles.Rend(k,1:end)); hold on;
legend("Ripple = " + delta_i(k));
end
xlabel('Densidade de Potência [kW/dm³]');
ylabel('Rendimento');
title('Rendimento x Densidade de Potência - Diferentes Ripples');
case 'pareto_fsw'
for k = 1 : length(fsw)
plot(handles.DenPot(:,k), handles.Rend(:,k)); hold on;
legend("Fsw = " + fsw(k) + "kHz");
end
xlabel('Densidade de Potência [kW/dm³]');
ylabel('Rendimento');
title('Rendimento x Densidade de Potência - Diferentes Fsw');
end
end
obs.: Is it correct how I made the plot loops and the legends of the two last cases (pareto_ripple and pareto_fsw) ?
Thanks in advance!

  7 Comments

Show 4 older comments
Adam Danz
Adam Danz on 15 Jan 2020 at 17:10
Ahhh.... sorry. I forgot that axis off only turns off the axes and does not turn off the content of the axes.
The small fix is to apply the visibility toggle to axis children, too.
set(handles.graph_1, 'Visible', 'off');
set(handles.graph_1.Children, 'Visible', 'off');
Pedro Augusto de Castro e Castro
Pedro Augusto de Castro e Castro on 15 Jan 2020 at 17:32
Hey man, I'm sorry but I still can't get this right. Do I put this line of code for every axes?
set(handles.graph_1.Children, 'Visible', 'off');
Even though I'm setting axes(AxesHandle) and plot(AxesHandle, x, y) and setting all of the others axes to not visible (even their children as you pointed), all the plots are going to the same graph and are shown at the same time.
graphs.PNG
Adam Danz
Adam Danz on 15 Jan 2020 at 17:43
Every time you want to turn an axes on or off you must execute both lines of code.
set(handles.graph_1, 'Visible', 'off'); % or 'on'
set(handles.graph_1.Children, 'Visible', 'off'); % or 'on'

Sign in to comment.

Accepted Answer

Adam Danz
Adam Danz on 15 Jan 2020 at 17:40
Edited: Adam Danz on 16 Jan 2020 at 16:22
Summary of the comments under the question:
Instead of using the [<<] and [>>] buttons to toggle through various data sets that will be plotted on the axes, you can create a number of axes that each host a dataset while the toggle buttons control which axes are visible.
Here are the steps needed and an example of the code for each step.
  1. Plot each set of data to it's corresponding axes
  2. Set the visibility of the axes and its children to "off" except for one of the axes.
  3. The callback functions to the toggle buttons will merely cycle through the list of axes.
% Step 1
hold(handles.axes1,'on')
plot(handles.axes1, x1, y1)
plot(handles.axes1, w1, z1)
hold(handles.axes2,'on')
plot(handles.axes2, x2, y2)
plot(handles.axes2, w2, z2)
hold(handles.axes3,'on')
plot(handles.axes3, x3, y3)
plot(handles.axes3, w3, z3)
% Step 2
handles.axes1.Visible = 'on'; % this one is visible
set(handles.axes1.Children, 'Visible','on')
% put this axis on top
uistack(handles.axes1,'top')
handles.axes2.Visible = 'off';
set(handles.axes2.Children, 'Visible','off')
handles.axes3.Visible = 'off';
set(handles.axes3.Children, 'Visible','off')
% Step 3
% There are lots of ways to do this; here's 1 example.
% **********************************************************
% In the Startup function store the axis label and axis
% index in the handles structure. Add the first two lines
% prior to the 3rd line which should alread exist in your
% GUI opening function.
handles.allAxes = [handles.axes1, handles.axes2, handles.axes3];
handles.axisNumber = 1:numel(handles.allAxes);
guidata(hObject, handles); % THIS LINE SHOULD ALREADY EXIST
% **********************************************************
function toggleButtonLeft(hobj, event, handles)
% Since this is the left toggle button,
% we'll cycle circularly to the left
handles.axisNumber = circshift(handles.axisNumber, 1); % circshift(..., -1) for right-button
% update stored data
guidata(hObject, handles);
% turn on current axes & children
handles.allAxes(handles.axisNumber(1)).Visible = 'on';
set(handles.allAxes (handles.axisNumber(1)).Children,'Visible','on')
% turn off all other axes and children
for j = 2:numel(handles.axisNumber)
handles.allAxes (handles.axisNumber(j)).Visible = 'off';
set(handles.allAxes (handles.axisNumber(j)).Children,'Visible','off')
end
% put current axis on top
uistack(handles.allAxes(handles.axisNumber(1)),'top')
end

  10 Comments

Show 7 older comments
Adam Danz
Adam Danz on 16 Jan 2020 at 16:23
Pedro Augusto de Castro e Castro, sorry about that. I've updated the code in my new answer with a new approach. Be sure to look at all of the code in my answer carefully for changes.

Sign in to comment.

More Answers (0)

Sign in to answer this question.