MATLAB Answers

How to plot particle trajectories and normalise to 0,0 origin?

26 views (last 30 days)
Amadeus Xu
Amadeus Xu on 25 Nov 2020
Commented: Star Strider on 26 Nov 2020
Hi all,
I have data of lots of single particle trajectories that run for different lengths of time which I'd like to be able to plot them onto a 2D graph, with all the trajectory start positions normalised to 0,0 origin, so the plot looks a bit like the following:
My data is in an excel sheet with PARTICLE_ID, Time, X and Y co-ordinate (see attached testdata.xlsx file for example of 5 particle trajectories)
After importing the data as a matrix, I presume I must use mat2cell to convert the matrix to smaller cell arrays, with each cell array representing the data different particle trajectories? Currently I have the following code:
C = mat2cell(testdata, [59 56 240 56 10], [4])
C =
5×1 cell array
{ 59×4 double} % trajectory 1
{ 56×4 double} % trajectory 2
{240×4 double} % trajectory 3
{ 56×4 double} % trajectory 4
{ 10×4 double} % trajectory 5
However, if I have a file with >100s of trajectories, how would I code this so I don't have to manually specify the cell array sizes for each trajectory?
Then the next question is how do I normalise all the particle trajectory coordinates so that they begin at the origin 0,0?
I'd greatly appreciate any help you can offer.
Thank you in advance!
Amadeus

  1 Comment

Pier Giorgio Petrolini
Pier Giorgio Petrolini on 25 Nov 2020
Hello Amadeus, I tried to solve your problem in the following way :
1) Convert the dataset in a table;
2) Find all the points of the trajectory of the same particle;
3) Scale all the points of the trajectory ( I assumed the the starting point of the trajectory of a certain particle was the first value recorded of the particle dataset under consideration i don't know if it is a correct assumption but you can easily change it in the code);
4) Plot the scaled values of the trajectory.
% Import the data
testdata = readtable("C:\Users\Client\Downloads\testdata.xlsx", opts, "UseExcel", false)
Clear temporary variables
clear opts
% Count unique values in "PARTICLE_ID" column
n = unique(testdata.PARTICLE_ID)
ParticleNumber = numel(n)
% Plot each scaled trajectory
for i = 1:ParticleNumber
table = testdata(testdata.PARTICLE_ID == i,:); % Isolate single particle trajetory
color = {'k' 'r' 'b' 'g' 'c'};
xmin = table.X(1); % Zero point on x-axis
ymin = table.Y(1); % Zero point on y-axis
table.Scaled_x = table.X-xmin; % Scaled values on x-axis
table.Scaled_y = table.Y-ymin; % Scaled values on y-axis
plot(table.Scaled_x, table.Scaled_y, color{i})
xlabel('x')
ylabel('y')
legend
hold on
end
In the attached file "untitled.1.png" you can find the plot that was generated by this code.
I really hope it helps. Kind regards,
PGP

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 25 Nov 2020
This will normalise everycell to begin at (0,0):
testdata = readmatrix('Amadeus Xu testdata.xlsx');
[Uid,~,ix] = unique(testdata(:,1));
tally = accumarray(ix, ones(size(ix)));
C = mat2cell(testdata, tally, [4])
figure
hold on
for k = 1:size(C,1)
plot(C{k}(:,3)-C{k}(1,3), C{k}(:,4)-C{k}(1,4))
end
grid
plot([0 0], ylim, 'k')
plot(xlim, [0 0], 'k')
hold off
xlabel('x')
ylabel('y')
Note that the arguments to mat2cell were not correct, so I added code to create the correct argument. The unique call is not absolutely necessary here since the IDs go from 1 to 5, however I included it in the event that is not the situation in other files. This also requires that the IDs be consecutive. Code to correct for that would be required if that is not the situation on other files.
.

  2 Comments

Amadeus Xu
Amadeus Xu on 26 Nov 2020
Thank you everyone for the help! The unique call in your code is very helpful as the Particle IDs are not always consecutive as in the example file provided.

Sign in to comment.

More Answers (2)

Steve Eddins
Steve Eddins on 25 Nov 2020
Here is one way you could do it. Read in the whole Excel file as a table. Then, in a loop, extract the particle data for each trajectory, subtract the first X-Y location, and plot it.
>> T = readtable('testdata.xlsx');
>> head(T)
ans =
8×4 table
PARTICLE_ID TIME X Y
___________ ____ ______ ______
1 42 40.831 69.093
1 43 40.865 69.034
1 44 40.861 69.039
1 45 40.887 69.043
1 46 40.857 69.045
1 47 40.859 69.07
1 48 40.826 69.189
1 49 40.864 69.655
>> N = max(T.PARTICLE_ID)
N =
5
>> hold on
>> for k = 1:N
Tk = T(T.PARTICLE_ID == k,:);
plot(Tk.X - Tk.X(1), Tk.Y - Tk.Y(1))
end
>> hold off
>> axis equal

  0 Comments

Sign in to comment.


Pier Giorgio Petrolini
Pier Giorgio Petrolini on 25 Nov 2020
Hello Amadeus, I tried to solve your problem in the following way :
1) Convert the dataset in a table;
2) Find all the points of the trajectory of the same particle;
3) Scale all the points of the trajectory ( I assumed the the starting point of the trajectory of a certain particle was the first value recorded of the particle dataset under consideration i don't know if it is a correct assumption but you can easily change it in the code);
4) Plot the scaled values of the trajectory.
% Import the data
testdata = readtable("C:\Users\Client\Downloads\testdata.xlsx", opts, "UseExcel", false)
Clear temporary variables
clear opts
% Count unique values in "PARTICLE_ID" column
n = unique(testdata.PARTICLE_ID)
ParticleNumber = numel(n)
% Plot each scaled trajectory
for i = 1:ParticleNumber
table = testdata(testdata.PARTICLE_ID == i,:); % Isolate single particle trajetory
color = {'k' 'r' 'b' 'g' 'c'};
xmin = table.X(1); % Zero point on x-axis
ymin = table.Y(1); % Zero point on y-axis
table.Scaled_x = table.X-xmin; % Scaled values on x-axis
table.Scaled_y = table.Y-ymin; % Scaled values on y-axis
plot(table.Scaled_x, table.Scaled_y, color{i})
xlabel('x')
ylabel('y')
legend
hold on
end
In the attached file "untitled.1.png" you can find the plot that was generated by this code.
I really hope it helps. Kind regards,
PGP

  0 Comments

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!