2016-08-03 50 views
3

我有一个由2D矢量(X)表示的点的数据集。根据矢量值绘制符号

每个点属于由整数值(从1到4)表示的分类数据(Y)。

我想绘制每个点与不同的符号取决于它的类。

玩具例子:

X = randi(100,10,2); % 10 points ranging 1:100 in 2D space 
Y = randi(4,10,1);  % class of the points (1 to 4) 

我为每个类创建符号的载体:

S = {'bx' 'rx' 'b.' 'r.'}; 

然后我尝试:

plot(X(:,1), X(:,2), S(Y)) 


Error using plot 
Invalid first data argument 

我怎么能分配到的每个点X是基于Y值的不同符号?

诅咒我可以为每个班级使用一个循环,并逐个绘制不同的班级。但是有没有一种方法直接用不同的符号来绘制每个类?

回答

4

没有必要为一个循环,使用gscatter

X = randi(100,10,2); % 10 points ranging 1:100 in 2D space 
Y = randi(4,10,1);  % class of the points (1 to 4) 
color = 'brbr'; 
symbol = 'xx..'; 
gscatter(X(:,1),X(:,2),Y,color,symbol) 

您将得到: group scatter

+0

以前从未使用过它,所以没有考虑它......这显然是最好的答案! +1 =) –

+0

这正是我所期待的。谢谢 –

3

如果X有很多行,但只有几个S类型,那么我建议你先检查第二种方法。它针对速度而不是可读性进行了优化。如果矢量具有10个元素,则速度是其的两倍;如果矢量具有1000个元素,则速度是速度的200倍。


第一种方法(便于阅读):

不管的做法,我认为你需要这样的循环:

hold on 
arrayfun(@(n) plot(X(n,1), X(n,2), S{Y(n)}), 1:size(X,1)) 

或者写循环中的“常规方式“:

hold on 
for n = 1:size(X,1) 
    plot(X(n,1), X(n,2), S{Y(n)}) 
end 

enter image description here

第二条本办法(给出同样的情节如上):

如果你的数据集较大,您可以排序[Y_sorted, sort_idx] = sort(Y),然后用sort_idx索引X,像这样:X_sorted = X(sort_idx);。在此之后,您将X_sorted分为4个组,每个个人Y-值使用histcmat2cell。然后你循环四个组并分别绘制每一组。

这样,您只需循环四个值,而不管数据中元素的数量。如果元素数量很多,这应该会快很多。

[Y_sorted, Y_index] = sort(Y); 
X_sorted = X(Y_index, :); 
X_cell = mat2cell(X_sorted, histc(Y,1:numel(S))); 

hold on 
for ii = 1:numel(X_cell) 
    plot(X_cell{ii}(:,1),X_cell{ii}(:,2),S{ii}) 
end 

标杆:

我没有使用timeit这两种方法的一个非常简单的标杆。结果表明,第二种方法是快了很多:

对于10个元素:

First approach: 0.0086 
Second approach: 0.0037 

为1000个元素:

First approach = 0.8409 
Second approach = 0.0039 
+0

谢谢。实际上,不用排序,你可以得到与循环中正在处理的类相对应的X的值:'X(Y == i,:)'将返回属于类'i'的点。 –