2017-08-06 111 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