根据矢量值绘制符号
Plot symbols depending on vector values
我有一个由二维向量 (X) 表示的点的数据集。
每个点都属于用整数值(从 1 到 4)表示的分类数据 (Y)。
我想根据 class.
用不同的符号绘制每个点
玩具示例:
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)
我为每个 class:
创建一个符号向量
S = {'bx' 'rx' 'b.' 'r.'};
那我试试:
plot(X(:,1), X(:,2), S(Y))
Error using plot
Invalid first data argument
如何根据 Y 的值为 X 的每个点分配不同的符号?
Of curse 我可以为每个 class 使用一个循环,并一一绘制不同的 classes。但是有没有一种方法可以直接用不同的符号绘制每个 class?
如果X
的行数很多,但是S
的类型很少,那我建议你先看看第二种方法。它针对速度而不是可读性进行了优化。如果向量有 10 个元素,速度大约是原来的两倍;如果向量有 1000 个元素,速度大约是原来的 200 倍。
第一种方法(易于阅读):
无论采用哪种方法,我认为您都需要一个循环:
hold on
arrayfun(@(n) plot(X(n,1), X(n,2), S{Y(n)}), 1:size(X,1))
或者,在"conventional way"中编写循环:
hold on
for n = 1:size(X,1)
plot(X(n,1), X(n,2), S{Y(n)})
end
第二种方法(给出与上面相同的图):
如果你的数据集很大,你可以排序[Y_sorted, sort_idx] = sort(Y)
,然后使用sort_idx
索引X
,像这样:X_sorted = X(sort_idx);
。在此之后,您使用 histc
和 mat2cell
将 X_sorted
分成 4 组,每个 Y
值对应一组。然后你遍历这四个组并单独绘制每个组。
这样你只需要遍历四个值,而不管你的数据中有多少元素。如果元素数量很多,这应该会快很多。
[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
不需要循环,使用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)
你会得到:
我有一个由二维向量 (X) 表示的点的数据集。
每个点都属于用整数值(从 1 到 4)表示的分类数据 (Y)。
我想根据 class.
用不同的符号绘制每个点玩具示例:
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)
我为每个 class:
创建一个符号向量S = {'bx' 'rx' 'b.' 'r.'};
那我试试:
plot(X(:,1), X(:,2), S(Y))
Error using plot
Invalid first data argument
如何根据 Y 的值为 X 的每个点分配不同的符号?
Of curse 我可以为每个 class 使用一个循环,并一一绘制不同的 classes。但是有没有一种方法可以直接用不同的符号绘制每个 class?
如果X
的行数很多,但是S
的类型很少,那我建议你先看看第二种方法。它针对速度而不是可读性进行了优化。如果向量有 10 个元素,速度大约是原来的两倍;如果向量有 1000 个元素,速度大约是原来的 200 倍。
第一种方法(易于阅读):
无论采用哪种方法,我认为您都需要一个循环:
hold on
arrayfun(@(n) plot(X(n,1), X(n,2), S{Y(n)}), 1:size(X,1))
或者,在"conventional way"中编写循环:
hold on
for n = 1:size(X,1)
plot(X(n,1), X(n,2), S{Y(n)})
end
第二种方法(给出与上面相同的图):
如果你的数据集很大,你可以排序[Y_sorted, sort_idx] = sort(Y)
,然后使用sort_idx
索引X
,像这样:X_sorted = X(sort_idx);
。在此之后,您使用 histc
和 mat2cell
将 X_sorted
分成 4 组,每个 Y
值对应一组。然后你遍历这四个组并单独绘制每个组。
这样你只需要遍历四个值,而不管你的数据中有多少元素。如果元素数量很多,这应该会快很多。
[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
不需要循环,使用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)
你会得到: