4

次のようなデータセット (ファイル名 'data') が あり、このデータを点としてプロットしたいと思います。私が試してみると: 5つのx軸値a、b、c、b、aを含むプロットを取得しますが、5つのy値すべてを含むプロットで3つ(a、b、c(順序は重要ではありません))のみを取得したい. 出来ますか?
a 10.1
b 10.1
c 10.2
b 15.56
a 3.20


plot 'data' using 2:xticlabels(1)

私の実際のデータ ファイルは次のように なります。約 1000 のレコードがあります。
2-8-16-17-18 962.623408
2-3-4-5-6 -97.527840
2-8-9-10-11 962.623408
2-8-9-10-11 937.101308
2-3-4-5-6 37.101308


mgilson のコードの使い方がわかりませんが、彼はアイデアをくれました。データ ファイルに追加の列 (インデックス) を追加します。

1 a 10.1 
2 b 10.1 
3 c 10.2 
2 b 15.56 
1 a 3.20
その後、gnuplot でのプロットは簡単です:
plot 'data' u 1:3

私はperlを使用しているので、スクリプトは次のようになります。

#!/usr/bin/perl 
$index_number = 0; 
while (<>) 
{ 
   $line = $_;
   @columns = split(" ",$line);
   $col1 = $columns[0];
   $col2 = $columns[1];
   if( not exists $non_numeric{$col1} )
   {
      $index_number++;
      $non_numeric{$col1} = $index_number;
   }
   print "".$non_numeric{$col1}."\t".$col1."\t".$col2."\n"; 
}
4

1 に答える 1

1

gnuplot のみの解決策を思いつくことができるとは思えません。ただし、システムに python2.5 以降がインストールされている限り、これは機能するはずです。(テストデータで動作します)。

import sys
import collections

data = collections.defaultdict(list)
keys = []

# build a mapping which maps values to xticlabels (hereafter "keys")
# Keep a second keys list so we can figure out the order we put things into
# the mapping (dict)
with open(sys.argv[1]) as f:
    for line in f:
        key,value = line.split()
        data[key.strip()].append( value )
        keys.append(key.strip())

def unique(seq):
    """
    Simple function to make a sequence unique while preserving order.
    Returns a list
    """
    seen = set()
    seen_add = seen.add
    return [ x for x in seq if x not in seen and not seen_add(x) ]

keys = unique(keys) #make keys unique

#write the keys alongside 1 element from the corresponding list.
for k in keys:
    sys.stdout.write( '%s %s\n' % (k, data[k].pop()) )

# Two blank lines tells gnuplot the following is another dataset
sys.stdout.write('\n\n')

# Write the remaining data lists in order assigning x-values
# for each list (starting at 0 and incrementing every time we get
# a new key)
for i,k in enumerate(keys):
    v = data[k]
    for item in v:
       sys.stdout.write( '%d %s\n' % (i, item) )

これをプロットするスクリプトは次のとおりです。

set style line 1 lt 1 pt 1
plot '<python pythonscript.py data' i 0 u 2:xticlabels(1) ls 1,\
     '' i 1 u 1:2 ls 1 notitle

これがどのように機能するかです。のようなことをするとplot ... u 2:xticlabels(1)、gnuplotはデータ ポイント (0 から始まる) に連続した整数 x 値を暗黙的に割り当てます。Python スクリプトは、この事実を利用するためにデータを再配置します。基本的に、最初の列の「キー」をそのキーに対応する要素のリストにマップするマッピングを作成します。つまり、ダミーのデータファイルでは、キー'a'は値のリストにマップされます[10.1, 3.2]. ただし、python 辞書 (マッピング) は順序付けされていません。したがって、順序を維持する2番目のリストを保持します(たとえば、軸が「c」、「a」、「b」ではなく「a」、「b」、「c」とラベル付けされるように)。必要なデータを印刷するために使用できるように、軸リストが一意であることを確認します。データを 2 パスで書き込みます。最初のパスでは、マッピング「キー」とともに各リストから 1 つの値のみを出力します。2 番目のパスでは、gnuplot が暗黙的に割り当てる x 値とともに、残りの値を出力します。2 つのデータセットの間に 2 つの空白行を挿入して、gnuplot がindexキーワード (ここではi)。それに応じて 2 つのデータセットをプロットする必要があります。最初に、プロット時に両方のパスが同じスタイルになるように線のスタイルを設定します。次に、xticlabels を使用してインデックス 0 (最初のデータセット) をプロットし、python スクリプトが計算した x 値、y 値のペアを使用してインデックス 1 をプロットします ( u 1:2)。説明が長くなって申し訳ありません (元のバージョンには少しバグがありました)。頑張って、gnuplotting をお楽しみください!

于 2012-08-26T17:17:54.207 に答える