# How to plot multiple data sets on the same graph - Complex Aggression study

2 views (last 30 days)
John Doe on 7 May 2015
Commented: John Doe on 13 May 2015
I am relatively new to Matlab. I am aware how to use the hold functions to do basic plots however I can't work out how to implement this into the following code to achieve multiple sets of data but on the same plot. Any help will be greatly appreciated.
Edit: Some code such as 'neighbours' are functions I have created so if some of the code seems strange, that may also be why. - If anyone needs to see these in order to help please let me know. Once again thanks!
Edit 2: I have added all the code you need to run the experiment. If you do this you will see what I am trying to achieve (hopefully) - Thanks again for the responses! __________________________________________________________________________
Firstly the Neighbours function (save this as a function):
function nbrs = neighbours(m, n, bdry, conn, prnt)
% function nbrs = neighbours(m, n, bdry, conn)
%
% calculate adjacency list for image graph
%
% m, n = image dimensions (m x n)
% bdry = boundary condition 'closed' or 'torus'
% conn = connectivity '4' or '8'
% prnt = optional printout (print when prnt = 1)
%
% nbrs = cell array of lists of indices k = 1 to m*n
% nbrs{k} = [k1 k2 k3 ...]
% Lookup table for i, j values of the three
% [-1 0 1]-shifted versions of rows and coumns,
% NaN indicates neighbour is off edge
switch bdry
case 'closed'
I = [[NaN 1:m-1]; 1:m; [2:m NaN]];
J = [[NaN 1:n-1]; 1:n; [2:n NaN]];
case 'torus'
I = [[m 1:m-1]; 1:m; [2:m 1]];
J = [[n 1:n-1]; 1:n; [2:n 1]];
end
%%%%nested function to simplify coding below
function k = ind(i1, j1, i, j)
k = sub2ind([m n], I(i1, i), J(j1, j));
end
nbrs = {};
for k = 1:m*n
[i j] = ind2sub([m n], k);
switch conn
case '4' % fancy formatting so easy to check layout
nbr = [ind(1, 2, i, j) ind(2, 1, i, j),ind(2, 3, i, j), ...
ind(3, 2, i, j)];
case '8'
nbr = [ind(1, 1, i, j), ind(1, 2, i, j), ind(1, 3, i, j), ...
ind(2, 1, i, j),ind(2, 3, i, j), ...
ind(3, 1, i, j), ind(3, 2, i, j), ind(3, 3, i, j)];
end
nbrs{k} = nbr(~isnan(nbr)); % remove any missing (boundary) pixels
end
if prnt == 1
for k = 1:length(nbrs)
fprintf('%5d :', k); fprintf('%5d ', nbrs{k}); fprintf('\n')
end
end
end % function end
___________________________________________________________________
Here is the code for the function rand_binary
function im = rand_binary(m, n, prob)
% function im = rand_binary(prob)
%
% Make binary image with pixels randomly set to black
%
% m, n = image size (m x n)
% prob = probablity of black pixel
%
% im = returned image
im = double(rand(m, n) > prob);
__________________________________________________________________
And run_simulation function:
function [pop2, xagg] = run_simulation(pop1, sf, nbrs, niter, plt)
% function [pop2, xagg] = run_simulation(pop1, sf, nbrs, niter, sf, plt)
%
% pop1 = binary image for initial aggression map(aggressive = 0 = black)
% sf = binary image for short-fuse map (short-fuse = 0 = red-star)
% nbrs = adjacency list to specify network topology
% niter = number of updates to apply
% plt = plot flag (0 = no plots, 1 = ahow plots)
%
% pop2 = final aggresion map
% xagg = final proportion of aggressives
if nargin < 5
plt = 1;
end
[m n] = size(pop1);
if plt
plot_world(pop1, sf);
drawnow
end
a = 0; % aggressive
p = 1; % peaceful
pop2 = pop1;
for i = 1:niter
for k = 1:m*n
nbr = nbrs{k};
na = sum(pop1(nbr) == a); % number aggressive;
np = sum(pop1(nbr) == p); % number peaceful
if sf(k) == 0
if na >= 1
pop2(k) = a;
else
pop2(k) = p;
end
else
if na > np
pop2(k) = a;
elseif na < np
pop2(k) = p;
end % else stays unchanged
end
end
pop1 = pop2;
if plt
plot_world(pop1, sf);
title(sprintf('Day %d', i+1));
pause(0.2)
end
end
xagg = sum(pop2(:) == a)/(m*n);
____________________________________________________________________
Now this is the code to plot my graph. If you run this data as it is it should plot a smooth sigmoidal curve for a single sf value. However I want to compare the effect of different sf values by plotting their results on the same graph.
clear all % check this is stand-alone
% specify grid size and topology
m = 100;
n = 100;
nbrs = neighbours(m, n, 'closed', '4', 0);
% independent variable: proportion of aggressives
nsamp = 1000; % number of values of pagg to use
pagg = linspace(0, 1, nsamp); % pagg increases from 0 (none aggaggresive) to 1 (all aggresive)
% dependent variable xagg: the final proportion of aggresssives
xagg = NaN(1, nsamp); % xagg is storage for this number, one for each pagg value
% specify proportion of short-fuse individuals
psf = 0.2;
sf = rand_binary(m, n, psf);
% number of iterations
ndays = 20;
niter = ndays-1;
plt = 0; % no movie
figure(3); clf
for i = 1:nsamp
pop1 = rand_binary(m, n, pagg(i)); % make initial population with pagg(i)
[pop2, xagg(i)] = run_simulation(pop1, sf, nbrs, niter, plt); % get final population & proportion of aggressives
figure(3);
plot(pagg, xagg, '.', 'MarkerSize', 10)
xlabel('Initial Population Aggressive');
ylabel('Final Population Aggressive');
title('Parametric Study for Neighbourhood Connectivity')
axis([0 1 0 1]);
drawnow
end
Any help with this problem would be greatly appreciated (sorry i haven't been all that clear, struggling to wrap my head around the code and the way to verbally express it).
Many thanks again, John
Chad Greene on 12 May 2015
I understand--when you're starting out it's hard to know which lines are absolutely necessary and which are not. I don't have Matlab with me, but next time I do I'll give your code another shot.
John Doe on 13 May 2015
really appreciate it!

Ilham Hardy on 7 May 2015
Edited: Ilham Hardy on 7 May 2015
if you want the points have similar color, use
hold on
if you want the points have alternating color, use
hold all
*put the hold command after the plot command
John Doe on 7 May 2015
Ive managed to use the hold functions previously to plot multiple plots on a single graph,
For some reason however, I am having a lot of issue implementing this into the above code to get the desired effect.
Any ideas?
Kind regards, John

Chad Greene on 7 May 2015
Edited: Chad Greene on 7 May 2015
A few notes:
1. Don't use i as a variable name. Sometimes Matlab thinks it's the imaginary unit.
2. Only call axis settings once. No need to keep making Matlab perform the same operation multiple times.
Run this:
figure(3); clf
for k = 1:20
x = rand(3,1);
y = rand(3,1);
plot(x, y, '.', 'MarkerSize', 10)
if k == 1
xlabel('Initial Population Aggressive');
ylabel('Final Population Aggressive');
title('Parametric Study for Neighbourhood Connectivity')
axis([0 1 0 1]);
box off
hold all
end
drawnow
pause(.1)
end
Chad Greene on 7 May 2015
The jargon is a bit confusing. Can you strip out all lingo specific to your field and just talk in terms of x and y?
How many dependent variables do you have? Perhaps two, y1 and y2? Do they share an independent variable x or do they each have their own x1 and y1?
As I understand it, your dependent variables are changing through time, and that's what you want to animate? Does this do what you want?
% independent variable:
x = 0:.1:1;
% starting values of y1 and y2:
y1 = .2*rand(size(x));
y2 = .2*rand(size(x));
figure(3); clf
for k = 1:30
% new values of y1 and y2:
y1 = y1+.05*rand(size(x));
y2 = y2+.02*rand(size(x));
% plot y1:
h1 = plot(x, y1, 'r.', 'MarkerSize', 12);
% Set axis properties the first time:
if k == 1
xlabel('Initial Population Aggressive');
ylabel('Final Population Aggressive');
title('Parametric Study for Neighbourhood Connectivity')
axis([0 1 0 1]);
box off
hold all
end
% plot y2:
h2 = plot(x, y2, 'b.', 'MarkerSize', 10);
if k==1
legend('y1','y2')
end
drawnow
pause(.1)
% delete the data we just plotted:
delete([h1 h2])
end
John Doe on 8 May 2015
Hi Chad, Firstly thank you for continued help. I have taken what you said and tried to re word my question above with the code for the added function and additional comments on the code itself. Hopefully this has clarified my question.
Thanks, John