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

7 次查看(过去 30 天)
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 个评论
Pier Giorgio Petrolini
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

请先登录,再进行评论。

采纳的回答

Star Strider
Star Strider 2020-11-25
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.
.
  5 个评论
ADJE JEREMIE ALAGBE
编辑:ADJE JEREMIE ALAGBE 2021-7-20
Hello, @Star Strider, thanks a lot for your comment.
To get things more clear, I have attached now the original file (rawdata.xlsx). From the dataset in this file, you can now understand how the vehicle IDs as well as their trajectory data were stored. Actually, at each second of time the information about all vehicles in the detection area were stored in one row, with an ID for each vehicle, starting from 1. One can observe that in the first row, on 2021/5/15 0:00:00.599, two vehicles were present at the detection area, one with ID=6 and the second with ID=1. At the next second, still the two vehicles in area, but at the third second 2021/5/15 0:00:02.626 the number of vehicles became three, with a new vehicle entered the detection area (ID=11), and at 2021/5/15 0:00:03.644 the number became four (a new vehicle was added with ID=12), and so on vehicles enter and leave the detection area one after another from different lane (YPos). The ID was given to each vehicle, starting from 1 for the first vehicle detected, and when the number reaches 255, the system begins the numbering of the next vehicles from 1 again, and follows that periodical numbering.
"N' in my code bellow is the maximum ID number, which is 255, (N = max(T.ID)).
The second plot differs from the first plot in that the plot I should get after plotting the whole data of one-day recording, should look like the second plot one (in where we can see clearly trajectories are only grouped by the road lanes), but not like the first plot (where although trajectories were grouped by road lanes, but there were also other zigzag or diagonal lines that I guess were the effect of the repeated plotting of peiodically same IDs that actually are not same vehicles)
For the consistency of the ‘ID’ values, we can't expect to have equal numbers of the different ‘ID’ values, because for example a vehicle that was detected at the previous second can be lost at the next second, although it's still in the detection area, but was hided behind a truck, so the number of times a vehicle is detected can differ from one another.
I really hope this explanation could make the issue more clear so that you can offer more help. Thanks again!

请先登录,再进行评论。

更多回答(2 个)

Steve Eddins
Steve Eddins 2020-11-25
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
  1 个评论
ADJE JEREMIE ALAGBE
编辑:ADJE JEREMIE ALAGBE 2021-7-20
I have a dataset that seems to have some similarities with @Amadeus Xu's dataset, but when I tried to apply @Star Strider and @Steve Eddins's solutions to my dataset it works but there were also some excessive lines that should not be present in the plot, so I guess I still need some additional line of code to make it perfetct.
The dataset is attached in excel file 15_device76.xlsx. It's a set of data collected at an approach of a freeway intersection by a radar detector. It has 9 columns as follows: deviceno (the number given to each device, radar, here there is only one radar which is numbered 76), timestamp (at every second, the radar detects all vehicles in the detection area and collects their information, including each vehicle's position, speed, and attributes an id to each vehicle, which means same instant or timestamp can contain many vehicles, and a same vehicle can be detected in the next second and so on if it's still in the detection area), unixtime, ID (each vehicle is given an id by the radar; the vehicles are circularly number from 1 to 255, which means after the number reaches 255 it restarts numbering the following vehicles from 1 to 255, and so on), Length (vehicle length), YPos (the vehicle's Y-coordinate in the radar coordinate system, with radar as origin), XPos (the vehicle's X-coordinate), YSpeed (the vehicle's speed in Y-direction), and XSpeed (the vehicle's speed in X-direction). The following image is the plot I got.
I tried to take a single range of the dataset that now only contains the firt 1-255 range of vehicle ID trajectories data (see attached 15_device76_1.xlsx file) and plot it by using the fllowing code from @Steve Eddins:
T = readtable('15_device76_1.xlsx');
N = max(T.ID)
hold on
for k = 1:N
Tk = T(T.ID == k,:);
plot(Tk.yPos, Tk.XPos)
end
hold off
xlabel('y')
ylabel('x')
It works perfectly as you can see in the image bellow, however I don't know how to continue plotting all other successive 1-255 ranges on the same plot, as my original file contains a very large amount of vehicle trajectory data to visualize. This is the issue I'm facing.
I would greatly appreciate a solution from you to my problem. Thank you all in advance!

请先登录,再进行评论。


Pier Giorgio Petrolini
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

Community Treasure Hunt

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

Start Hunting!

Translated by