pie chart creation with name (number) and corresponding percentage
13 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Alberto Acri
le 30 Août 2023
Réponse apportée : Benjamin Kraus
le 26 Avr 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 commentaires
Réponse acceptée
Star Strider
le 30 Août 2023
Modifié(e) : Star Strider
le 30 Août 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 commentaires
Star Strider
le 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
le 4 Sep 2023
Modifié(e) : Voss
le 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);
Plus de réponses (2)
Benjamin Kraus
le 26 Avr 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 commentaires
MYBLOG
le 30 Août 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 commentaires
Voir également
Catégories
En savoir plus sur Data Import and Export dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!