'Legend on MATLAB plot where every point is scattered individually

I am trying to get a legend on a scatter plot in Matlab, the problem is the way I plot the graph involves scattering each point (of which there are >10,000) individually going through a for loop. The code is as follows:

figure;
xlabel ('\omega_u/p','FontSize',24,'FontName','Helvetica')
ylabel ('u_0/\alpha g','FontSize',24,'FontName','Helvetica')
set (findobj('type','axes'),'FontSize',24,'FontName','Helvetica')
hold on;

for j= 1:1:length(SURVIVALMODE)
 if SURVIVALMODE(j,1) == 1;
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'g','fill');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==6
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'b','fill');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==13
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'r','fill');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==14
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'k','fill');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==21
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'c','fill');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==29
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'m','fill');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==10
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'b','^');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==17
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'r','^');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==18
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'k','^');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==25
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'c','^');
 elseif SURVIVALMODE(j,1) == 0 && SURVIVALMODE(j,2)==33
     scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'m','^');
 end
end

U0OMEGAU is a matrix containing all the points to be plotted SURVIVALMODE contains the conditions on how to plot them. When I use a conventional legend it tries to make a legend containing every point that has been plotted, rather than the different types of points. I tried to create a dummy scatter plot with one point of each type and create a legend from that but wasn't successful. Any help would be appreciated!



Solution 1:[1]

A sneaky way to solve this is to plot beforehand a point for each data you want to appear in the legend, outside the area where the actual points will be displayed, and then to use axis to set the plot borders to exclude these dummy points. The legend entries will then correspond to these points.

For example, suppose you want to plot two datasets but put them in a reverse order in the legend, you can do:

x = 0:pi/100:2*pi;
y1 = sin(x); % I want this in green
y2 = cos(x); % I want this in red
% If for some reason I want to plot y1 before y2,
% but use a different order in the legend, I can do:
yOut = min([y1 y2]) - 1;
figure;
plot(0, yOut, 'r', 0, yOut, 'g');
hold on;
plot(x, y1, 'g', x, y2, 'r');
hold off;
legend('Red plotted 2nd', 'Green plotted 1st');
axis([min(x) max(x) min([y1 y2]) max([y1 y2])]);

This can be applied to your case as well. There might be a more straightforward answer, but this works for me.

Solution 2:[2]

I just had the same question today and thought I expand expand on what buzjwa wrote using my solution. I would start the for loop at 2 instead of 1 and run the first entries before the loop. You could then also give a handle to each scatter point that you would like to add to the legend.

So for your code, it could look something like this:

figure;
xlabel ('\omega_u/p','FontSize',24,'FontName','Helvetica')
ylabel ('u_0/\alpha g','FontSize',24,'FontName','Helvetica')
set (findobj('type','axes'),'FontSize',24,'FontName','Helvetica')
hold on;

j=1

h1=scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'g','fill');

scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'b','fill');

h2=scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'r','fill');

scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'k','fill');

scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'c','fill');

scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'m','fill');

h3=scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'b','^');

h4=scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'r','^');

h5=scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'k','^');

scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'c','^');

scatter(U0OMEGAU(j,2)/p,U0OMEGAU(j,1)/(alpha*g),14,'m','^');


for j= 2:1:length(SURVIVALMODE)
    
    this bit stays untouched..

end

legend([h1, h2, h3, h4, h5],'first','second','third','fourth','fifth'))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 buzjwa
Solution 2 partypeter