Is there a way to update the legend as the for goes on?

I've been thinking how I could update in Matlab the legend of my plots as the for goes on, basically, I have a for which creates a graph that is added to the plot (using hold on) in every iteration, I'd like to update the legend of the aforementioned plot. This is how I've done it:

clear all; close all; clc; x0 = 10; t = linspace(0, 2, 100); v0 = 0; g = [10:10:100]; str = []; hold on for i = 1:length(g) x = x0 + v0*t - 1/2*g(i)*t.^2; v = v0 - g(i)*t; plot(t, x) axis([0, 2, -200, 10]); str = [str, sprintf("g = %d", g(i))]; legend(str, 'Location','southwest'); pause(0.3); end hold off 

i.e. using that size-changing string str. I have a feeling that there is a better and more performant way of doing this but I don't know how else to approach the problem.

2 Answers

Use DisplayName in the plot function, and toggle AutoUpdate in legend. This is my attempt of your for-loop:

for i = 1:length(g) x = x0 + v0*t - 1/2*g(i)*t.^2; v = v0 - g(i)*t; plot(t, x,'DisplayName',sprintf("g = %d", g(i))); axis([0, 2, -200, 10]); % str = [str, sprintf("g = %d", g(i))]; % legend(str, 'Location','southwest'); legend('Location','southwest','AutoUpdate',1); pause(0.3); end 
1

An improvement would be to update the String property of the legend, instead of creating a new legend in each iteration. This "update instead of re-create" idea is common practice for graphical objects that change with time, and results in faster execution. In your example code this will hardly have any impact, but it still looks like a cleaner approach:

clear all; close all; clc; x0 = 10; t = linspace(0, 2, 100); v0 = 0; g = [10:10:100]; str = []; le = legend(str, 'Location','southwest'); %%% new: create empty legend hold on for i = 1:length(g) x = x0 + v0*t - 1/2*g(i)*t.^2; v = v0 - g(i)*t; plot(t, x) axis([0, 2, -200, 10]); str = [str, sprintf("g = %d", g(i))]; le.String = str; %%% changed: update String property of the legend pause(0.3); end hold off 

Alternatively, you can avoid storing str, and directly append the new part to the legend. Again, the main reason for this is that the code arguably looks cleaner, as you avoid keeping the same information in two places (the variable and the graphical object):

clear all; close all; clc; x0 = 10; t = linspace(0, 2, 100); v0 = 0; g = [10:10:100]; % str = []; %%% removed le = legend(str, 'Location','southwest'); %%% new: create empty legend hold on for i = 1:length(g) x = x0 + v0*t - 1/2*g(i)*t.^2; v = v0 - g(i)*t; plot(t, x) axis([0, 2, -200, 10]); % str = [str, sprintf("g = %d", g(i))]; %%% removed le.String = [le.String sprintf("g = %d", g(i))]; %%% changed: append new string pause(0.5); end hold off 

As a side note, speaking of performance, you may want to replace clear all by clear; see relevant links: 1, 2, 3.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like