Main Content

Guardado y carga de instancias de clases de gráficas

Las gráficas que se heredan de la clase básica ChartContainer siguen las mismas reglas de guardado y carga que los otros objetos de MATLAB®. No obstante, en algunos casos, es posible que desee que sus objetos guarden y carguen información adicional. Por ejemplo, para proporcionar soporte para el guardado y la carga del resultado de los cambios interactivos, como la rotación o acercar y alejar, tiene que almacenar la vista modificada de los ejes en una propiedad de la clase. Al definir las propiedades y los métodos para almacenar y recuperar estos tipos de cambios, permite que los usuarios guarden y vuelvan a cargar las instancias de la gráfica conservando los cambios.

Patrón de codificación para el guardado y la carga de los cambios de los ejes

Las interacciones de los ejes integrados cambian algunas propiedades de los ejes. Por ejemplo, arrastrar para rotar una gráfica 3D cambia la propiedad View. De forma similar, arrastrar para acercar o alejar en una gráfica cambia las propiedades XLim, YLim (y posiblemente ZLim) de los ejes. Para conservar los cambios cuando el usuario guarde y vuelva a cargar la gráfica, añada estos componentes a la clase:

  • Defina una propiedad protegida para almacenar el estado de la gráfica: esta propiedad ofrece un lugar para almacenar los cambios de los ejes cuando MATLAB guarda el objeto de la gráfica. Por ejemplo, puede llamar a esta propiedad ChartState.

  • Defina un método get para recuperar el estado de la gráfica: este método realiza ambas funciones en función de si MATLAB guarda o carga el objeto de la gráfica. Cuando MATLAB guarda el objeto de la gráfica, el método devuelve los cambios relevantes de los ejes para que se puedan guardar. Cuando MATLAB carga el objeto de la gráfica, el método devuelve los cambios de los ejes que se almacenan en la propiedad ChartState.

  • Defina un método protegido que actualice los ejes: cuando el objeto de la gráfica se carga en MATLAB, este método llama al método get de la propiedad ChartState y, a continuación, actualiza las propiedades relevantes de los ejes de la gráfica.

Definir una propiedad protegida para almacenar el estado de la gráfica

Defina una propiedad protegida para almacenar la información relevante de los ejes. Esta propiedad está vacía a no ser que MATLAB establezca su valor durante el proceso de guardado o que MATLAB cargue una instancia guardada de la gráfica. Defina la propiedad con un nombre que sea útil y fácil de reconocer. Por ejemplo, defina una propiedad llamada ChartState.

properties (Access = protected)
    ChartState = []
end

Definir un método get para obtener el estado de la gráfica

Defina un método get público para la propiedad ChartState. Como todos los métodos set y get, este método hereda de forma automática los permisos de acceso de la propiedad ChartState. MATLAB llama a este método cuando guarda una instancia de la gráfica.

En este método, cree una variable llamada isLoadedStateAvailable que almacena un valor logical. Este valor es true cuando la propiedad ChartState no está vacía.

A continuación, escriba una instrucción condicional que compruebe el valor de isLoadedStateAvailable. Divida los segmentos en cláusulas:

  • Cláusula if...then: el valor isLoadedStateAvailable es true. Devuelva los contenidos de la propiedad ChartState.

  • Cláusula else: el valor isLoadedStateAvailable es false. Cree una estructura y obtenga el objeto de ejes. Agregue los campos XLim, YLim y ZLim a la estructura solo si las propiedades XLim, YLim y ZLim en los ejes han cambiado. Para probar si las propiedades de los ejes han cambiado, compruebe para ver si las propiedades de modo correspondientes se establecen en 'manual'. Ya que no hay una propiedad de modo asociada con los ejes de la propiedad View, agregue el campo View a la estructura sin comprobar nada.

methods
    function data = get.ChartState(obj)
        isLoadedStateAvailable = ~isempty(obj.ChartState);
            
         if isLoadedStateAvailable
             data = obj.ChartState;
         else
             data = struct;
             ax = getAxes(obj);
                
             % Get axis limits only if mode is manual.
             if strcmp(ax.XLimMode,'manual')
                 data.XLim = ax.XLim;
             end
             if strcmp(ax.YLimMode,'manual')
                 data.YLim = ax.YLim;
             end
             if strcmp(ax.ZLimMode,'manual')
                 data.ZLim = ax.ZLim;
             end
                
             % No ViewMode to check. Store the view anyway.
             data.View = ax.View;
         end
     end
end

Definir un método protegido que actualice los ejes

Defina un método protegido llamado loadstate. En este método realice los siguientes pasos:

  • Solicite la propiedad ChartState y almacene el valor devuelto como data.

  • Compruebe la existencia de los campos XLim, YLim, ZLim y View antes de actualizar las propiedades correspondientes en los ejes.

  • Elimine los contenidos de la propiedad ChartState.

Después de crear este método, llámelo al final del método setup (después de la creación de los objetos de gráficas que componen su gráfica). El método setup se ejecuta en el momento en el que MATLAB crea una nueva instancia de la gráfica o cuando carga una instancia de una gráfica.

function loadstate(obj)
    data=obj.ChartState;
    ax = getAxes(obj);
            
    % Look for states that changed
    if isfield(data, 'XLim')
        ax.XLim=data.XLim;
    end
    if isfield(data, 'YLim')
        ax.YLim=data.YLim;
    end
    if isfield(data, 'ZLim')
        ax.ZLim=data.ZLim;
    end
    if isfield(data, 'View')
        ax.View=data.View;
    end
            
    % Reset ChartState to empty
    obj.ChartState=[];
end

Ejemplo: Gráfica en 3D que almacena los límites y la visualización del eje

Defina una clase MeshGradientChart para mostrar una gráfica de malla con los vectores de los gradientes x e y en los puntos de la cuadrícula. Diseñe esta clase para que las propiedades XLim, YLim, ZLim y View de los ejes se conserven cuando el usuario guarde y vuelva a cargar una instancia de la gráfica.

Para definir esta clase, cree un archivo de programa denominado MeshGradientChart.m en una carpeta que se encuentre en la ruta de MATLAB. A continuación, implemente la clase siguiendo los pasos que aparecen en la tabla.

PasoImplementación

Derive la clase a partir de la clase básica ChartContainer.

classdef MeshGradientChart < matlab.graphics.chartcontainer.ChartContainer

Defina las propiedades públicas.

    properties
        XData (:,:) double = []
        YData (:,:) double = []
        ZData (:,:) double = []
    end

Defina las propiedades privadas. Una propiedad almacena un objeto Surface y la otra almacena un objeto Quiver.

    properties (Access = private,Transient,NonCopyable)
        SurfaceObject (1,1) matlab.graphics.chart.primitive.Surface
        QuiverObject (1,1) matlab.graphics.chart.primitive.Quiver
    end

Defina una propiedad ChartState protegida para el almacenamiento del estado de los ejes.

    properties (Access = protected)
        ChartState = []
    end

Implemente el método setup. En este caso, llame a las funciones mesh y quiver3 para crear los objetos Surface y Quiver, respectivamente. Almacene los objetos en las propiedades correspondientes y vuelva a definir el estado de permanencia de los ejes en 'off'. Después llame al método loadstate para actualizar el estado de los ejes.

    methods(Access = protected)
        function setup(obj)
            ax = getAxes(obj);
            
            % Create Mesh and Quiver objects.
            obj.SurfaceObject=mesh(ax,[],[],[],'FaceColor','none');
            hold(ax,'on')
            obj.QuiverObject=quiver3(ax,[],[],[],[],'Color','r','LineWidth',2);
            hold(ax,'off')
            
            % Load state of the axes.
            loadstate(obj);
        end

Implemente el método update. En este caso, actualice las coordenadas x e y de la gráfica de malla y el origen de los vectores de los gradientes. Después actualice las longitudes y las direcciones de los vectores.

        function update(obj)
            % Update Mesh data.
            obj.SurfaceObject.XData = obj.XData;
            obj.SurfaceObject.YData = obj.YData;
            obj.SurfaceObject.ZData = obj.ZData;
            
            % Update locations of vector tails.
            obj.QuiverObject.XData = obj.XData;
            obj.QuiverObject.YData = obj.YData;
            obj.QuiverObject.ZData = obj.ZData;
            
            % Update lengths and directions of vectors.
            [gradx,grady] = gradient(obj.ZData);
            obj.QuiverObject.UData = gradx;
            obj.QuiverObject.VData = grady;
            obj.QuiverObject.WData = zeros(size(obj.ZData));
        end

Implemente el método loadstate, que actualiza los ejes y restablece la propiedad ChartState para un arreglo vacío.

        function loadstate(obj)
            data=obj.ChartState;
            ax = getAxes(obj);
            
            % Look for states that changed.
            if isfield(data, 'XLim')
                ax.XLim=data.XLim;
            end
            if isfield(data, 'YLim')
                ax.YLim=data.YLim;
            end
            if isfield(data, 'ZLim')
                ax.ZLim=data.ZLim;
            end
            if isfield(data, 'View')
                ax.View=data.View;
            end
            
            % Reset ChartState to empty.
            obj.ChartState=[];
        end
    end

Implemente el método el método ChartState get, que devuelve la información del estado de los ejes.

    methods
        function data = get.ChartState(obj)
            isLoadedStateAvailable = ~isempty(obj.ChartState);
            
            % Return ChartState content if loaded state is available.
            % Otherwise, return current axes state.
            if isLoadedStateAvailable
                data = obj.ChartState;
            else
                data = struct;
                ax = getAxes(obj);
                
                % Get axis limits only if mode is manual.
                if strcmp(ax.XLimMode,'manual')
                    data.XLim = ax.XLim;
                end
                if strcmp(ax.YLimMode,'manual')
                    data.YLim = ax.YLim;
                end
                if strcmp(ax.ZLimMode,'manual')
                    data.ZLim = ax.ZLim;
                end
                
                % No ViewMode to check. Store the view anyway.
                data.View = ax.View;
            end
        end
    end
end

A continuación, cree una instancia de la gráfica. Después gire o acerque la gráfica y guárdela. El objeto conserva los cambios interactivos cuando vuelve a cargar la gráfica en MATLAB.

Crear una instancia de la gráfica

[X,Y] = meshgrid(-5:5);
Z = X.^2 + Y.^2;
c = MeshGradientChart('XData',X,'YData',Y,'ZData',Z);

Cuando crea la gráfica:

  • El método setup llama al método loadstate.

  • El método loadstate lleva a cabo estas tareas, que últimamente no tiene efecto sobre el objeto de la gráfica o el objeto de los ejes subyacente.

    • Llame al método get.ChartState, que devuelve una estructura que contiene el valor actual de la propiedad View de los ejes.

    • Establezca la propiedad View sobre los ejes para el valor almacenado en la estructura.

    • Eliminar los contenidos de la propiedad ChartState.

Girar o acercar la gráfica y guardarla

savefig(gcf,'mychart.fig')

Cuando guarde la gráfica, MATLAB llama al método get.ChartState, que devuelve una estructura que contenga:

  • Los valores de las propiedades XLim, YLim o ZLim en los ejes, pero solo si cambiaron

  • El valor de la propiedad View en los ejes

Después de que MATLAB recupere la estructura, almacena la estructura en la propiedad ChartState del objeto de la gráfica que se está guardando.

Cargar la gráfica que ha guardado

openfig('mychart.fig')

Cuando carga la gráfica:

  • El método setup llama al método loadstate.

  • El método loadstate lleva a cabo estas tareas:

    • Llamar al método get.ChartState, que devuelve la estructura de la propiedad ChartState.

    • Restablecer las propiedades XLim, YLim, ZLim y View en los ejes, pero solo si la estructura contiene los campos correspondientes.

    • Eliminar los contenidos de la propiedad ChartState.

Consulte también

Clases

Funciones

Propiedades

Temas relacionados