Scatter pie plot

坚强是说给别人听的谎言 提交于 2019-12-04 14:42:39

As a first attempt, I managed to draw the pie charts at each point using only two LINE graphic objects: one for the circles, and one for the divisions inside the circles. Thus we are just plotting unfilled pie charts.

This is very efficient in terms of performance. It is achieved by using NaN to separate the lines into segments. Compare this to the other proposed solution; if we look at its source code, we find that it creates one axis for every single point, and calls MATLAB's function PIE inside it.

We start with some data points along with their "fuzzy clustering":

numPoints = 15; numClasses = 5;

%# random 2D points
points = randn(numPoints,2);

%# fuzzy clustering: probabilistic distribution
prob = rand(numPoints,numClasses);
prob = bsxfun(@rdivide, prob, sum(prob,2));

Now here is the code to plot a scatter of pie charts:

%# pie parameters
theta = linspace(0, 2*pi, 100); %# steps to approximate a circle
r = min(range(points)) / 10;    %# radius (determined based on points spread)

%# pie circles
px = bsxfun(@plus, cos(theta).*r, points(:,1))';
py = bsxfun(@plus, sin(theta).*r, points(:,2))';
px(end+1,:) = NaN; py(end+1,:) = NaN;

%# pie divisions
tt = cumsum(prob,2) .* 2*pi;
qx = cat(3, ...
    bsxfun(@plus, cos(tt).*r, points(:,1)), ...
    repmat(points(:,1), [1 numClasses]), ...
    NaN(numPoints,numClasses));
qy = cat(3, ...
    bsxfun(@plus, sin(tt).*r, points(:,2)), ...
    repmat(points(:,2), [1 numClasses]), ...
    NaN(numPoints,numClasses));
qx = permute(qx, [3 2 1]); qy = permute(qy, [3 2 1]);

%# plot
figure
line(px(:), py(:), 'Color','k')
line(qx(:), qy(:), 'Color','k')
axis equal


In my second attempt, I managed to plot colored pie charts by using PATCH function to draw each slice in every circle. Obviously, this implies we are creating a lot more graphics objects compared to before...

We could have used the same NaN technique to plot same slice from every circle using a single PATCH call, but it proved problematic when the pie charts overlap (specifically the z-order was not correct).

clr = hsv(numClasses);          %# colors for each class
r = min(range(points)) / 10;    %# radius (determined based on points spread)
tt = cumsum(prob,2) .* 2*pi;    %# pie divisions

figure
h = zeros(numPoints,numClasses);    %# handles to patches
for idx=1:numPoints                 %# for each point
    for k=1:numClasses              %# for each class
        %# start/end angle of arc
        if k>1
            t(1) = tt(idx,k-1);
        else
            t(1) = 0;
        end
        t(2) = tt(idx,k);

        %# steps to approximate an arc from t1 to t2
        theta = linspace(t(1), t(2), 50);

        %# slice (line from t2 to center, then to t1, then an arc back to t2)
        x = points(idx,1) + r .* [cos(t(2)) ; 0 ; cos(t(1)) ; cos(theta(:))];
        y = points(idx,2) + r .* [sin(t(2)) ; 0 ; sin(t(1)) ; sin(theta(:))];
        h(idx,k) = patch('XData',x, 'YData',y, ...
            'FaceColor',clr(k,:), 'EdgeColor','k');

        %# show percentage labels
        ind = fix(numel(theta)./2) + 3;     %# middle of the arc
        text(x(ind), y(ind), sprintf('%.2f%%', prob(idx,k)*100), ...
            'Color','k', 'FontSize',6, ...
            'VerticalAlign','middle', 'HorizontalAlign','left');
    end
end
axis equal

labels = cellstr( num2str((1:numClasses)', 'Cluster %d') );
legend(h(1,:), labels)

If the percentage labels are too much, simply remove the TEXT call above.

The Bubble Pie by Abraham Anderson on Matlab File Exchange seems like something relevant to what you are describing.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!