That's pretty simple to do. kkuilla posted a very insightful link. To get something started, if you want to have a colour map that varies from blue to red, you know that an image is decomposed into three colours: Red, green and blue.
Therefore, all you would have to do is vary the red and blue channels. Start with a pure blue colour, which is RGB = (0,0,255)
where this is mapped to the initial weight of w = 0
and vary this to the end where RGB = (255,0,0)
with w = 1
. You can very easily do that by linspace
. However, colours in a colour map for plotting in MATLAB are normalized so that they're between [0,1]
, not [0,255]
. Also, because a colour map in MATLAB is a matrix of N x 3
, where N
is the total number of colours you want, all you have to do is:
num_colours = 10;
colourmap = [linspace(0,1,num_colours).' zeros(num_colours,1) linspace(1,0,num_colours).'];
weights = linspace(0,1,num_colours);
num_colours
is the total number of colours you would like displayed. I set it to 10 to get you started. weights
is something we will need for later, so don't worry about that righ tnow. Essentially, colormap
would be the colour map you apply to your data.
However, what is going to be difficult now is that the data that you're plotting has no correlation to the weight of the data itself (or the fourth column of your data). This means that you can't simply use the (X,Y,Z)
data to determine what the colour of each plot in your stem
is going to look like. Usually for colour maps in MATLAB, the height of the stem is proportional to the colour that is displayed. For the largest Z
value in your data, this would naturally be assigned to the colour at the end of your colour map, or red. The smallestZ
value in your data would naturally get assigned at the beginning of your colour map, or blue.
If this was the case, you would only need to make one stem
call and specify the colour map as the attribute for Color
. Because there is no correlation between the height of the Z
value and the weight that you're assigning for each data point, you have no choice but to loop through each of your points and determine the closest value between the weight for a point with every weight and ultimately every colour in your colour map, then apply this closest colour to each point in your stem
respectively.
We determine the closest point by using the weights
vector that was generated above. We can consider each colour as having a mapping from [0,1]
, and each weight corresponds to the colour in colourmap
. Therefore, a weight of 0 is the first colour in the colour map, and that's in the first row. The next weight after this is the second colour, and that's in the second row and so on.... so we simply need to determine where each weight that's in the fourth column of your matrix is closest to for the above weights
vector. This will determine which colour we need to select from the colour map to plot the point.
Given that your matrix of 200 x 4
is stored in data
, you must specifically do this:
%// Spawn a new figure
figure;
%// Determine the number of points in the dataset
num_points = size(data,1);
%// For each point in the data set
for idx = 1 : num_points
%// Get 4th column element and determine closest colour
w = data(idx,4);
[~,ind] = min(abs(weights-w));
color = colourmap(ind,:);
%// Plot a stem at this point and change the colour of the stem
%// as well as the marker edge colour and face colour
stem3(data(idx,1), data(idx,2), data(idx,3), 'Color', color, ...
'MarkerEdgeColor', color, 'MarkerFaceColor', color);
%// Make sure multiple calls to stem don't clear the plot
hold on;
end
%// Display colour bar to show colours
colormap(colourmap(1:end-1,:));
colorbar('YTickLabel', colourmap);
The last two lines are a bit hackish, but we basically show a colour bar to the right of the plot that tells you how each weight maps to each colour.
Let's test this on some data. I'm going to generate a random 200 x 4
matrix of points and we will use the above code and plot it using stem3
:
rng(123123); %// Set seed for reproducibility
data = rand(200,4);
num_colours = 10;
I set the total number of unique colours to 10. Once I have this above data, when I run through the code above, this is the plot I get:
