2017-08-06 56 views
3

我正在MATLAB中运行一个模拟,其中我有一个可以更改每个时间步的大型3D数据集。我正在尝试使用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的链接。有什么方法可以加速渲染并使轮换更流畅吗?我注意到,将所有数据点的大小固定为单个标量可大大加快渲染和旋转速度。是否有可能保持代码中的大小,并且仍然能够快速渲染和旋转图形?

编辑:A 我发布了。

+0

它是否需要在实时或你可以渲染它作为一个电影(.avi)以后更流畅的播放? – informaton

+0

实时并不是一项要求,但它是首选。 –

+0

我在代码中调用了大约0.5秒的延迟(例如tic/toc)。你现在在做什么? – informaton

回答

1

听起来好像timer函数是一个很好的地方,可以让您了解模拟的进展,然后在您对视觉效果感到满意后再制作AVI。

MATLAB的得到了一些伟大的documentation为它连续调用的各种选项和它们之间的间距。查看ExecutionModePeriod属性。

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