Reputation: 8585
Problem:
The legend colors in my scatter3 plot do not match the series colors after using a for loop.
Background:
I'm writing a script to produce a 3d plot based on experimental data. I process the data in R, as well. So the data is formatted as a data.frame (i.e. a nx7 CSV with headers are Value Gain Cost, Entropy, Risk, Credibility, algorithm, color, pch). I want the resulting 3d scatter plot to add a point for each observation (i.e. each [x,y,z] element) and color it according to its pch value (e.g. all observations with pch==1 should be the same color).
Code:
%get & count unique pch values ommitting NANs
UniquePchVal =transpose(unique(pch));
numberOfUniquePchVals=length(UniquePchVal(~isnan(UniquePchVal)))
UniquePchVal = UniquePchVal(1:numberOfUniquePchVals);
% get boolean vector for each series to indicate which observations should
% are to be included
numberOfObservations=length(pch)
UniquePchValMatrix = repmat(UniquePchVal,numberOfObservations,1);
pchMatrix=repmat(pch,1,numberOfUniquePchVals);
rows=UniquePchValMatrix(1:numberOfObservations,1:numberOfUniquePchVals);
rows =(rows==pchMatrix);
%make the plot
hold on
for i=1:numberOfUniquePchVals
x=ValueGain(rows(:,i));
y=Cost(rows(:,i));
z=Risk(rows(:,i));
size=repmat(20,length(x),1);
color=repmat(i,length(x),1);
h(i)=scatter3(x,y,z,size,color,'filled');
end
xlabel('Value Gain')
ylabel('Cost')
zlabel('Risk')
legend(h,unique(algorithm))
hold off
Result:
Executing the code produces a legend where each dot is the same color.
Sample Data:
Value Gain Cost Entropy Risk Credibility algorithm color pch
-0.0 0.0 -0.0 0.0 -0.0 MOEAD orange 3
-1.39838 1.44 -1.0 2.55555 -1.0 MOEAD orange 3
-1.41319 4.15 -1.0 1.55555 -1.0 MOEAD orange 3
-1.39593 3.84 -1.0 1.55555 -1.0 MOEAD orange 3
-1.25189 1.11 -0.5 1.55555 -1.0 IBEA cornflowerblue 4
-1.43183 2.87 -0.5 2.55555 -1.0 IBEA cornflowerblue 4
-1.38953 1.43 -1.0 1.55555 -1.0 NSGA2 #fb8072 5
-1.39585 1.13 -0.33333 1.55555 -1.0 NSGA2 #fb8072 5
-1.1792 1.0 -0.2 2.55555 -1.0 NSGA2 #fb8072 5
-1.38244 1.14 -1.0 1.55555 -1.0 NSGA2 #fb8072 5
-0.05665 0.89 -1.0 2.55543 -1.0 NSGA2 #fb8072 5
-0.1175 0.9 -0.5 1.55556 -1.0 NSGA2 #fb8072 5
-0.06518 0.75 -0.33333 1.55555 -1.0 NSGA2 #fb8072 5
-0.51192 0.98 -0.5 1.55555 -1.0 NSGA2 #fb8072 5
-0.77432 0.98 -1.0 2.55555 -1.0 NSGA2 #fb8072 5
-0.82269 0.94 -0.25 2.55555 -1.0 NSGA2 #fb8072 5
-0.92626 1.0 -1.0 1.55555 -1.0 NSGA2 #fb8072 5
Upvotes: 4
Views: 424
Reputation: 782
If all markers are the same colour, or there are only a few distinct colours, it is much more efficient to just use line
instead of scatter3
; the latter makes one handle per marker, line
has one handle for all points. scatter3
with many points can bring Matlab to a halt.
Added bonus when using line
is that the legend works as expected:
colors = ['r','g','b'];
hold on
h = [];
for ii = 1:3
x = rand(10,1);
y = rand(10,1);
z = rand(10,1);
h(ii) = line(x,y,z);
set(h(ii),...
'Marker','.',...
'MarkerEdgeColor',colors(ii),...
'MarkerFaceColor',colors(ii),...
'MarkerSize',10,...
'LineStyle','none')
end
legend('a','b','c')
Upvotes: 1