How do I define colors for individual bars on my bar graph according to their values in MATLAB?

337 views (last 30 days)
I am trying to change colors on the individual bars in a bar graph according to the value of my data. When I issue the following command,
mydata=rand(1,5);
h=bar(mydata);
all the bars in my bar graph have the color blue. I want the bar colors to be such that if the value of 'mydata' is between [0, 0.2), the bars are black, if the value of my data is between [0.2, 0.6), the bars are blue, and if the value of my data is between [0.6, 1] then the corresponding bars are red.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 7 Oct 2019
Edited: MathWorks Support Team on 7 Oct 2019
This issue has been resolved in MATLAB R2017b with the addition of a property "CData" to the "bar" function. To find out more about "CData", look at the following documentation page.
Prior to MATLAB R2017b, there was no built in function in MATLAB to control the color of individual bars in the bar graphs, but you can plot each bar individually and set the colors one at a time. For example:
mydata=rand(1,5);
figure(1)
hold on
for i = 1:length(mydata)
h=bar(i,mydata(i));
if mydata(i) < 0.2
set(h,'FaceColor','k');
elseif mydata(i) < 0.6
set(h,'FaceColor','b');
else
set(h,'FaceColor','r');
end
end
hold off
will produce a figure similar to the one below:
In MATLAB R2014a and earlier, the following example provides an alternative method to set the color of a bar in the chart based on its value.
First, obtain the handle to the 'Children' of a bar graph.
mydata=rand(1,5);
bar_h=bar(mydata);
bar_child=get(bar_h,'Children');
1. In order to map the color on the bars to your data, execute the following code:
set(bar_child,'CData',mydata);
Once 'CData' is set to "mydata", the colors on the individual bars are decided by comparing their values linearly with the default colormap "jet". You can change the colors on your barplot now by changing the colormap to one of the supplied colormaps. For example,
colormap(pink)
2. Since the default colormap is "jet", the minimum value in "mydata" is mapped to blue and the maximum value in "mydata" is mapped to red. To have more control on the colors on the bar, create your own colormap
mycolor=[0 0 0;0 0 1;1 0 0];
colormap(mycolor)
This will create a colormap with black as the first color, blue as the second, and red as the third color. Applying this colormap forces the color of the bars in the chart to be dependent on a linear scale between "mydata" and the number of available colors in the colormap. So the first third of the data range is black, the second third is blue, and the final third is red.
3. To apply specific colors for specific data ranges, set the 'CDataMapping' property to 'direct'.
set(bar_child,'CDataMapping','direct');
For example, to map all values between [0, 0.2) to black, all values between [0.2, 0.6) to blue, and all values between [0.6, 1] to red, execute the following code:
mycolor=[0 0 0;0 0 1;1 0 0];
for iCount=1:length(mydata)
if (mydata(iCount)<.2)
index(iCount)=1;
elseif(mydata(iCount)>=.6)
index(iCount)=3;
else
index(iCount)=2;
end
end
Set the 'CData' to the desired indices of the colormap.
set(bar_child, 'CData',index);
colormap(mycolor);
As an alternative to looping through the data, apply a vectorized method using logical arrays. In the following example, a logical array is found for a specific data range, and then wieghted by the color index associtated with the data range. The sum of the weighted logical arrays will result in the index vector.
blackRange = 1*(mydata<0.2);
redRange = 3*(mydata>=0.6);
blueRange = 2*~(blackRange+redRange);
index = blackRange + redRange + blueRange;
4. Note that if you have more than 150 datapoints to plot, you may see an error similar to the following after setting the 'CData' property: ERROR: Warning: Patch FaceVertexCData length (160) must equal Vertices length (801) for flat EdgeColor
In that case, you will need to set the 'EdgeColor' property of the 'bar_child' to a color specification or to 'none'. Add the following line just before the command that sets the 'CData' property:
set(bar_child, 'EdgeColor', 'r'); % red outlines around the bars
  1 Comment
Walter Roberson
Walter Roberson on 28 Jan 2016
Starting from R2014b, barseries are no longer implemented as patches. Unfortunately no mechanism to customize the bar colors has been provided. You will need to bar() each item individually specifying its color.

Sign in to comment.

More Answers (0)

Categories

Find more on Colormaps in Help Center and File Exchange

Products


Release

R2017b

Community Treasure Hunt

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

Start Hunting!