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 .







scatter-plot