Azzera filtri
Azzera filtri

How to plot billions of points efficiently?

34 visualizzazioni (ultimi 30 giorni)
I have 3 billions of 2D points to be plotted, which requires a lot of memory. Thus, I can only do this on a server, which has about 1TB memory. But the server does not have a decent graphics card, thus export of figures uses CPU to render and takes more than 5 hours. But this procedure needs to be done many times, because I need to change the scale of axes according to the shape of the scatter diagrams. My desktop has a decent graphics card. Could I utilize the desktop's ability when data can not fit into its memory?
Here is an example of my figures.
  6 Commenti
Stephen23
Stephen23 il 4 Lug 2018
Modificato: Stephen23 il 4 Lug 2018
" In linear scale, it can be easily done by using round(). "
Yes, I also thought of using round, or some kind of tolerance.
"In linear scale, it can be easily done by using round(). But in log scale, I have no clean way to do this. Do you have any idea?"
Convert to linear scale, round to whatever precision, get the unique X-Y pairs, use the indices to plot a subset of the data. I think with a few billion points this might be possible with the memory that you have available, but you would have to try.
Eli4ph
Eli4ph il 4 Lug 2018
@Cobeldick: Thanks. Let me try it.

Accedi per commentare.

Risposta accettata

Stephen23
Stephen23 il 4 Lug 2018
Modificato: Stephen23 il 4 Lug 2018
Here is one way to subsample the data to produce almost identical plots:
% Fake data:
X = 10.^randn(2e4,1);
Y = 10.^randn(2e4,1);
figure()
scatter(X,Y,'filled')
set(gca,'xscale','log','yscale','log','title','AllData')
% Merge data points:
Xb = log10(X);
Yb = log10(Y);
Xf = 0.05; % adjust factor to suit
Yf = 0.05; % adjust factor to suit
Xb = Xf*round(Xb/Xf);
Yb = Yf*round(Yb/Yf);
[~,idx] = unique([Xb,Yb],'rows');
figure()
scatter(X(idx),Y(idx),'filled')
set(gca,'xscale','log','yscale','log','title','SubData')
The number of points plotted:
>> numel(X) % AllData
ans = 20000
>> nnz(idx) % SubData
ans = 6653
You can also see that all extrema are still clearly visible.
PS: you might be able to save some memory by putting the merging onto one line:
[~,idx] = unique([Xf*round(log10(X)/Xf),Yf*round(log10(Y)/Yf)],'rows');

Più risposte (2)

Steven Lord
Steven Lord il 5 Lug 2018
Consider storing your data as a tall array and using the tall visualization capabilities introduced in release R2017b.
  1 Commento
Eli4ph
Eli4ph il 6 Lug 2018
Thanks. I have used the round solution and gained a considerable speedup.

Accedi per commentare.


James Tursa
James Tursa il 5 Lug 2018
  1 Commento
Eli4ph
Eli4ph il 6 Lug 2018
Thanks. I have used the round solution and gained a considerable speedup.

Accedi per commentare.

Categorie

Scopri di più su Line Plots in Help Center e File Exchange

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by