📄 piechart.m
字号:
function [out1] = piechart(values,label_matrix,p1,v1,p2,v2,p3,v3,p4,v4,p5,v5)
%
% Function to create a pie chart.
%
% PIECHART(X) - creates a pie chart of the data in vector X.
% Percentages of a pie slice with respect to whole pie are
% displayed.
%
% PIECHART(X,'STRING_MATRIX') - same as previous expect that the
% rows of the STRING_MATRIX are associated with each element
% of X (ie., STRING_MATRIX must have the same number of
% rows as X has elements).
%
% Additional properties of the pie chart can be supplied
% as argument pairs to the PIECHART function:
%
% 'ExplodeDistance' ,V1 where V1 is a vector equal size as X. Each
% element of V1 is a fraction of pie's radius that defines how far
% the particular slice associated with X is to be moved [default =
% zeros(size(X))].
%
% 'PercentLabels',V2 where V2 is 'on' or 'off'. Specifies whether
% or not the percentages are shown.
%
% 'LabelLocation',V3 where V3 is 'inside' or 'outside'. Specifies
% whether the text string associated with each slice is placed on
% top of the slice or off to the side of the chart.
% [Default == 'inside']
%
% 'View',V4 where V4 is 2 or 3. Specifies whether this is a 2D or 3D
% pie chart. Is essentially a view(2) or view(3) and therefore may
% be modified at the command window. [Default == 2]
%
% 'Rotation',V5 where V5 is a scalar in degrees specifying the
% starting slice's angular position. [Default == 0]
%
% Examples
% piechart([1 2 3],str2mat('String1','String2','String3'))
%
% piechart([1 2 3],str2mat('String1','String2','String3'),...
% 'ExplodeDistance',[0 .25 0],'View',3)
%
% Patrick Marchand (prmarchand@aol.com) 2 Feb. 1995 Initial
%
if nargin > 2 & rem(nargin,2) ~= 0
error('piechart called with an incorrect number of arguments');
end
if nargin < 2
label_matrix = [];
end
explode_dist = zeros(size(values));
initial_rotation = 0;
percent_labels_on_off = 'on';
label_location = 'outside';
view_type = 2;
for arg = 1:((nargin-2)/2)
p = eval([lower(sprintf('p%g',arg))]);
v = eval([sprintf('v%g',arg)]);
if strcmp(p(1:3),'exp')
explode_dist = v;
elseif strcmp(p(1:3),'rot')
initial_rotation = v(1);
elseif strcmp(p(1:3),'per')
percent_labels_on_off = v;
elseif strcmp(p(1:3),'lab')
label_location = v;
elseif strcmp(p(1:3),'vie')
view_type = v;
end
end
if length(values(:)) ~= length(explode_dist)
explode_dist = explode_dist(1)*ones(size(values));
end
% Normalize the input data to 100%
norm_values = values/sum(values);
norm_cum_values = [0 cumsum(norm_values)];
Hold_Status_On = ishold;
pi_values = norm_cum_values*360;
piece_angle = [];
colord = get(gca,'colororder');
colord = hsv(length(pi_values)-1);
for pie_piece = 1:(length(pi_values)-1)
% Define pie slice positions
pie_xvals = [cos(([pi_values(pie_piece):5:pi_values(pie_piece+1) pi_values(pie_piece+1)]+initial_rotation)*pi/180)];
pie_yvals = [sin(([pi_values(pie_piece):5:pi_values(pie_piece+1) pi_values(pie_piece+1) ]+initial_rotation)*pi/180)];
piece_angle(pie_piece) = mean(pi_values(pie_piece+[0 1])) + initial_rotation;
xpld_dist = explode_dist(pie_piece)*cos(piece_angle(pie_piece)*pi/180);
ypld_dist = explode_dist(pie_piece)*sin(piece_angle(pie_piece)*pi/180);
% Define color of slice
color_num = rem(pie_piece,size(colord,1));
if color_num == 0
color_num = size(colord,1);
end
if pie_piece == (length(pi_values)-1) & color_num == 1 & pie_piece ~= 1
color_num = color_num + 2;
end
col = colord(color_num,:);
% Render outer curvature of pie slice
s1=surf([1;1]*[xpld_dist+pie_xvals],[1;1]*[ypld_dist+pie_yvals],[1;0]*ones(size([ypld_dist+pie_yvals])),col);
set(s1,'tag',['piece' num2str(pie_piece)],'edgecolor','none','facecolor',col);
% Render Top and Bottom of each pie slice.
x_top = [xpld_dist+[pie_xvals cos(([90-initial_rotation pi_values(pie_piece)]+initial_rotation)*pi/180)]];
y_top = [ypld_dist+[pie_yvals sin(([(0-initial_rotation) pi_values(pie_piece)]+initial_rotation)*pi/180)]];
patch(x_top,y_top,ones(size(x_top)),col,'linewidth',2)
patch(x_top,y_top,zeros(size(x_top)),col,'linewidth',2)
% Render sides to pie slice.
x_side1 = [x_top([length(x_top)+[-2 -1 -1 -2]])];
y_side1 = [y_top([length(y_top)+[-2 -1 -1 -2]])];
patch(x_side1,y_side1,[0 0 1 1],col,'linewidth',2);
x_side2 = [x_top([1 length(x_top)+[-1 -1 ] 1])];
y_side2 = [y_top([1 length(y_top)+[-1 -1] 1])];
patch(x_side2,y_side2,[0 0 1 1],col,'linewidth',2);
% Next two lines created to help adjust for some 3D rendering problems.
line([1 1]*[x_top(1)],[1 1]*[y_top(1)],[0 1],'linewidth',2,'color',[0 0 0])
line([1 1]*[x_top(length(x_top)-2)],[1 1]*[y_top(length(y_top)-2)],[0 1],'linewidth',2,'color',[0 0 0])
hold on
end
minx = -1;
maxx = 1;
miny = -1;
maxy = 1;
if strcmp(lower(label_location(1)),'o')
label_radi = 1.25;
else
label_radi = 0.5;
end
for pie_piece = 1:(length(pi_values)-1)
xpld_dist = explode_dist(pie_piece)*cos(piece_angle(pie_piece)*pi/180);
ypld_dist = explode_dist(pie_piece)*sin(piece_angle(pie_piece)*pi/180);
txpld_dist = xpld_dist+label_radi*cos(piece_angle(pie_piece)*pi/180);
typld_dist = ypld_dist+label_radi*sin(piece_angle(pie_piece)*pi/180);
lxpld_dist = xpld_dist+[0.9 1.2]*cos(piece_angle(pie_piece)*pi/180);
lypld_dist = ypld_dist+[0.9 1.2]*sin(piece_angle(pie_piece)*pi/180);
if strcmp(lower(percent_labels_on_off) , 'on')
text_string = [' (' num2str(round(norm_values(pie_piece)*1000)/10) '% )'];
else
text_string = '';
end
if length(label_matrix) ~= 0
text_string = [deblank(label_matrix(pie_piece,:)) text_string];
end
if piece_angle(pie_piece) < 90 | piece_angle(pie_piece) > 270
t = text(txpld_dist,typld_dist,1,text_string,'horiz','left','vert','middle');
else
t = text(txpld_dist,typld_dist,1,text_string,'horiz','right','vert','middle');
end
extent = get(t,'extent');
if extent(1) < minx
minx = extent(1);
end
if extent(2) < miny
miny = extent(2);
end
if sum(extent([1 3])) > maxx
maxx = sum(extent([1 3]));
end
if sum(extent([2 4])) > maxy
maxy = sum(extent([2 4]));
end
if strcmp(lower(label_location(1)),'o')
line(lxpld_dist,lypld_dist,ones(size(lxpld_dist)),'color',[1 1 1]);
end
end
axis('equal');
axis('off');
if view_type == 2
view(2);
% axis([min([-1 minx]) max([1 maxx]) min([-1 miny]) max([1 maxy]) 0 1])
else
view([-37.5 60])
% axis([min([-1 minx]) max([1 maxx]) min([-1 miny]) max([1 maxy]) -1 2])
end
axis('auto')
if ~Hold_Status_On
hold off
end
if nargout == 1;
out1 = piece_angle;
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -