Only last iteration of for loop

7 views (last 30 days)
Hello,
I am running a for loop in a while loop in app designer which may not be good programming practice but I really need it to run. I am ploting a bar chart in the for loop because i need various colors for different bars. * while loop because am constantly reading serial data from a com port using the serial port fronctions.
Only the last bar is plotted when i run the code. Displaying b on the gui is always 3. I fixed b to 2 and the second bar showed up. I would be very happy to get your ideas on y this is happening. Not just for the code to run but also for future reference. Thanks
Below is my code
properties (Access = public)
% Battery represenstation
Batteries = reordercats(categorical({'Battery1','Battery2','Battery3'})); % x values
y = [Volt1, Volt2, Volt3]; % y Values
clr = [0.2 0.71 0.3; 0.25 0.55 0.79; 0.9 0.1 0.14]; % colors
end
myBar = zeros((lenth(Batteries)));
while(1)
for b = 1:length(y)
app.BEditField.Value = b; % display b on GUI
% Plot one single bar as a separate bar series.
myBar(b) = bar(app.UIAxes, app.Batteries(b), y(b));
% Apply the color to this bar series.
set(myBar(b),'FaceColor', app.clr(b,:));
% values on each bar
text(app.UIAxes, b:b, y(b)', num2str(y(b)','%0.2f'),'HorizontalAlignment','center','VerticalAlignment','bottom')
hold on ;
end
end

Accepted Answer

Cris LaPierre
Cris LaPierre on 26 Apr 2023
Edited: Cris LaPierre on 27 Apr 2023
I think the reson you are only getting the final bar is because your hold on is not being applied to your UIAxes. In app designer, you always have to specify the target axes. Try this
hold(app.UIAxes,'on')
Note that it is best practice to pair every hold on with a corresponding hold off. Here, that should probably go outside the for loop, but inside the while loop. Otherwise, your bars will continue to be plotted on top of the previous loop's.
However, you don't need to use hold at all. My recommendation would be to add a startupfcn that creates the bar graph when the app starts.
app.myBar = bar(app.UIAxes, app.Batteries, zeros(1,3));
app.myBar.CData(1,:) = clr(1,:);
app.myBar.CData(2,:) = clr(2,:);
app.myBar.CData(3,:) = clr(3,:);
Then have your loop just update the YData property of each bar.
app.myBar(b).YData = y(b);
drawnow
  3 Comments
Kizito Amungwa Achembong
Kizito Amungwa Achembong on 27 Apr 2023
Also, I wish to ask if there is a more efficient way to represent a battery state of charge graphically on a GUI. I will like to have something that looks like a battery and changes level as it charges and discharges (Just like on an Iphone) and in a modular way so that i can show x number of batteries without changing a lot on the code. I am presently using the bar graph which works (thanks to you) but i guess there is a more efficient way.
Cris LaPierre
Cris LaPierre on 27 Apr 2023
Edited: Cris LaPierre on 27 Apr 2023
Depends what you mean by efficient. The most effecient way to me is to use something MATLAB already provides a function for (e.g. bar plot). Getting closer to what you are describing would require developing a solution yourself. That's certainly possible, and wouldn't necessarily be computationally expensive, but not sure it would qualify as efficient.
It just matters on how you value that over the current approach.

Sign in to comment.

More Answers (0)

Categories

Find more on App Building in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!