how do i make a plot from a data table with a random number of entries

1 次查看(过去 30 天)
I wrote a little script to make a video for the dynamic of 10 beads connected by springs from a data table.
The data table format:
timestep1 x1 y1 z1 x2 y2 z2 ... x10 y10 z10
timestep2 x1 y1 z1 x2 y2 z2 ... x10 y10 z10
timestep3 x1 y1 z1 x2 y2 z2 ... x10 y10 z10
...
timestep increments with a fixed factor, xi yi zi are the cartesian coordinates of the i. bead wich change with every timestep.
here is the code:
A = readtable('\\wsl$\Debian\home\cpp\traj.txt');
t = A{:,1};
x0 = A{:,2};
y0 = A{:,3};
z0 = A{:,4};
x1 = A{:,5};
y1 = A{:,6};
z1 = A{:,7};
x2 = A{:,8};
y2 = A{:,9};
z2 = A{:,10};
x3 = A{:,11};
y3 = A{:,12};
z3 = A{:,13};
x4 = A{:,14};
y4 = A{:,15};
z4 = A{:,16};
x5 = A{:,17};
y5 = A{:,18};
z5 = A{:,19};
x6 = A{:,20};
y6 = A{:,21};
z6 = A{:,22};
x7 = A{:,23};
y7 = A{:,24};
z7 = A{:,25};
x8 = A{:,26};
y8 = A{:,27};
z8 = A{:,28};
x9 = A{:,29};
y9 = A{:,30};
z9 = A{:,31};
set(gca, 'XLim', [-5 5], 'YLim', [-5 5], 'ZLim', [-5 5]);
view(43,24);
hold on;
for i=1:1000
k = scatter3(x0(i), y0(i), z0(i),'filled','MarkerFaceColor','k');
a = scatter3(x1(i), y1(i), z1(i),'filled','MarkerFaceColor','r');
lx0 = linspace(x0(i),x1(i));
ly0 = linspace(y0(i),y1(i));
lz0 = linspace(z0(i),z1(i));
l0 = plot3(lx0,ly0,lz0);
b = scatter3(x2(i), y2(i), z2(i),'filled','MarkerFaceColor','g');
lx1 = linspace(x1(i),x2(i));
ly1 = linspace(y1(i),y2(i));
lz1 = linspace(z1(i),z2(i));
l1 = plot3(lx1,ly1,lz1);
c = scatter3(x3(i), y3(i), z3(i),'filled','MarkerFaceColor','b');
lx2 = linspace(x2(i),x3(i));
ly2 = linspace(y2(i),y3(i));
lz2 = linspace(z2(i),z3(i));
l2 = plot3(lx2,ly2,lz2);
d = scatter3(x4(i), y4(i), z4(i),'filled','MarkerFaceColor','y');
lx3 = linspace(x3(i),x4(i));
ly3 = linspace(y3(i),y4(i));
lz3 = linspace(z3(i),z4(i));
l3 = plot3(lx3,ly3,lz3);
e = scatter3(x5(i), y5(i), z5(i),'filled','MarkerFaceColor','m');
lx4 = linspace(x4(i),x5(i));
ly4 = linspace(y4(i),y5(i));
lz4 = linspace(z4(i),z5(i));
l4 = plot3(lx4,ly4,lz4);
f = scatter3(x6(i), y6(i), z6(i),'filled','MarkerFaceColor','c');
lx5 = linspace(x5(i),x6(i));
ly5 = linspace(y5(i),y6(i));
lz5 = linspace(z5(i),z6(i));
l5 = plot3(lx5,ly5,lz5);
g = scatter3(x7(i), y7(i), z7(i),'filled','MarkerFaceColor','b');
lx6 = linspace(x6(i),x7(i));
ly6 = linspace(y6(i),y7(i));
lz6 = linspace(z6(i),z7(i));
l6 = plot3(lx6,ly6,lz6);
h = scatter3(x8(i), y8(i), z8(i),'filled','MarkerFaceColor','k');
lx7 = linspace(x7(i),x8(i));
ly7 = linspace(y7(i),y8(i));
lz7 = linspace(z7(i),z8(i));
l7 = plot3(lx7,ly7,lz7);
j = scatter3(x9(i), y9(i), z9(i),'filled','MarkerFaceColor','r');
lx8 = linspace(x8(i),x9(i));
ly8 = linspace(y8(i),y9(i));
lz8 = linspace(z8(i),z9(i));
l8 = plot3(lx8,ly8,lz8);
drawnow
F(i) = getframe(gcf);
pause(0.01);
delete(a);
delete(b);
delete(c);
delete(d);
delete(e);
delete(f);
delete(g);
delete(h);
delete(j);
delete(k);
delete(l0);
delete(l1);
delete(l2);
delete(l3);
delete(l4);
delete(l5);
delete(l6);
delete(l7);
delete(l8);
end
video = VideoWriter('ConnectedBeads.avi', 'Uncompressed AVI');
video.FrameRate = 60;
open(video)
writeVideo(video,F);
close(video)
I'm sure this isnt a very dapper code. How can I improve it so It works for a random number of N beads with a table that looks like:
timestep1 x1 y1 z1 x2 y2 z2 ... x10 y10 z10 ... xN yN zN
timestep2 x1 y1 z1 x2 y2 z2 ... x10 y10 z10 ... xN yN zN
timestep3 x1 y1 z1 x2 y2 z2 ... x10 y10 z10 ... xN yN zN
  1 个评论
KSSV
KSSV 2020-8-5
It looks like you can use gscatter. All at once can be plotted. You have made it complex by taking different number of variables.

请先登录,再进行评论。

采纳的回答

Rik
Rik 2020-8-5
Use arrays instead of numbered variables. You see how this code is much less repeating and easier to see what is happening where?
Because I don't have your data, I didn't test this code.
A = readtable('\\wsl$\Debian\home\cpp\traj.txt');
t = A{:,1};
x = A(:,2:3:end); x=cell2mat(x);
y = A(:,3:3:end); y=cell2mat(y);
z = A(:,4:3:end); z=cell2mat(z);
%create a clean figure and axis with handles
f=figure(1);clf(1)%you could also do f=figure; instead
ax=axis('Parent',f,...
'XLim', [-5 5], 'YLim', [-5 5], 'ZLim', [-5 5],...
'NextPlot','add');
view(43,24);
%how are you making sure you never run out of colors?
%consider either not explicitly choosing colors yourself, or using ColorList{mod(bead,end-1)+1}
ColorList={'k','r','g','b','y','m','c','b','k','r'};
h=[];
for bead=1:size(x,2)
%initialize all bead plots
h.scatter(bead) = scatter3(x(1,bead), y(1,bead), z(1,bead),...
'filled','MarkerFaceColor',ColorList{bead});
lx0 = linspace(x(1,bead),x(1,bead));
ly0 = linspace(y(1,bead),y(1,bead));
lz0 = linspace(z(1,bead),z(1,bead));
h.plot(bead) = plot3(lx0,ly0,lz0);
end
%initialize F properly here
for timestamp=1:numel(t)
for bead=1:size(x,2)
%update the XData,YData,ZData properties instead of deleting everything, which can now do with delete(h.plot),delete(h.scatter)
end
drawnow
F(timestamp) = getframe(f);
end
  3 个评论
Rik
Rik 2020-8-5
First a little housekeeping: This time I edited your post for you. Next time, please use the tools explained on this page to make your post more readable. If you feel my answer solved your issue, please mark it as accepted answer.
The easiest way to make sure your data is an array, is to load it as an array, e.g. with A=readmatrix('traj.txt','NumHeaderLines',0);.
To avoid indexing errors in your last iteration, you can replace bead+1 by min(bead+1,end).
moritz123
moritz123 2020-8-6
"Use arrays instead of numbered variables." was definetly the right answer. Again, thank you!
Here my solution with arrays that gets the job done:
A = readtable('\\wsl$\Debian\home\cpp\traj.txt');
time = A{:,1};
%using arrays
x = A(:,2:3:end);
x= table2array(x);
y = A(:,3:3:end);
y= table2array(y);
z = A(:,4:3:end);
z= table2array(z);
set(gca, 'XLim', [-40 45], 'YLim', [-40 50], 'ZLim', [-40 45]);
view(25,-25);
hold on;
h=[];
l =[];
for t =1:length(time)
for bead=1:size(x,2)-1
h(bead) = scatter3(x(t,bead), y(t,bead), z(t,bead),'filled','MarkerFaceColor','b');
lx = linspace(x(t,bead),x(t,bead + 1));
ly = linspace(y(t,bead),y(t,bead + 1));
lz = linspace(z(t,bead),z(t,bead + 1));
l(bead) = plot3(lx,ly,lz);
end
h(size(x,2)) = scatter3(x(t,size(x,2)), y(t,size(x,2)), z(t,size(x,2)),'filled','MarkerFaceColor','b');
drawnow
F(t) = getframe(gcf);
pause(0.01);
delete(h);
delete(l);
end
video = VideoWriter('100Beads.avi', 'Uncompressed AVI');
video.FrameRate = 60;
open(video)
writeVideo(video,F);
close(video)

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Language Support 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by