# Add legend to plot colored by colormap function

75 views (last 30 days)
Sophie Leiter on 12 Aug 2021
Commented: Sophie Leiter on 12 Aug 2021
I am using currently making a plot where the color of the points is determined by a code (1-3) in the 3 column of the matrix. I can't seem to figure out how to get matlab to make a legend for this and not a colorbar. Since they're plotted as one thing the automatic legend function only includes one point. As it stands I've just been adding a legend in illustrator but it's a bit time consuming with lots of graphs and I'd prefer to have it done in matlab. Is it possible to either make a legend from scratch and specify each entry and label or get matlab to do it automatically? Thanks!
The code I am using and the figure are below:
x = [HL_conpor HL_perm HL_class];
colors = [0.8 0.8 0;
1 0.5 0
1 0 0
]; %
scatter(x(:,1), x(:,2),[], x(:,3),'filled')
set(gca, 'YScale', 'log')
xlabel('Connected Porosity(\phi_c)');
ylabel('Permeability (m^2)');
colormap(colors)
legend_labels = {'VDP1', 'VDP2', 'VDP3'};
legend(legend_labels, 'Location', 'Best'); Dave B on 12 Aug 2021
Edited: Dave B on 12 Aug 2021
When you specify CData (the color input) for scatter, MATLAB uses colormapping to plot the data, and a colorbar to describe the mapping. Scatter is thinking of CData as continuous, but you're thinking of color as discrete.
There are two common approaches to solving this problem...
Problem case and fake data
x=randn(100,1);
y=randn(100,1);
c=randi(3,100,1);
tiledlayout(2,2)
nexttile;
scatter(x,y,30,c,'f')
colormap([1 0 0; 0 1 0; 0 0 1])
colorbar('Ticks',[4/3 2 8/3],'TickLabels',["Red" "Green" "Blue"])
title('Problem Version')
Solution 1: use hold on, make seperate scatter objects, and use colororder to define the colors (could also specify the color explicitly in each scatter as long as there's one color for each scatter):
nexttile(3)
hold on
scatter(x(c==1),y(c==1),30,'filled')
scatter(x(c==2),y(c==2),30,'filled')
scatter(x(c==3),y(c==3),30,'filled')
colororder([1 0 0;0 1 0; 0 0 1])
legend(["Red" "Green" "Blue"])
Solution 2: create some hidden scatters and pass them in to legend:
nexttile(4)
scatter(x,y,30,c,'f')
hold on
h=gobjects(3,1);
h(1)=scatter(nan,nan,'r','filled');
h(2)=scatter(nan,nan,'g','filled');
h(3)=scatter(nan,nan,'b','filled');
legend(h, ["Red" "Green" "Blue"])
title("3 Hidden Scatters") Sophie Leiter on 12 Aug 2021
That makes sense. Thank you for the explanation!

Scott MacKenzie on 12 Aug 2021
One approach is to do three scatters, one for each value in the 3rd column in your data. Here's the general idea using a modified version of your code:
x = [rand(25,1) rand(25,1) randi(3,25,1)];
colors = [0.8 0.8 0; 1 0.5 0; 1 0 1];
c1 = x(:,3) == 1;
c2 = x(:,3) == 2;
c3 = x(:,3) == 3;
scatter(x(c1,1), x(c1,2),100, 'filled');
hold on;
scatter(x(c2,1), x(c2,2),100, 'filled');
scatter(x(c3,1), x(c3,2),100, 'filled');
set(gca, 'YScale', 'log')
xlabel('Connected Porosity(\phi_c)');
ylabel('Permeability (m^2)');
colormap(colors)
legend_labels = {'VDP1', 'VDP2', 'VDP3'};
legend(legend_labels, 'Location', 'Best'); Sophie Leiter on 12 Aug 2021

R2021a

### Community Treasure Hunt

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

Start Hunting!