2016-10-19 2 views
1

私は、整数ベクトルの値に基づいて色を変える縦線の条件付きプロットを行いたいと思っています。これらの値は、0〜4の範囲の整数です。Matlab:ループで行われる条件付きプロットはベクトル化できますか?

現在、私はループを使ってテーブルを通って線をプロットしています。これは動作しますが、大量のデータには時間がかかります。ベクター化できるかどうかは疑問です。

添付されているのは、単純にベクトルをループするデータベクトル(サンプル)をループするためのスクリプトを取り除いたもので、整数の値に基づいて垂直線をプロットします。

また、私が作成したシンプルな変数 'SAMPLE'を添付してワークスペースに貼り付けます。

for i=1:size(sample,1) 
    if  sample(i)==1 
     line([i i] ,[0 10], 'Marker','.','LineStyle','-','Color','r'); 
    elseif sample(i)==2 
     line([i i] ,[0 10], 'Marker','.','LineStyle','-','Color','b'); 
    elseif sample(i)==3 
     line([i i] ,[0 10], 'Marker','.','LineStyle','-','Color',[1 .5 0]); 
    elseif sample(i)==4 
     line([i i] ,[0 10], 'Marker','.','LineStyle','-','Color','g'); 
    end 
end 
変数

sample=[[3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0]]; 

しかし、このようにプロットする「ベクトル化」に可能です/私が行っているように、ループで繰り返しそれを行うには持っOのw?

Picture of Desired Output

答えて

2

はラインをプロットするとき、MATLABは値NaNでポイントをスキップするという事実を利用してください。

% Your vector 
sample=[3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;0;0;0]; 

% Your colors 
colors = [ 
    1 0 0 
    0 0 1 
    1 .5 0 
    0 1 0]; 

for idx = 1:4 
    % Find the index of each of your integers 
    X = find(sample == (idx)); 

    % Force X to be a row vector 
    X = X(:)'; 

    % Stack two X's on top of one another with a third row filled 
    % with NaNs. Fill in your Y values in the same way while 
    % you're at it. 
    Y = [zeros(size(X)); 10 + zeros(size(X)); nan(size(X))]; 
    X = [X; X; nan(size(X))]; %#ok<AGROW> 

    % Matlab is column major. By using the colon here, you 
    % produce a vector that is [X1 X1 nan X2 X2 nan ... etc.] 
    X = X(:); 
    Y = Y(:); 

    % Draw the line 
    line(X, Y, 'Marker', '.', 'LineStyle', '-', 'Color', colors(idx, :)) 
end 

まだループがありますが、今ではベクトルの各値をループするのではなく、可能な値をループしています。私はあなたがこれがはるかに優れていることがわかるでしょう。

に入力を変更:OPコードは1.4861秒でベンチマークながら

sample = zeros(1, 1e6); 
for idx = 1:4 
    sample(randi(1e6, 1, 1000)) = idx; 
end 

timeitでベンチマークは、私のマシン上0.0065706秒の時間を与えます。

+0

うわー!それは間違いなく効率的で、私が探していたラインに沿っています。前に使用したベンチマークを使って、それを実行するのに約3秒かかりました。このmodで同じデータを使用すると、0.007036秒かかりました。したがって、〜400倍速くなります。 :) – pelt

1

私のようなものに変更したい:

colors=[1 0 0, 
     0 1 0, 
     1 0.5 0, 
     0 0 1]; 

nnsamples=samples(samples~=0); 

for ii=1:size(nnsamples,1) 

     line([ii ii] ,[0 10], 'Marker','.','LineStyle','-','Color',colors(nnsamples(ii),:)); 

end 
+0

ありがとう、私は今行っていたことのよりコンパクトなフォームですので、私は現在のスクリプトにこれらの変更を追加します。しかし、私はそれが処理される効率を何とか向上させるためにループをすべて一緒に削除することが可能かどうかまだ疑問に思っていますか?たとえば170Kの値でテストすると、両方のタイプはわずか3秒で処理されます。 – pelt

+0

170Kは3秒でプロットしますか?それは速いです@pelt –

+0

@peltは私の編集と速いかどうかをチェックします。 –