我正在MATLAB中运行模拟,其中我有一个大的3D数据集,可以更改每个时间步。我正在尝试使用3D散点图来显示数据,其中点随着模拟的进行呈现不同的位置,大小,颜色和透明度级别。尺寸和颜色信息是多余的。
在MATLAB中渲染和旋转图形是缓慢且不连贯的。我的电脑配有4 GHz i7-4790 CPU和NVIDIA GeForce GTX 750 Ti显卡。我在Windows 7上使用Matlab R2016a。我检查了我的MATLAB OpenGL设置,硬件支持级别已满。 (硬件OpenGL是透明度所必需的。)此外,我正在使用GPU-Z监控我的GPU使用情况,并且在绘图和旋转期间,GPU负载峰值仅为25-30%。
这是我的代码示例:
load sample_data2
channels_matrix = cat(1, channels{:});
num_channels = length(channels);
channel_lengths = cellfun(@(x) size(x, 1), channels);
figure(1);
for i = 1:num_channels
g = plot3(channels{i}(:, 1), channels{i}(:, 2), channels{i}(:, 3), 'k');
set(g, 'LineWidth', 1.5)
hold on;
text(channels{i}(1, 1), channels{i}(1, 2), channels{i}(1, 3), num2str(i))
end
caxis([0 1])
colorbar
drawnow
numDivisions = 8;
ptsPerDivision = numel(grid_x)/numDivisions;
T = 1000;
numplotpts = 2E4;
for t = 1:T
plot_signal = nan(size(grid_x));
plot_signal(sort(randsample(numel(grid_x), numplotpts))) =...
sort(rand(numplotpts, 1));
tic
for i = 1:numDivisions
temp = plot_signal(dists_idx((i-1)*ptsPerDivision+1:i*ptsPerDivision));
yplot = grid_y(dists_idx((i-1)*ptsPerDivision+1:i*ptsPerDivision));
xplot = grid_x(dists_idx((i-1)*ptsPerDivision+1:i*ptsPerDivision));
zplot = grid_z(dists_idx((i-1)*ptsPerDivision+1:i*ptsPerDivision));
if t == 1
h(i) = scatter3(yplot(~isnan(temp)), xplot(~isnan(temp)),...
zplot(~isnan(temp)), 50*temp(~isnan(temp)), temp(~isnan(temp)), ...
'filled', 'MarkerFaceAlpha', exp(-i)^0.25);
else
h(i).XData = yplot(~isnan(temp));
h(i).YData = xplot(~isnan(temp));
h(i).ZData = zplot(~isnan(temp));
h(i).SizeData = 50*temp(~isnan(temp));
h(i).CData = temp(~isnan(temp));
end
end
drawnow
toc
end
这是指向data的链接。有没有办法加快渲染速度并使旋转更平滑?我注意到将所有数据点的大小固定为单个标量会大大加快渲染和旋转速度。是否可以保持代码中的大小,并且仍然可以快速渲染和旋转图形?
修改:我发布的related question。
答案 0 :(得分:1)
听起来timer
函数是下一个尝试的好地方,以便了解模拟的进展,然后在对事物的外观感到满意后再制作AVI。
MATLAB为它提供了一些很棒的documentation,它有多种连续调用选项以及它们之间的间距。查看ExecutionMode
和Period
属性。
答案 1 :(得分:0)
我不确定这会解决所有问题,但作为第一步,我建议将所有计算从用于绘图的循环中取出。以下是建议:
load sample_data2
clf
channels_matrix = cat(1, channels{:});
num_channels = length(channels);
channel_lengths = cellfun(@(x) size(x, 1), channels);
figure(1);
for k = 1:num_channels
g = plot3(channels{k}(:, 1), channels{k}(:, 2), channels{k}(:, 3), 'k');
set(g, 'LineWidth', 1.5)
hold on;
text(channels{k}(1, 1), channels{k}(1, 2), channels{k}(1, 3), num2str(k))
end
caxis([0 1])
colorbar
drawnow
numDivisions = 8;
ptsPerDivision = numel(grid_x)/numDivisions;
T = 1000;
numplotpts = 2E4;
% -> chnages starts here:
% first loop for creating random indices
plot_signal = nan(size(grid_x));
rand_numplotpts =sort(rand(numplotpts,T),1);
rand_inds = zeros(numplotpts,T);
for t = 1:T % one loop for creating random indices
rand_inds(:,t) = sort(randperm(numel(grid_x),numplotpts));
end
plot_signal(rand_inds(:,t)) = rand_numplotpts(:,t);
% second loop for drawing the first instance:
for k = 1:numDivisions
temp = plot_signal(dists_idx((k-1)*ptsPerDivision+1:k*ptsPerDivision));
yplot = grid_y(dists_idx((k-1)*ptsPerDivision+1:k*ptsPerDivision));
xplot = grid_x(dists_idx((k-1)*ptsPerDivision+1:k*ptsPerDivision));
zplot = grid_z(dists_idx((k-1)*ptsPerDivision+1:k*ptsPerDivision));
h(k) = scatter3(yplot(~isnan(temp)), xplot(~isnan(temp)),...
zplot(~isnan(temp)), 50*temp(~isnan(temp)), temp(~isnan(temp)), ...
'filled', 'MarkerFaceAlpha', exp(-k)^0.25);
end
% third loop to calculate all timesteps:
[X,Y,Z,S,C] = deal(nan(size(temp,1),numDivisions,T));
for t = 2:T
plot_signal(rand_inds(:,t)) = rand_numplotpts(:,t);
for k = 1:numDivisions
temp = plot_signal(dists_idx((k-1)*ptsPerDivision+1:k*ptsPerDivision));
yplot = grid_y(dists_idx((k-1)*ptsPerDivision+1:k*ptsPerDivision));
xplot = grid_x(dists_idx((k-1)*ptsPerDivision+1:k*ptsPerDivision));
zplot = grid_z(dists_idx((k-1)*ptsPerDivision+1:k*ptsPerDivision));
non_nan_inds = ~isnan(temp);
inds = 1:sum(non_nan_inds);
X(inds,k,t) = yplot(non_nan_inds);
Y(inds,k,t) = xplot(non_nan_inds);
Z(inds,k,t) = zplot(non_nan_inds);
S(inds,k,t) = 50*temp(non_nan_inds);
C(inds,k,t) = temp(non_nan_inds);
end
end
% forth loop to draw all data:
for t = 2:T
for k = 1:numDivisions
h(k).XData = Y(:,k,t);
h(k).YData = X(:,k,t);
h(k).ZData = Z(:,k,t);
h(k).SizeData = S(:,k,t);
h(k).CData = C(:,k,t);
drawnow
end
end