2012-03-16 3 views
5

私はちょうどscipyスタックから始まっています。私はCSV版で虹彩データセットを使用しています。ピラブ:ラベルを色にマップする

iris=numpy.recfromcsv("iris.csv") 

し、それをプロットする:

pylab.scatter(iris.field(0), iris.field(1)) 
pylab.show() 

今、私もiris.field(4)に格納されているクラスを、プロットしたいと思います:

chararray(['setosa', ...], dtype='|S10') 

私はうまく使ってそれを読み込むことができますこれらの文字列をプロットするための色にマップするエレガントな方法は何ですか? scatter(iris.field(0), iris.field(1), c=iris.field(4))は動作しません(フロート値またはカラーマップが必要なドキュメントから)。私はカラーマップを自動的に生成するエレガントな方法を見つけられませんでした。

cols = {"versicolor": "blue", "virginica": "green", "setosa": "red"} 
scatter(iris.field(0), iris.field(1), c=map(lambda x:cols[x], iris.field(4))) 

お手数ですが、マニュアルカラー仕様があまり好きではありません。

編集:最後の行の少しよりエレガントなバージョン:

scatter(iris.field(0), iris.field(1), c=map(cols.get, iris.field(4))) 

答えて

4

は何のためにそれはあなたが一般的にそのような場合にはより多くのこのような何かをしたい、価値がありますデータ。

軸のカラーサイクルに頼ってプロットを複数回呼び出すほうが簡単です(コレクションの代わりに別のアーティストが表示されるなど、これは離散データにとっては良いことです)。

デフォルトでは、軸のカラーサイクルは青、緑、赤、シアン、マゼンタ、黄色、黒です。 plot

後7つの呼び出しは、それはサイクルが戻ってそれらの色の上に、あなたはより多くのアイテムを持っている場合ので、あなたはset it manuallyする必要があります(あるいは単にものと同様の補間カラーバーを使用してplotに各呼び出しで色を指定します@ Yannは上記で提案した)。

+0

ありがとうございます。私はマルチプロットのオプションを見ましたが、私はあなたがここで使用したエレガントな状態のトリック(+1)をまだ認識していませんでした。私は「ばらばら」について同意しなければなりません。私の理解では、それはポイントが独立していて、接続されていないこの種のプロットのためのものです( 'linestyle =" none "'を設定して回避する) –

+0

'plot'と' scatter'ポイントは不幸で、よくある誤解。点をプロットするには 'plot'を使用し、3番目または4番目の変数に基づいてマーカーのサイズや色を連続的に変更する必要がある場合は' scatter'を使ってプロットします。 'scatter'は、管理するのがはるかに難しいコレクションを返します。 'plot'_reallyは、切断された点をプロットすることを意図しています。デフォルトはちょうど線です。 'plt.plot(x、y、 'o')'は 'plt.plot(x、y、linestyle = 'none'、marker = 'o')'と同じことを行います。 。 –

+0

ありがとうございます。私は '' np.unique(iris.field(4)) 'を使用します(私のCSVには列ラベル行がないので)。しかし、それ以外は私は本質的にあなたのコードを使用しています。私は条件トリックが本当に好きです。 –

5

方法はやや主観的でエレガントかどうかを。私は個人的にあなたのアプローチが「matplotlib」のやり方より優れていると感じます。 matplotlibのcolorのモジュールから:

Colormappingは、典型的には2つのステップを含む:データアレイはノーマライズの又は サブクラスのインスタンスを使用して、範囲0~1にマッピング最初 あります。 0〜1の範囲にあるこの数値は、 を使用してColormapのサブクラスのインスタンスにマッピングされます。

私があなたの問題に関して取っているのは、Normalizeというサブクラスが必要で、文字列を受け取り0-1にマップする必要があるということです。

Normalizeから継承して、サブクラスをTextNormにする例です。これは、文字列を0から1までの値に変換するために使用されます。この正規化は、対応する色を取得するために使用されます。

import matplotlib.pyplot as plt 
from matplotlib.colors import Normalize 
import numpy as np 
from numpy import ma 

class TextNorm(Normalize): 
    '''Map a list of text values to the float range 0-1''' 

    def __init__(self, textvals, clip=False): 
     self.clip = clip 
     # if you want, clean text here, for duplicate, sorting, etc 
     ltextvals = set(textvals) 
     self.N = len(ltextvals) 
     self.textmap = dict(
      [(text, float(i)/(self.N-1)) for i, text in enumerate(ltextvals)]) 
     self.vmin = 0 
     self.vmax = 1 

    def __call__(self, x, clip=None): 
     #Normally this would have a lot more to do with masking 
     ret = ma.asarray([self.textmap.get(xkey, -1) for xkey in x]) 
     return ret 

    def inverse(self, value): 
     return ValueError("TextNorm is not invertible") 

iris = np.recfromcsv("iris.csv") 
norm = TextNorm(iris.field(4)) 

plt.scatter(iris.field(0), iris.field(1), c=norm(iris.field(4)), cmap='RdYlGn') 
plt.savefig('textvals.png') 
plt.show() 

これが生成します。

enter image description here

を、ポイントの3種類を区別することは容易であるように、私は「RdYlGn」カラーマップを選択しました。 __call__の一部としてclip機能は含まれていませんが、いくつか変更しても可能です。

伝統的に、あなたはnormキーワードを使用してscatter方法の標準化をテストすることができますが、scatterは、それは文字列を格納かどうかを確認するためにcキーワードをテストし、それがない場合、それは彼らの文字列値として使用すると、色で渡していると仮定し、例えば'赤'、 '青'など。したがって、plt.scatter(iris.field(0), iris.field(1), c=iris.field(4), cmap='RdYlGn', norm=norm)を呼び出すことはできません。代わりに、私はちょうどTextNormを使用し、iris.field(4)で "作動"して、0から1の範囲の値の配列を返します。

リストtextvalsに含まれていない刺しゅうの値が-1であることに注意してください。これはマスキングが便利になる場所です。

@Yannが提案するものは何も問題はありません
import numpy as np 
import matplotlib.pyplot as plt 

iris = np.recfromcsv('iris.csv') 
names = set(iris['class']) 

x,y = iris['sepal_length'], iris['sepal_width'] 

for name in names: 
    cond = iris['class'] == name 
    plt.plot(x[cond], y[cond], linestyle='none', marker='o', label=name) 

plt.legend(numpoints=1) 
plt.show() 

enter image description here

が、scatterが連続に適しています:

+0

私は例を書いています.... – Yann

+0

'R 'で同じことをしたので(ツールの概要を見てみると)、' unclass'に相当するものが ' 「scipy」。 –

+0

@ Anony-Mousseあなたのコメントであなたが何を求めているのか分かりません。どのように 'unclass'を使うのでしょうか、それを何に使うのでしょうか? – Yann

関連する問題