matlab - titulo - Visualización de grandes conjuntos de datos 3D con diagrama de dispersión
superponer graficas en matlab (2)
No estoy seguro de que esto resuelva todo el problema, pero como primer paso sugeriría sacar todos los cálculos del ciclo que se usa para dibujar. Aquí hay una sugerencia de cómo hacerlo:
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
Estoy ejecutando una simulación en MATLAB en la que tengo un gran conjunto de datos en 3D que cambia cada paso de tiempo. Intento visualizar los datos usando un diagrama de dispersión 3D con puntos que toman diferentes ubicaciones, tamaños, colores y niveles de transparencia a medida que avanza la simulación. La información de tamaño y color son redundantes.
Renderizar y girar la figura en MATLAB es lento y agitado. Mi computadora tiene una CPU i7-4790 a 4 GHz y una tarjeta gráfica NVIDIA GeForce GTX 750 Ti. Estoy usando Matlab R2016a en Windows 7. Revisé mi configuración de MATLAB OpenGL y el nivel de soporte de hardware está lleno. (El hardware OpenGL es necesario para la transparencia.) Además, estoy monitoreando el uso de mi GPU usando GPU-Z , y durante el trazado y la rotación, la carga de la GPU alcanza su máximo en solo 25-30%.
Aquí está mi ejemplo de código:
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
y aquí hay un enlace a los datos . ¿Hay alguna forma de acelerar el renderizado y hacer que la rotación sea más suave? Noté que al fijar el tamaño de todos los puntos de datos en un solo escalar se acelera enormemente la renderización y la rotación. ¿Es posible mantener el tamaño tal como está en el código y aún así tener la figura renderizada y rotar rápidamente?
Editar : una pregunta relacionada que publiqué.
Parece que la función del timer
es un buen lugar para probar a continuación con el fin de obtener una idea de la progresión de su simulación y luego hacer un AVI una vez que esté satisfecho con el aspecto de las cosas.
MATLAB tiene una gran documentación para ello con una variedad de opciones para hacer llamadas consecutivas y el espacio entre ellas. Consulte las propiedades ExecutionMode
y Period
.