If there any problems with running the code above, please let me know! Desperate to find a solution to this problem.

Many thanks to all!

2 views (last 30 days)

Show older comments

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

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

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);

% add a legend:

if k==1

legend('y1','y2')

end

drawnow

pause(.1)

% delete the data we just plotted:

delete([h1 h2])

end

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!