change color data of fill3 object
9 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Nathaniel Wood
am 11 Nov. 2020
Kommentiert: Nathaniel Wood
am 11 Nov. 2020
Hello everyone,
I am running into an issue with the fill3 command. In summary, I am trying to redraw a large fill3 object as part of an animation. However, the procedures I've thought of for doing this are very slow. I am not sure if this is because I am misunderstanding how data is stored in the fill3 object, and there could be a faster way of performing this operation that I am unaware of. My question is elaborated on below.
I have a 3D mesh, stored in the arrays X, Y, and Z. Each of X, Y, and Z are (3 x N) arrays, where N is the number of (triangular) polygons in the 3D mesh. I've computed a sequence of colormaps for this mesh for time steps tt = 1 through Lt. These colormaps are stored in a (1 x Lt) cell array, Color, where each element of Color is a (3 x N) array that stores the color value at each node in the mesh. I would like to animate the color evolution on the mesh, with something like the following code:
figure;
tt=1;
fig1=fill3(X,Y,Z,Color{tt}); colorbar;
xlabel('X'); ylabel('Y'); zlabel('Z'); title(['Colormap, tt =',num2str(tt),' of ',num2str(Lt)]);
drawnow nocallbacks
movie(tt)=getframe(gcf);
for tt=2:Lt
fig1.FaceVertexCData=Color{tt};
title(['Colormap, tt =',num2str(tt),' of ',num2str(Lt)]);
drawnow nocallbacks
movie(tt)=getframe(gcf);
end
The command
fig1.FaceVertexCData=Color{tt};
Comes from the documentation of fill3, which states that the fill3 command creates a patch object. FaceVertexCData is the property I use to change the vertex-wise color data for patch objects in other contexts. However, this procedure fails. MATLAB returns the error message "Expected one output from a curly brace or dot indexing expression, but there were N results." I have came up with two possible workarounds to this solution:
- Redraw the figure at each time step
figure;
tt=1;
fig1=fill3(X,Y,Z,Color{tt}); colorbar;
xlabel('X'); ylabel('Y'); zlabel('Z'); title(['Colormap, tt =',num2str(tt),' of ',num2str(Lt)]);
drawnow nocallbacks
movie(tt)=getframe(gcf);
for tt=2:Lt
clf;
fig1=fill3(X,Y,Z,Color{tt}); colorbar;
xlabel('X'); ylabel('Y'); zlabel('Z'); title(['Colormap, tt =',num2str(tt),' of ',num2str(Lt)]);
drawnow nocallbacks
movie(tt)=getframe(gcf);
end
2. Set the CData in an inner loop
figure;
tt=1;
fig1=fill3(X,Y,Z,Color{tt}); colorbar;
xlabel('X'); ylabel('Y'); zlabel('Z'); title(['Colormap, tt =',num2str(tt),' of ',num2str(Lt)]);
drawnow nocallbacks
movie(tt)=getframe(gcf);
for tt=2:Lt
tempcolor=Color{tt};
for ii=1:N
fig1(ii).FaceVertexCData=tempcolor(:,ii);
end
title(['Colormap, tt =',num2str(tt),' of ',num2str(Lt)]);
drawnow nocallbacks
movie(tt)=getframe(gcf);
end
Option 1 is obviously a very inefficient way to redraw the figure, however, because I have large N (N>10,000), implementing the inner loop of Option 2 means that Option 2 is not much faster. Both ways are very slow. I am writing this to ask if I am missing a more efficient way of performing this operation, based on an incomplete understanding of how to manipulate data stored in these objects. My thanks for any clarification that you can provide!
0 Kommentare
Akzeptierte Antwort
Walter Roberson
am 11 Nov. 2020
fig1.FaceVertexCData=Color{tt};
When you use the setup you describe, then fig1 is an array of N patch objects, so fig1.FaceVertexCData is designating multiple output locations.
In the setup you describe, each of those N patch objects will have a FaceVertexCData property that is a 3 x 1 vector.
With each Color{tt} being a 3 x N array, do this:
for tt=2:Lt
C = num2cell(Color{tt}, 1);
[fig1.FaceVertexCData] = C{:}; %equivalent to deal()
title(['Colormap, tt =',num2str(tt),' of ',num2str(Lt)]);
drawnow nocallbacks
movie(tt)=getframe(gcf);
end
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Animation finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!