Plot multiple categorical Pie Chart. Keep the color for each value.

14 views (last 30 days)
Hello,
I'm analyzing some categorical data. I want to plot 4 Pie Chart in one single figure.
All the Pie Chart have the same categories on it, but some of them are empty.
The problem is when I plot altogether, Matlab assign colors just to the nonempty values.
Therefore the color assigned to a category change depending on which categories are shown.
For example in that case 'sempre' is blue on chart 1,2 and 3 but cyan on 4.
Or yellow is assigned to 'Mai' in the first chart but is assined to 'Depenent....' on chart 2 and 3.
I would like to be able to assing a color to each category, or at least keep a consitency on the color legend.
Thank you very much for your help.
untitled.bmp

Answers (2)

Star Strider
Star Strider on 21 Dec 2018
One approach:
Data = randi(9, 4); % Create Data
Labels = {'Aaa','Bb','CQ','Dd'}; % Create Data
Cv = {'r','c','m','y'}; % Assign Colors
figure
for k1 = 1:4
Ax{k1} = subplot(2,2,k1);
Cols = randperm(4,3); % —> For Demonstration Code Only (Delete Later)
P{k1} = pie(Ax{k1}, Data(k1,Cols), Labels(Cols)); % Pie Chart
TextArr = findobj(P{k1}, 'Type','Text'); % Find ‘Text’ Objects
PatchArr = findobj(P{k1}, 'Type','patch'); % Find ‘Patch’ Objects
for k2 = 1:numel(PatchArr)
Idx = contains(Labels, TextArr(k2).String); % Match Strings To Index Into Color Array
PatchArr(k2).FaceColor = Cv{Idx}; % Assign Consistent Colors
end
title(Ax{k1},sprintf('Pie #%d',k1))
end
It works with the data I created here. It plots your data, then in the contains call, matches the label in each segment with one of the labels in the ‘Labels’ cell array, and assigns the appropriate color to that segment. (I deliberately used only 3 of the 4 possible categories and colors with each pie chart, because I am concentrating here on getting the colors to plot correctly with the appropriate labels regardless of the data plotted in each pie chart.)
You will have to experiment with it with your data. It should be straightforward to implement.
  2 Comments
Roman
Roman on 17 May 2019
Using your example works fine, thanks for that; however, when I change your color strings to color numbers (to eventually have more than 4 colors only):
Cv=colorcube(4)
.... and later use:
PatchArr(k2).FaceColor = Cv(Idx,:);
I keep getting the error message:
Error setting property 'FaceColor' of class 'Patch':
Color value must be a 3 element numeric vector
How can I do this properly?
Star Strider
Star Strider on 17 May 2019
The ‘Idx’ variable is a logical array in my code. With your definition of ‘Cv’, and with my cell array ‘Cv’ commented-out, this works correctly for me in R2019a:
PatchArr(k2).FaceColor = Cv(Idx,:); % Assign Consistent Colors
I also tried it with:
Cv = colormap(jet(4));
with similar success but obviously different colours.
Since ‘Idx’ is a logical array, my code should work with only those changes (definiing ‘Cv’ as an array, and the ‘PatchArr’ assignment I posted).

Sign in to comment.


Jonathan
Jonathan on 4 Nov 2021
This is an interesting workaround and I appreciate the question and response and was able to play with it a little. However, I'm struggling understanding the relationship between 'data' and 'Cols', as I have a similar situation and I can't figure out your code. Your code says Col can be replaced, I'm just not sure what it replaces or is replaced with. Lets say I have two datasets
t1=410, 376, 343, 0, 0, 0;
t2=300, 400, 200, 10, 100, 25;
Hence there would be six colors, but the first only has 3 segments while the second has all 6. It seems like Col controls the number of colors, but also seems to be controling the size of the segments, which is confusing as I thought Data did that. Any guidance would be much appreciated.

Products

Community Treasure Hunt

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

Start Hunting!