2017-04-23 66 views
0

我想要做的是獲取點(x,y,z),散點圖上的單個「單元格」(有9個不同的單元格:c = 1,...,9),並且t =時間,並且由此創建隨着時間的變化而不斷更新的分散體3。由於散點圖上每個點的t從0開始,因此散點圖上始終應該有9個點。到目前爲止,我所寫的是下面的代碼,它將列表變成一個矩陣,並根據t的當前值和最後一個值按順序連續繪製每個點(不管c值)。隨着時間更新的3D scatterplot:MATLAB

x=['x axis points']; 
y=['y axis points']; 
z=['z axis points']; 
c=[1,1,1,1,1,2,2,2,2,3,3,3,3....8,8,8,8,8,8,8,9,9,9,9,9,9,9]; %cells 
t=[0,1,2,3,4,0,1,2,3,0,1,2,3,,,,0,1,2,3,4,6,7,0,4,6,9,10,12,14]; %time resetting at 0 for each cell 

mat=cell2mat({[x;y;z;c;t]}); %Convert cells into a matrix 

scatter3(mat(1,2),mat(1,3),mat(1,4),100); 
axis tight; 

for jj=1:numel(mat(5,:)) %loops through for length of 5th row 
scatter3(mat(1,jj),mat(2,jj),... 
    mat(3,jj),100);  %plots point at t(x,y,z) w/ no regard to c 
drawnow 
if(jj>1 && mat(5,jj-1)>0) 
    pause(mat(5,jj)-mat(5,jj-1)) %waits for difference in last two times if not 0 
else 
    pause(1) %otherwise pause a second 
end 
end 

我需要做的第一件事是修改環路,使得每個散射點被繪製換每個C在時間t情節其點在對應(X,Y,Z)。

  • 算法幫助將是不錯的,我沒有使用MATLAB多年,我的算法技能生疏:可這跟一個for循環來完成,我應該根據時間基於C再拆矩陣排序?

接下來,我需要隨着時間的推移

  • 找出一種方法來更新點是值得嘗試計算各點之間的3D距離,並把它「滑」它的目的地逐漸或者這將是非常困難的MATLAB?如果兩點同時在兩個非常不同的地方,那麼這將如何與邊界一起工作?這個數字是否在MATLAB中自動縮放?

一旦我有一個顯示所有點流體足夠的算法,我可以使用代碼從這個變成一個視頻:https://www.youtube.com/watch?v=nnkTSX5U_a4

如果有人在動畫這樣的數據,請您分享一些提示或有幫助的位智慧碼。我有一些編程背景,但不是在表現這樣的數據,所以我發現容易的東西是扔我循環,對不起,如果這篇文章非常n00bish。

示例數據:

x=[-213.135 -217.261 -220.636 -225.325 -227.763 -232.826 -236.389 -239.577 
-238.827 -242.39]; 
y=[92.081 90.955 88.892 86.83 84.767 82.891 84.392 80.453 75.765 
73.327]; 
z=[60 70 70 80 90 90 90 90 90 100]; 
c=[1 1 1 1 1 1 1 1 1 1]; 
t=[0 1.008566667 2.017133333 3.025716667 4.034283333 5.04285 6.051416667 
7.059983333 8.068566667 9.077133333]; 
+0

請包括例如'x','y'和'z'數據,讓您現有的代碼可以運行,以便更好地理解你的問題 – Wolfie

+0

@Wolfie我從我的數據中添加了前10個數字,c = 1表示它們是同一個單元格。要一次繪製多個點,只需複製這些數據並將c值更改爲2,3,4 ...並更改其中一個x,y,z值,以便它們不會相互繪製,則時間間隔爲對於我剛剛意識到的每一個都是一樣的,所以程序可以同時更新每個點。 –

回答

0

下面我發佈代碼的兩種方法,第二個建立在第一次給你想要的結果。


設置

您最初的問題是,你的數據是所有行向量。讓我們xyz成矩陣與各行的不同c「彈道」,使用reshape

x = reshape(x, [], 9); % Makes x a 9 row matrix, assuming number of elements divisible by 9 

其他功能,這將使你的時機更容易處理的diff。這簡直是​​一個矢量相鄰點之間的差別,用它來獲得dt

dt = [1, diff(t)]; % The 1 is needed as numel(diff(t)) = numel(t) - 1 

現在你可以使用這些初始化數據:

% x,y and z are 10*9=90 element matrices, representing 9 trajectories. 
% For real data, don't use REPMAT, use actual matrix. If data is just a 
% 90 element row vector, use RESHAPE to split into 9 rows. 
x = repmat([-213 -217 -220 -225 -227 -232 -236 -239 -238 -242], 9, 1); 
y = repmat([92.1 91.0 88.9 86.8 84.8 82.9 84.4 80.5 75.8 73.3], 9, 1); 
z = repmat([60 70 70 80 90 90 90 90 90 100], 9, 1); 
t = [0 1.0085 2.0171 3.0257 4.0342 5.0428 6.0514 7.0599 8.0685 9.0771]; 
dt = [1, diff(t)]; dt(dt < 0) = 1; % Initialise dt, setting negative values to 1. 

n = size(x,2); 
% Offset z by row number. This wouldn't be needed with actual data. 
% c is the trajectory number (1 - 9) 
c = repmat((1:9)', 1, n); 
z = z - 5*c; 
% Get axes limits, so they can be kept constant for the animation 
lims = [min(x(:)), max(x(:)), min(y(:)), max(y(:)), min(z(:)), max(z(:))]; 

繪製粗糙的動畫 - 後運行「設置」 代碼

% Plot actual points 
figure; 
for jj = 1:n   % Loop through all points in rows 
    clf;    % Clear figure and hold on for multiple plots 
    for ii = 1:9  % Loop over trajectories (rows) 
     hold on; 
     plot3(x(ii,jj), y(ii,jj), z(ii,jj), 'o'); % Plots point at x(t), y(t), z(t) 
     drawnow; 
     hold off; view(-37.5, 30) % Hold off and set default 3D viewpoint 
     axis(lims); grid on; 
    end 
    pause(dt(jj))  
end 

使用跟蹤線繪製平滑動畫 - 在「設置」代碼後運行

您希望讓點「滑動」。最簡單的方法是使用interp1爲您插入點,然後像以前一樣繪製它們。在這個例子中,我還繪製了 「歷史性」 的數據線

pts = 100;        % Number of points (more is smoother) 
x = interp1(1:n, x', linspace(1,n,pts))'; % Make x,y,z,t into pts number of points 
y = interp1(1:n, y', linspace(1,n,pts))'; 
z = interp1(1:n, z', linspace(1,n,pts))'; 
t = interp1(1:n, t, linspace(1,n,pts)); 
dt = max(1/pts, [1/pts, diff(t)]);  % Set dt as positive time diff 

% Plot smooth version, with trajectory lines 
% Set up colours matrix so that plots points/lines can be the same colour 
clrs = [linspace(0.4,0.8,9)', linspace(0.6,0.1,9)', linspace(0,0.5,9)']; 
figure; 
for jj = 1:pts   % Loop through all points in rows 
    clf;    % Clear figure and hold on for multiple plots 
    for ii = 1:9  % Loop over trajectories (rows) 
     hold on; 
     plot3(x(ii,jj), y(ii,jj), z(ii,jj), 'o', 'color', clrs(ii,:)); % Plots point at x(t), y(t), z(t) 
     plot3(x(ii,1:jj), y(ii,1:jj), z(ii,1:jj), '-', 'color', clrs(ii,:)); % Plot lines from T = 0 to T = t 
     drawnow; 
     hold off; view(-37.5, 30) % Hold off and set default 3D viewpoint 
     axis(lims); grid on; 
    end 
    pause(dt(jj))  
end 

結果(最後圖):

plot


軸限制

上面,我有固定座標軸限制,以使它們在整個動畫中保持不變,並適合所有點。你可以讓它們自動使用

axis auto 

但是,這會讓你的動畫看起來非常激動!


拍電影

您可能會發現在文件中的此項交易是有用的,它表明生成使用imwrite一個GIF /電影,看起來很簡單。我沒有測試此,請參閱「示例」選項卡上的信息:

https://uk.mathworks.com/matlabcentral/fileexchange/21944-animated-gif

+0

謝謝!還沒有測試,但一個非常詳細的答案,這無疑會給我很多工作與 –

+0

不用擔心@邁克,讓我知道如果你有進一步的問題。乾杯 – Wolfie