# matlab - xyz - scatter plot

## Visualizzazione di un set di dati 3D di grandi dimensioni con diagramma a dispersione (2)

Non sono sicuro che questo risolverà tutto il problema, ma come primo passo suggerirei di prendere tutti i calcoli dal ciclo utilizzato per disegnare. Ecco un suggerimento su come farlo:

``````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``````

Sto eseguendo una simulazione in MATLAB in cui ho un grande set di dati 3D che cambia ogni passo temporale. Sto provando a visualizzare i dati utilizzando un grafico a dispersione 3D con punti che assumono posizioni, dimensioni, colori e livelli di trasparenza diversi man mano che la simulazione procede. Le informazioni sulla dimensione e sul colore sono ridondanti.

Il rendering e la rotazione della figura in MATLAB sono lenti e instabili. Il mio computer ha una CPU i7-4790 a 4 GHz e una scheda grafica NVIDIA GeForce GTX 750 Ti. Sto usando Matlab R2016a su Windows 7. Ho controllato le mie impostazioni OpenGL MATLAB e il livello di supporto hardware è pieno. (L'hardware OpenGL è necessario per la trasparenza.) Inoltre, sto monitorando l'utilizzo della GPU usando GPU-Z , e durante la stampa e la rotazione, i picchi di carico della GPU sono solo del 25-30%.

Ecco il mio esempio di codice:

``````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``````

e qui c'è un link ai dati . C'è un modo per velocizzare il rendering e rendere la rotazione più fluida? Ho notato che fissare le dimensioni di tutti i punti dati su un singolo scalare accelera notevolmente il rendering e la rotazione. È possibile mantenere la dimensione come è nel codice e mantenere il rendering e la rotazione della figura rapidamente?

Modifica : una domanda correlata che ho postato.

Sembra che la funzione `timer` sia un buon posto per provare in seguito per avere un'idea della progressione della tua simulazione e quindi fare un AVI una volta che sei soddisfatto di come stanno le cose.

MATLAB ha una grande documentazione per questo con una varietà di opzioni per le chiamate consecutive e la spaziatura tra di loro. Controlla le proprietà `ExecutionMode` e `Period` .