pie chart creation with name (number) and corresponding percentage
    16 views (last 30 days)
  
       Show older comments
    
    Alberto Acri
      
 on 30 Aug 2023
  
    
    
    
    
    Answered: Benjamin Kraus
    
 on 26 Apr 2024
            Hi! I would like to create a pie chart like in the present demo:
x = [1,2,3];
p = pie(x);
pText = findobj(p,'Type','text');
percentValues = get(pText,'String'); 
txt = {'Item A: ';'Item B: ';'Item C: '};
combinedtxt = strcat(txt,percentValues); 
pText(1).String = combinedtxt(1);
pText(2).String = combinedtxt(2);
pText(3).String = combinedtxt(3);
How can I achieve the same result with my data? 
I tried it this way:
number = [78;79;80;81;82;83;84;85;86;87;88]';
value = [4509;5239;6400;9074;11047;13147;15137;13909;6354;1152;183]';
number2 = {};
for K = 1:height(number)
    number1 = sprintf('%.0f',number(K));
    number2 = [number2,{number1}];
end
number2 = number2.';
p = pie(value);
pText = findobj(p,'Type','text');
percentValues = get(pText,'String'); 
combinedtxt = strcat(number2,percentValues); 
for K = 1:height(value)
    pText(K).String = combinedtxt(K);
end
0 Comments
Accepted Answer
  Star Strider
      
      
 on 30 Aug 2023
        
      Edited: Star Strider
      
      
 on 30 Aug 2023
  
      One approach — 
number = [78;79;80;81;82;83;84;85;86;87;88]';
value = [4509;5239;6400;9074;11047;13147;15137;13909;6354;1152;183]';
f = figure;
p = pie(value);
pText = findobj(p,'Type','text');
percentValues = get(pText,'String'); 
delete(f)
pcts = regexp(percentValues, '\d*', 'match');
pcts = cellfun(@(x)str2double(x), pcts);
idx = pcts<7;
combine = number(idx);
pctv = pcts(idx);
percentVals = compose(' (%d%%)',pcts(~idx));
percentVals{end+1} = [' (' num2str(sum(pctv)) '%)'];
nrc = compose('%d ', number(~idx)).';
nrc{end+1} = [num2str(combine) ' '];
cattxt = cellfun(@(x,y)cat(2,x,y),nrc,  percentVals, 'Unif',0);
pText(numel(cattxt)+1:end) = [];
value2 = [value(~idx) sum(value(idx))];
figure
p = pie(value2);
pText = findobj(p,'Type','text');
percentValues = get(pText,'String');
for k = 1:numel(cattxt)
    pText(k).String = cattxt(k);
end
.
15 Comments
  Star Strider
      
      
 on 4 Sep 2023
				That may not be possible.  I tried my own version, and I don’t get exactly the same results the pie gets, although my calculations otherwise work — 
number = [48	49	50	51	52	53	54	55	56	57	58	59	60	61	62	63	64	65	66	67	68	69	70	71	72	73	74	75	76	77	78	79	80	81	82	83	84	85	86	87	88];
value = [0	0	0	0	0	0	42	91	152	276	440	572	821	1155	1580	1761	2157	2256	2578	2499	2715	2794	3280	3237	3263	3586	3334	3652	3675	4404	4509	5239	6400	9074	11047	13147	15137	13909	6354	1152	183];
f = figure;
p = pie(value);
[U_value,nidx,ix]  = unique(value,'stable');
Counts = accumarray(ix, value);
sum_Counts = sum(Counts);
Freqs = Counts/sum(Counts) * 100;
[v1,v2] = bounds(Freqs)
number_v = number(nidx).';
Interim_Results = table(number_v,Counts,Freqs)
Freqs_lt_7 = Freqs < 7;                                             % Threshold Results
Thresholded_Interim_Results_1 = sum(Freqs(Freqs_lt_7))
Thresholded_Interim_Results_2 = [number_v(~Freqs_lt_7)  Freqs(~Freqs_lt_7)  round(Freqs(~Freqs_lt_7))];
Thresholded_Interim_Results_2(end+1,:) = [NaN sum(Thresholded_Interim_Results_2(:,2:end))]
pText = findobj(p,'Type','text');
percentValues = get(pText,'String'); 
delete(f)
pcts = regexp(percentValues, '\d*', 'match');
pcts = cellfun(@(x)str2double(x), pcts);
idx = pcts<7;
combine = number(idx);
pctv = pcts(idx);
percentVals = compose(' (%d%%)',pcts(~idx));
percentVals{end+1} = [' (' num2str(sum(pctv)) '%)'];
nrc = compose('%d (%2d%%)', [number(~idx).', pcts(~idx)]);
% VARIED
nrc{end+1} = sprintf('%d %d %d %d %d %d (%2d%%)\n%d %d %d %d %d %d\n%d %d %d %d %d %d\n%d %d %d %d %d %d\n%d %d %d %d %d %d\n%d %d %d %d %d %d',[combine(1:6) sum(pcts(idx)) combine(7:end)]);    % NEW 'nrc{end+1}'
cattxt = nrc;
pText(numel(cattxt)+1:end) = [];
value2 = [value(~idx) sum(value(idx))];
figure
p = pie(value2);
pPatch = findobj(p, 'Type','Patch');
cm = colormap(turbo(numel(pPatch)));                                % Colour Array (Can Be Whatever You Define It To Be)
pText = findobj(p,'Type','text');
percentValues = get(pText,'String');
for k = 1:numel(cattxt)
    pPatch(k).FaceColor  = cm(k,:);                                 % Colour Each Patch Individually
    pText(k).String = [];                                           % Delete The 'String' Labels
end
lgd = legend(cattxt, 'Location','eastoutside','FontSize',12);
.
  Voss
      
      
 on 4 Sep 2023
				
      Edited: Voss
      
      
 on 4 Sep 2023
  
			@Alberto Acri: The numbers sum to 107 because the first (deleted) pie chart includes several strings that are "<1%". When you get the number from those strings and use it, of course those are counted as 1 instead of what they really are. The solution is, instead of getting the percentages from a pie chart you're going to delete, just calculate the percentages directly, and they'll have a higher precision. You'll have to round them when you use them in the legend, but here's the important part: the small ones (<1%) do not get "rounded" to 1 and then summed; instead you sum them first and then round the result. You can see below that the total sum is 100:
number = [48	49	50	51	52	53	54	55	56	57	58	59	60	61	62	63	64	65	66	67	68	69	70	71	72	73	74	75	76	77	78	79	80	81	82	83	84	85	86	87	88];
value = [0	0	0	0	0	0	42	91	152	276	440	572	821	1155	1580	1761	2157	2256	2578	2499	2715	2794	3280	3237	3263	3586	3334	3652	3675	4404	4509	5239	6400	9074	11047	13147	15137	13909	6354	1152	183];
% calculate percentages:
pcts = 100*value.'/sum(value);
idx = round(pcts)<7;
combine = number(idx);
pctv = pcts(idx);
nrc = compose('%d (%2d%%)', [number(~idx).', round(pcts(~idx))]);
% VARIED
nrc{end+1} = sprintf('%d %d %d %d %d %d (%2d%%)\n%d %d %d %d %d %d\n%d %d %d %d %d %d\n%d %d %d %d %d %d\n%d %d %d %d %d %d\n%d %d %d %d %d %d',[combine(1:6) round(sum(pcts(idx))) combine(7:end)]);    % NEW 'nrc{end+1}'
cattxt = nrc;
value2 = [value(~idx) sum(value(idx))];
figure
p = pie(value2);
pPatch = findobj(p, 'Type','Patch');
cm = colormap(turbo(numel(pPatch)));                                % Colour Array (Can Be Whatever You Define It To Be)
pText = findobj(p,'Type','text');
percentValues = get(pText,'String');
for k = 1:numel(cattxt)
    pPatch(k).FaceColor  = cm(k,:);                                 % Colour Each Patch Individually
    pText(k).String = [];                                           % Delete The 'String' Labels
end
lgd = legend(cattxt, 'Location','eastoutside','FontSize',12);
More Answers (2)
  Benjamin Kraus
    
 on 26 Apr 2024
        You can read about it here: https://blogs.mathworks.com/graphics-and-apps/2023/11/13/pie-charts-and-donut-charts/
A new feature (added in R2024a) is the LabelStyle property, which can be used to quickly create the labels you were asking about.
x = [1,2,3];
txt = {'Item A';'Item B';'Item C'};
p = piechart(x, txt);
p.LabelStyle = 'namepercent';
0 Comments
  MYBLOG
      
 on 30 Aug 2023
        The code you provided is mostly correct, but you can simplify it a bit. Here's how you can achieve the same result with your data:
% Your data
number = [78;79;80;81;82;83;84;85;86;87;88]';
value = [4509;5239;6400;9074;11047;13147;15137;13909;6354;1152;183]';
% Create labels for the pie chart
number2 = cellstr(num2str(number)); % Convert numbers to cell array of strings
% Create the pie chart
p = pie(value);
pText = findobj(p,'Type','text');
percentValues = get(pText,'String'); 
% Combine labels and percentages
combinedtxt = strcat(number2, ': ', percentValues);
% Set the combined text for each slice
for K = 1:numel(value)
    pText(K).String = combinedtxt{K};
end
0 Comments
See Also
Categories
				Find more on 2-D and 3-D Plots in Help Center and File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!























