Cii
Cii

Reputation: 133

Matlab plot 2D scatter points and lines of groups

I have a matrix cell, I want to plot all points into 3 graphs (x,y1), (x,y2) and (x,y3).

              y1      y2        y3     x
BCLK103     4.000    5.102    7.055    10
BCLK103     4.100    5.112    7.555    5
BCLK103     4.600    6.182    9.55     3
BCLK105     5.000    5.112    7.255    11
BCLK105     4.060    6.12     8.555    6
BCLK109     4.050    5.112    7.152    10
BCLK109     7.000    5.112    7.545    5
BCLK109     4.900    6.142    8.545    2
BCLK110     3.900    6.311    8.100    2

And I want to plot lines within group in each graph, eg.a line for BCLK103 in the y1 graph connect three points (4.000, 4.100, 4.600), a line for BCLK103 in the y2 graph should connect three points (5.102, 5.112, 6.182), a line for BCLK103 in the y3 graph should connect three points (7.055, 7.555, 9.55); a line for BCLK105 in the y1 graph connect two points (5.000, 4.060) etc. BCLK110 has only one point so it could not form a line in each graph. But I still want its point plotted in each graph.

I tried this:

figure; 
f1 = plotmatrix(x,y1);
hold on

for n = 1:9

   sameGroup = strcmp(allData(n+1,1), allData(n,1));

   if sameGroup

      tempx1 = cell2mat(allData(n,5));
      tempx2 = cell2mat(allData(n+1,5));
      tempy1 = cell2mat(allData(n,2));
      tempy2 = cell2mat(allData(n+1,2));

      tempx = [tempx2, tempx1];
      tempy = [tempy2, tempy1];

      plot(tempx, tempy, '-');

   end
end

hold off

But MATLAB only plots the scatter graph without any lines. Would anyone please teach me how to plot the points? Am i using hold on correctly?

Upvotes: 2

Views: 292

Answers (1)

Rody Oldenhuis
Rody Oldenhuis

Reputation: 38032

The problem is, you're extracting only single points in the loop:

tempx1 = cell2mat(allData(n,5));
% 'n' is the loop index, and thus scalar. therefore, 
% tempx1 is a scalar. Similar for the rest. 

plot() needs vector/matrix inputs to be able to know which points to connect to which other points. Here is how I would do this:

function plot_example()

    % Your data (probably passed via function argument)
    allData = {...
         NaN        'y1'     'y2'     'y3'     'x'
        'BCLK103'    4.000    5.102    7.055    10
        'BCLK103'    4.100    5.112    7.555    5
        'BCLK103'    4.600    6.182    9.55     3
        'BCLK105'    5.000    5.112    7.255    11
        'BCLK105'    4.060    6.12     8.555    6
        'BCLK109'    4.050    5.112    7.152    10
        'BCLK109'    7.000    5.112    7.545    5
        'BCLK109'    4.900    6.142    8.545    2
        'BCLK110'    3.900    6.311    8.100    2
    };

    % Rename for convenience (might need to be generalized)
    gp =  allData(2:end, 1);
    y1 = [allData{2:end, 2}];
    y2 = [allData{2:end, 3}];
    y3 = [allData{2:end, 4}];
    x  = [allData{2:end, 5}];

    % Unique group IDs
    gu = unique(gp);

    % Plot all desired plots in a single figure
    figure('position', [400, 200, 1200, 600]);

    do_plot(1, y1);
    do_plot(2, y2);
    do_plot(3, y3);

    % Helper function doing the actual work
    function do_plot(pltind, ydata)

        subplot(1,3, pltind);
        hold on
        plot(x, ydata, '.');

        legendentries = ['scatter'; gu];
        for ii = 1:numel(gu)

            % Make slice according to group ID
            gp_inds = strcmp(gu{ii}, gp);

            % Pick a Unique color, taking into account that 
            % that only may be one point
            colcmd = {'color', rand(1,3)};
            if sum(gp_inds) == 1
                colcmd = ['x' colcmd 'markersize' 10]; end %#ok<AGROW>

            % Use plot(), is a line plotter by default
            plot(x(gp_inds), ydata(gp_inds), colcmd{:});

        end

        xlabel('x')
        ylabel(['y' int2str(pltind)])
        legend(legendentries)

    end

end

Result:

result from running the function above

Upvotes: 1

Related Questions