2010-11-06 15 views
7

Chodzi o to, jak MATLAB może zająć bardzo różne czasy, aby narysować to samo - i dlaczego.MATLAB scatter3, plotowanie z szybkością plotowania

generowania 10000 punktów w przestrzeni 3D:

X = rand(10000, 1); 
Y = rand(10000, 1); 
Z = rand(10000, 1); 

Następnie stosuje się jedną z czterech różnych metod wykreślić to, aby utworzyć wykres tak:

alt text

I nieczynna i wyczyścił przestrzeń roboczą między każdym biegiem, aby zapewnić sprawiedliwość.

Luzem kreślenie za pomocą scatter3:

>> tic; scatter3(X, Y, Z); drawnow; toc 
Elapsed time is 0.815450 seconds. 

indywidualna kreślenie za pomocą scatter3:

>> tic; hold on; 
for i = 1:10000 
    scatter3(X(i), Y(i), Z(i), 'b'); 
end 
hold off; drawnow; toc 
Elapsed time is 51.469547 seconds. 

Luzem kreślenie za pomocą Plot3:

>> tic; plot3(X, Y, Z, 'o'); drawnow; toc 
Elapsed time is 0.153480 seconds. 

Indywidualne kreślenia przy użyciu Plot3:

>> tic; hold on 
for i = 1:10000 
    plot3(X(i), Y(i), Z(i), 'o'); 
end 
drawnow; toc 
Elapsed time is 5.854662 seconds. 

Co to jest, że MATLAB robi za kulisami w „dłuższe” rutyny do podjęcia tak długo? Jakie są zalety i wady stosowania każdej metody?

Edit: Dzięki poradę Ben Voigt (patrz odpowiedź), mam włączone drawnow komendy w przejściowymi - ale to uczynił małą różnicę czasów.

+0

Wprowadzono niewielką różnicę? Czas na masę 'plot3' wzrósł o trzy rzędy wielkości! –

Odpowiedz

6

Główna różnica między czasem potrzebnym do uruchomienia scatter3 a plot3 jest kompilowana, podczas gdyjest interpretowana (jak zobaczysz podczas edycji funkcji). Jeśli skompilowano również scatter3, różnica prędkości byłaby niewielka.

Główna różnica między czasem wymaganym do wykreślenia w pętli a wykreślaniem za jednym razem jest to, że dodajesz uchwyt do wykresu jako element potomny do osi (spójrz na dane wyjściowe get(gca,'Children')), a Ty " w ten sposób rośnie skomplikowana tablica wewnątrz pętli, o której wszyscy wiemy, że jest wolna. Co więcej, wywołujesz kilka funkcji często zamiast raz i ponoszenia w ten sposób wywołań z funkcji narzut.

Ponowne obliczenie limitów osi nie stanowi tutaj problemu. Jeśli prowadzisz

for i = 1:10000 
    plot3(X(i), Y(i), Z(i), 'o'); 
    drawnow; 
end 

co zmusza Matlab zaktualizować rysunek po każdej iteracji (i która jest dużo wolniejsze), zobaczysz, że limity osie w ogóle nie zmieniać (ponieważ domyślne limity są osie 0 i 1). Jednak nawet jeśli limity osi zaczynałyby się inaczej, nie wymagałoby to wielu powtórzeń, aby zbiegały się z tymi danymi. Porównaj z pominięciem hold on, co powoduje, że kreślenie trwa dłużej, ponieważ osie są przeliczane na każdym kroku.

Dlaczego te różne funkcje? scatter3 umożliwia rysowanie punktów o różnych rozmiarach znaczników i kolorach pod jednym uchwytem, ​​podczas gdy potrzebujesz pętli i uchwyt dla każdego punktu przy użyciu plot3, który jest nie tylko kosztowny pod względem szybkości, ale także pod względem pamięć. Jeśli jednak chcesz interakcję z różnymi punktami (lub grupami punktów) indywidualnie - może chcesz dodać oddzielny wpis legendy dla każdego, może chcesz móc je włączać i wyłączać osobno itd. - używając plot3 w pętli może być najlepszym (choć powolnym) rozwiązaniem.

+0

Dzięki, to naprawdę wyjaśniło problemy związane z różnicami prędkości, szczególnie w tym, co dzieje się za kulisami. –

4

Cóż, jeśli chcesz kontrolować kolor każdego punktu, rozrzut masowy będzie szybszy, ponieważ musisz wywołać wykres oddzielnie.

Ponadto nie jestem pewien, czy informacje dotyczące czasu są dokładne, ponieważ użytkownik nie zadzwonił pod numer drawnow, więc rzeczywisty rysunek może mieć miejsce po toc.

Podsumowując:

  • plot3 jest najszybszy, ponieważ zwraca ten sam znacznik w wielu różnych miejscach
  • scatter3 przyciąga wielu różnych znaczników, ponieważ rozmiar i kolor markera (wolno) zmieniają się z każdym punkt
  • wywoływanie w pętli jest bardzo powolne, ponieważ przetwarzanie argumentów i tak dalej musi odbywać się wielokrotnie, dodatkowo jako punkty dodawane do wykresu, osie muszą być ponownie obliczone
+0

To bardzo interesujące - podobnie jak MATLAB tworzy fabułę losowo po tym, jak zostali nazwani? Znowu, dlaczego? Co MATLAB robi w swoim kodzie, aby to spowodować? –

+0

Mam teraz zaktualizowany czas na twoją radę tutaj. Dzięki. –

+0

Prawie wszystkie programy GUI wykreślają rzeczy tylko wtedy, gdy otrzymają żądanie malowania z systemu operacyjnego. To jest naprawdę bardzo dobra rzecz. Zauważyłem, że używasz automatycznych osi, więc wersja 'hold on' oblicza jedną skalę osi dla pierwszego punktu, nową skalę osi po dodaniu następnego punktu i dostosowuje osie ponownie za każdym razem, gdy dodajesz nowy punkt, który nie mieści się w poprzednio wykreślonych punktach. Jeśli byłaby natychmiast renderowana, musiałaby rysować osie, tyknięcia, tytuły itd. Setki razy zamiast raz. Można też zminimalizować lub zakryć okno rysunku. –

6

Dla szybszego podejścia, należy rozważyć tę trzecią opcję (bezpośrednio wykorzystuje funkcję linii niskiego poziomu):

line([X,X], [Y,Y], [Z,Z], 'LineStyle','none', 'Marker','o', 'Color','b') 
view(3) 

Oto kilka artykułów na temat kreślenia problemy z wydajnością:

+5

Oprócz artykułów wymienionych na UndocumentedMatlab.com, zwróć uwagę na następujący artykuł wyjaśniający, że funkcja rozpraszania działa nieoczekiwanie, gdy zażądano jej wykreślenia ponad 100 punktów danych: http: // UndocumentedMatlab.com/blog/undocumented-scatter-plot-behaviour / –