Q: Plotting large number of squares in different colours I am trying to speed up some code I've inherited that draws boxes around defined coordinates over an image. The number of boxes typically ranges around 1000-6000. Currently it uses a for loop around the plot() function, which is passed 5 coordinates to draw the box.
I am trying to rework it to use a single call to plot(), which I understand is a more efficient way of rendering. I have generated an array of x and y coordinates that I can pass to the plot, and an array of RGB triplets to define the colour of each line (each box has a status shown by this colour). I can use these with the 'defaultAxesColorOrder' property, but I need it to stop joining every square together.
I have looked at the 'defaultAxesLineStyleOrder' property, but from what I understand it only cycles styles after one full colour cycle, which won't work in this case. What I really need is a way for it to draw lines for 5 points, then none for the next, then repeat.
Is there any way I can do this in a way that won't slow down rendering too much?
EDIT: Here's the new code so far:
EDIT 2: I've managed to stop it drawing lines between squares using NaN values to separate each square. I got the technique from the Mathworks documentation on a page about optimising line plots, I can't find the URL for the life of me now. I have updated the code below.
numObjs = size(MYDATA.objectInformation, 1);
if isfield(MYDATA, 'objectInformation')
    if (numObjs > 0)

        padding = MYDATA.preferences.boxSize/2;

        % Array of coords. 6* the number of objects (takes 5 points to draw
        % a square + NaN gap hack)
        objCoords = zeros(6*numObjs, 2);
        objCoordsIndex = 1;

        % array of line colours for defaultAxesColorOrder
        objColours = zeros(6*numObjs, 3);

        % Add each object to array
        for loop = 1:numObjs

            x_seed = MYDATA.objectInformation{loop, 1};
            y_seed = MYDATA.objectInformation{loop, 2};
            status = MYDATA.objectInformation{loop, 3};

            % set coords to draw bounding box
            objCoords(objCoordsIndex    , 1:2) = [(x_seed - padding), (y_seed - padding)];  % bottom left
            objCoords(objCoordsIndex + 1, 1:2) = [(x_seed - padding), (y_seed + padding)];  % top left
            objCoords(objCoordsIndex + 2, 1:2) = [(x_seed + padding), (y_seed + padding)];  % top right
            objCoords(objCoordsIndex + 3, 1:2) = [(x_seed + padding), (y_seed - padding)];  % bottom right
            objCoords(objCoordsIndex + 4, 1:2) = [(x_seed - padding), (y_seed - padding)];  % bottom left
            objCoords(objCoordsIndex + 5, 1:2) = [NaN, NaN];  % gap!

            % set colour depending on status
            % NOTE: doesn't use preferences due to effort of converting
            % short colour names with line style modifiers to RGB triplets
            if strcmp(status, 'Interesting object') || strcmp(status, 'Interesting object - manually tagged')
                colour = [0 1 0];
            elseif strcmp(status, 'Not interesting')
                colour = [1 0 0];
            else    % If not processed/other status
                colour = [0 0 1];
            end

            for i = 1:5
                objColours(objCoordsIndex + i - 1, 1:3) = colour;
            end

            objCoordsIndex = objCoordsIndex + 5;

        end

        % Define line colours

        % Plot array
        plot(MYDATA.imagePanelHandles.mainAxes, objCoords(:, 1), objCoords(:, 2));
    end
end

Here's the old code if anyone wants to see it:
    if isfield(MYDATA, 'objectInformation')
    if (size(MYDATA.objectInformation, 1) >= 1)
        for loop = 1:size(MYDATA.objectInformation, 1)

            x_seed = MYDATA.objectInformation{loop, 1};
            y_seed = MYDATA.objectInformation{loop, 2};
            status = MYDATA.objectInformation{loop, 3};

            %form MYDATA.preferences.boxSize/2 pixel wide box around seed
            padding = MYDATA.preferences.boxSize/2;

            x = [(x_seed - padding), (x_seed - padding), (x_seed + padding), (x_seed + padding), (x_seed - padding)];
            y = [(y_seed - padding), (y_seed + padding), (y_seed + padding), (y_seed - padding), (y_seed - padding)];

            if strcmp(status,'Not yet processed')
                plot(MYDATA.imagePanelHandles.mainAxes,x,y,MYDATA.preferences.notProcessedBoxColour)
            elseif strcmp(status, 'Interesting object') || strcmp(status, 'Interesting object - manually tagged')
                plot(MYDATA.imagePanelHandles.mainAxes,x,y,MYDATA.preferences.interestingObjectBoxColour)
            elseif strcmp(status, 'Not interesting')
                plot(MYDATA.imagePanelHandles.mainAxes,x,y,MYDATA.preferences.notInterestingBoxColour)
            else % be cautious and catch anything that has fallen through
                plot(MYDATA.imagePanelHandles.mainAxes,x,y,'-r')
            end
        end
    end


A: I have solved the problem by taking advantage of the plot() function's ability to take 2D arrays for each coordinate. Each column is plotted in a different colour automatically, so all I had to do was create an array of X and an array of Y coords where each row represents one object's coordinate and each row represents its status. Here is a relevant part of the documentation: http://uk.mathworks.com/help/matlab/ref/plot.html#btzptin
Here's my final code:
numObjs = size(MYDATA.objectInformation, 1);
if isfield(MYDATA, 'objectInformation')
if (numObjs > 0)

    padding = MYDATA.preferences.boxSize/2;

    % Arrays of coords. 6* the number of objects (takes 5 points to draw
    % a square + NaN gap hack)
    objCoordsX = NaN(6*numObjs, 3);
    objCoordsY = NaN(6*numObjs, 3);
    objCoordsIndex = 1;

    % Add each object to array
    for loop = 1:numObjs

        x_seed = MYDATA.objectInformation{loop, 1};
        y_seed = MYDATA.objectInformation{loop, 2};
        status = MYDATA.objectInformation{loop, 3};

        % set column to write to depending on status
        if strcmp(status, 'Interesting object') || strcmp(status, 'Interesting object - manually tagged')
            statusColumn = 1;
        elseif strcmp(status, 'Not interesting')
            statusColumn = 2;
        else    % If not processed/other status
            statusColumn = 3;
        end

        objCoordsX(objCoordsIndex    , statusColumn) = x_seed - padding;  % bottom left
        objCoordsX(objCoordsIndex + 1, statusColumn) = x_seed - padding;  % top left
        objCoordsX(objCoordsIndex + 2, statusColumn) = x_seed + padding;  % top right
        objCoordsX(objCoordsIndex + 3, statusColumn) = x_seed + padding;  % bottom right
        objCoordsX(objCoordsIndex + 4, statusColumn) = x_seed - padding;  % bottom left

        objCoordsY(objCoordsIndex    , statusColumn) = y_seed - padding;  % bottom left
        objCoordsY(objCoordsIndex + 1, statusColumn) = y_seed + padding;  % top left
        objCoordsY(objCoordsIndex + 2, statusColumn) = y_seed + padding;  % top right
        objCoordsY(objCoordsIndex + 3, statusColumn) = y_seed - padding;  % bottom right
        objCoordsY(objCoordsIndex + 4, statusColumn) = y_seed - padding;  % bottom left

        objCoordsIndex = objCoordsIndex + 6;    % 5 coords to draw box + NaN gap in line

    end

    % Plot coords
    plot(MYDATA.imagePanelHandles.mainAxes, objCoordsX, objCoordsY);
end

