change color data of fill3 object
9 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Walter Roberson
2020-11-11
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
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!