guide - set axes matlab gui
¿Cómo debo actualizar los datos de una parcela en Matlab? (3)
Supongamos que quiero actualizar un gráfico con nuevos datos. ¿Qué método debo elegir?
- Establezca la propiedad
XDataSource
a algún nombre, actualice la variable y llame arefreshdata
- Borre el
plot
original y llame al comandoplot
nuevamente. - Use
Set(''Xdata'',...'')
Supongamos que quiero actualizar un gráfico con nuevos datos. ¿Qué método debo elegir?
Si tiene más de un objeto de línea en los ejes dados, entonces Método:
- Establezca la propiedad XDataSource a algún nombre, actualice la variable y llame a
refreshdata
generará un error en MATLAB R2012b. Un ejemplo apropiado se proporciona en la respuesta de Andrey.
Se ha enviado un error al Mathworks.
Puede llamar a la función drawnow
y hacer algo como eso:
h = plot(nan);
for i = 1:n
y = ...
set(h,''YData'',y);
drawnow %update the graph
end
Respuesta corta: use siempre Set(''Xdata'',...'')
.
Código de ejemplo:
function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
y = sin(x.^3);
set(h,''XData'',x,''YData'',y);
end
Respuesta larga:
Hay tres medidas relevantes por las cuales uno debe elegir el mejor método.
- Claridad del código : ¿Qué tan fácil es para alguien leer su código?
- Tiempo de ejecución : ¿Cuán rápido realiza cada método su tarea?
- Portabilidad del código : ¿con qué rapidez puede volver a factorizar su código?
Ahora, analicemos los métodos posibles.
Método (1) - refreshdata
function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
set(h,''YDataSource'',''y'')
set(h,''XDataSource'',''x'')
y = sin(x.^3);
refreshdata(h,''caller'');
end
M-lint inmediatamente emite una advertencia en la línea y=sin(x.^3)
The value assigned to variable `y` might be unused
¿Por que sucede? refreshdata
usa eval
y m-lint
no puede saber que usará y
. Alguien que lea tu código, bien podría eliminar esta línea por completo. Esto sucedió porque rompiste el principio de encapsulación. refreshdata
accede a las variables del espacio de trabajo de la persona que llama. Otra forma de ver esto, suponga que pasa el control de la trama a otra función. El lector no tiene idea de por qué en la tierra escribiste y = sin(x.^3);
y cómo va a estar relacionado con la actualización de la trama.
Ahora veamos la velocidad / tiempo de ejecución. Si echas un vistazo al código fuente de refreshdata
, verás dos feos bucles for, que pasan por todas las variables de manejo de gráficos en tu espacio. Aquí está el primero:
% gather up all the objects to refresh
objs = {};
for k = 1:length(h)
obj = h(k);
objfields = fields(obj);
for k2 = 1:length(objfields)
% search for properties ending in DataSource
if strncmpi(fliplr(objfields{k2}),''ecruoSataD'',10)
objs = {objs{:},obj, objfields{k2}};
end
end
end
Imagina que no tienes una trama, sino una trama de 100 y quieres actualizar solo la primera. Esto será muy lento, porque para cada una de las parcelas, ¡intentas encontrar la que necesitas! (Me voy como ejercicio para que el lector ecruoSataD
qué es ecruoSataD
y cómo se usa).
Incluso si das el argumento relevante como argumento, todavía tienes el segundo ciclo, que ejecuta eval
varias veces. No es exactamente eficiente. Mostraré una comparación de tiempo al final.
Conclusión: difícil de entender, difícil de refactorizar, tiempo de ejecución lento
Método (2) - Eliminar y volver a trazar
function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
set(h,''YDataSource'',''y'')
set(h,''XDataSource'',''x'')
y = sin(x.^3);
delete(h);
h = plot(x,y);
end
Este método es bastante claro para el lector. Eliminaste la trama y dibujaste una nueva. Sin embargo, como veremos en la comparación de tiempo al final, ese es el método más lento.
Conclusión: fácil de entender, fácil de refactorizar, tiempo de ejecución muy lento
Método (3) - set (''XData'', ..., ''YData'')
El código es muy claro. Desea modificar dos propiedades de su trazado, XData
e YData
. Y eso es exactamente lo que haces. Además, el código se ejecuta muy rápido, como puede ver en la comparación a continuación.
function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
y = sin(x.^3);
set(h,''XData'',x,''YData'',y);
end
Desde el nuevo motor de gráficos hg2 (R2014b y superior), también puede usar la sintaxis de propiedades para especificar datos si prefiere esa notación:
function PlotUpdate()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
y = sin(x.^3);
h.XData = x;
h.YData = y;
end
Conclusión: fácil de entender, fácil de refactorizar, rápido tiempo de ejecución
Aquí está el código de comparación de tiempo
function PlotUpdateTimeCompare()
x = 0:.1:8;
y = sin(x);
h = plot(x,y);
set(h,''YDataSource'',''y'')
set(h,''XDataSource'',''x'')
y = sin(x.^3);
tic
for i=1:100
refreshdata(h,''caller'');
end
toc
tic
for i=1:100
delete(h);
h = plot(x,y);
end
toc
tic
for i=1:100
set(h,''XData'',x,''YData'',y);
end
toc
end
Y los resultados:
El tiempo transcurrido es 0.075515 segundos.
El tiempo transcurrido es 0.179954 segundos.
El tiempo transcurrido es 0.002820 segundos.