pie chart creation with name (number) and corresponding percentage
8 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Alberto Acri
am 30 Aug. 2023
Beantwortet: Benjamin Kraus
am 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 Kommentare
Akzeptierte Antwort
Star Strider
am 30 Aug. 2023
Bearbeitet: Star Strider
am 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 Kommentare
Star Strider
am 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
am 4 Sep. 2023
Bearbeitet: Voss
am 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);
Weitere Antworten (2)
Benjamin Kraus
am 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 Kommentare
MYBLOG
am 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 Kommentare
Siehe auch
Kategorien
Mehr zu Data Import and Export finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!