matlab: scatter plots with high number of datapoints

18,123

Solution 1

You can use plot, but then all points have the same color. However, you can divide the set in different subsets and plot them each with their own color:

N = 100000;
x = rand(N,1);
y = rand(N,1);
C = sin(2*x)+y;

cdivs = 10;
[~, edges] = hist(C,cdivs-1);
edges = [-Inf edges Inf]; % to include all points
[Nk, bink] = histc(C,edges);

figure;
hold on;
cmap = jet(cdivs);
for ii=1:cdivs
    idx = bink==ii;
    plot(x(idx),y(idx),'.','MarkerSize',4,'Color',cmap(ii,:));
end

colormap(cmap)
caxis([min(C) max(C)])
colorbar

enter image description here

which responds already a lot better than scatter(x,y,1,C) which gives about the same plot, but with higher color resolution (which is adjustable in my code above).

Solution 2

My experience is that the most efficient plotting command in matlab is Patch, and I have used it to emulate the functionality of scatter or scatter3 with much higher efficiency.

If you have a list of points, use each point to define a square patch (or octagons, or whatever) of reasonable edge length for your particular data, then plot the collection of patches with a single call to patch. After the graphic object is created, you can update its color data to individually color the squares.

You can use the same concept in 3D by building cubes or 3D crosses from your data set.

This snippet creates 1e5 randomly placed squares, with random colors in this case and runs in a little under a second on my four year old laptop. A similar call to scatter takes 40 seconds, and returns an unwieldy figure that is hard to manipulate.

tic
P=rand(1e5,2);
Edge=.01;
X=[P(:,1)'; P(:,1)'+Edge; P(:,1)'+Edge; P(:,1)'];
Y=[P(:,2)'; P(:,2)'; P(:,2)'+Edge; P(:,2)'+Edge];
figure;
h=patch(X,Y,'r');
set(h,'facevertexcdata',rand(size(X,2),3),'facecolor','flat','edgecolor','none')
drawnow
toc
Share:
18,123

Related videos on Youtube

Art
Author by

Art

Updated on June 05, 2022

Comments

  • Art
    Art almost 2 years

    I'm trying to plot scatter, something like:

    scatter(coor(:, 2), coor(:, 3), 1, coor(:, 4));
    

    The problem is, that I have quite big number of coordinates to plot (~100 000). Its taking long time to plot it, and when I try to export figure to tiff - then matlab is dead for goooood few minutes... Any solution to improve plotting, or at least tiff export?

    EDIT: Forgot to mention, 3rd coordinate (coor(:, 4)) is a color code.

    So, when I'm using scatter (as above), I have something like on the image below, and thats exactly how I want to see it (just its super slow and I can't export that):

    scatter

    When I do:

    plot3(coor(:, 2), coor(:, 3), coor(:, 4), '.')

    effect is not as cool any more (note: images are not from the same coordinates...) :

    enter image description here

    • Anael
      Anael about 7 years
      Does anyone know how to solve this by binning the data into pixels, then display it as an image?
  • Art
    Art over 11 years
    Thanks for interest, however its not solving my problem, please see EDIT above...
  • Fantastic Mr Fox
    Fantastic Mr Fox over 11 years
    Yeah unfortunately i dont know how to use plot3 to change colour
  • arne.b
    arne.b over 11 years
    +1. I use that approach quite often so I even wrote a simple method to do this more easily (although the data I have often allow easier separation into a handful of distinct groups).
  • Art
    Art over 11 years
    very smart solution. Thanks!