pie chart creation with name (number) and corresponding percentage
12 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Alberto Acri
el 30 de Ag. de 2023
Respondida: Benjamin Kraus
el 26 de Abr. de 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 comentarios
Respuesta aceptada
Star Strider
el 30 de Ag. de 2023
Editada: Star Strider
el 30 de Ag. de 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 comentarios
Star Strider
el 4 de Sept. de 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
el 4 de Sept. de 2023
Editada: Voss
el 4 de Sept. de 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);
Más respuestas (2)
Benjamin Kraus
el 26 de Abr. de 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 comentarios
MYBLOG
el 30 de Ag. de 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 comentarios
Ver también
Categorías
Más información sobre Graphics Object Identification en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!