散点图 [英] Scatter pie plot
问题描述
我正在尝试可视化软集群.点很多,簇很少,每个点以一定的概率属于每个簇.
I'm trying to visualize a soft clustering. There are a number of points and a small number of clusters, each point belongs to each cluster with some probability.
目前,我正在为每个聚类叠加一个散点图,"o"标记的大小随概率而变化.这样可以轻松识别最可能的群集,但除此之外没有太多.
Currently, I'm overlaying a scatterplot for each cluster, with the size of 'o' markers varying by the probability. This allows easy identification of the most probable cluster, but not much beyond that.
我想绘制饼图的散点图,即为多个数据点中的每个数据点绘制一个小饼图,以显示这些概率.在Matlab中有可能吗?我还没有找到一种方法来绘制饼图作为标记或将多个饼图放置在一个图中的任意位置...
I'd like to draw a scatterplot of pie charts, i.e. one small pie chart for each of the many data points, showing these probabilities. Is that possible in Matlab? I haven't found a way to draw pies as markers or place multiple pie charts at arbitrary positions in one plot…
推荐答案
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.
这在性能方面非常有效.这是通过使用NaN
将行分成几段来实现的.将此与其他建议的解决方案进行比较;如果我们查看其源代码,就会发现它为每个点创建一个轴,并调用MATLAB的函数 PIE 在里面.
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
在第二次尝试中,我通过使用 PATCH来绘制彩色饼图函数可绘制每个圆圈中的每个切片.显然,这意味着我们要比以前创建更多的图形对象...
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...
我们本可以使用相同的NaN
技术通过单个PATCH调用从每个圆绘制相同的切片,但是事实证明,当饼图重叠时(特别是z顺序不正确),这是有问题的.
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)
如果百分比标签过多,只需删除 TEXT 致电上方.
If the percentage labels are too much, simply remove the TEXT call above.
这篇关于散点图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!