2012-03-16 3 views
5

방금 ​​scipy 스택으로 시작합니다. 나는 CSV 버전에서 홍채 데이터 세트를 사용하고 있습니다. 내가 사용하여 잘로드 할 수 있습니다Pylab : 레이블을 색상으로 매핑하십시오.

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해야합니다 (또는 것과 유사한 보간 년 Colorbar를 사용하여 plot에 각 호출에 색상을 지정합니다 @ Yann은 위에 제안했다).

+0

감사합니다. 멀티 플롯팅 옵션을 보았지만 여기에서 사용한 우아한 트릭을 잘 모르고있었습니다 (+1). 나는 '산산이 (scatter)'에 대해 동의해야한다. 내 이해를 위해이 점은 포인트가 독립적이며 연결되지 않은 이런 유형의 플롯을 의미합니다 (linestyle = "none"을 설정하여 해결할 수 있습니다). –

+0

'plot' vs'scatter' 포인트는 불행한 점입니다. 일반적인 오해. 점을 그리려면'plot'을 사용하고, 3 번째 또는 4 번째 변수를 기반으로 마커의 크기 및/또는 색상을 연속적으로 변경해야하는 경우에만 'scatter'를 사용하여 사물을 그립니다. 'scatter'는 관리하기가 훨씬 더 어려운 콜렉션을 반환합니다. 'plot' _really is_ 연결 해제 된 점을 플롯하기위한 것입니다. 기본값은 단지 선이됩니다. 'plt.plot (x, y, 'o')'는'plt.plot (x, y, linestyle = 'none', marker = 'o')'와 같은 일을 할 것이다. . –

+0

감사합니다. 내 CSV에는 열 레이블 행이 없으므로'np.unique (iris.field (4))'를 사용합니다. 하지만 그 외에는 본질적으로 코드를 사용하고 있습니다. 나는 조건 트릭을 정말 좋아한다. –

5

여부는 다소 주관적이다. 나는 개인적으로 당신의 접근 방식이 'matplotlib'방식보다 나은 것으로 생각한다. 하기 matplotlib의 color 모듈 :

Colormapping는 일반적으로 두 가지 단계가 포함하는 데이터 배열의 정상화 또는 서브 클래스의 인스턴스를 이용하여 0-1 범위로 매핑 제이고; 0-1 범위의이 숫자는 Colormap의 하위 클래스 인스턴스를 사용하여 색상으로 매핑됩니다.

나는 당신의 문제와 관련하여 문자열을 취하여 0-1로 매핑하는 Normalize 하위 클래스가 필요하다는 점을 알아 냈습니다.

다음은 Normalize에서 상속되어 0에서 1 사이의 값으로 문자열을 변환하는 데 사용되는 TextNorm 하위 클래스를 만드는 예제입니다.이 정규화를 사용하여 해당 색상을 얻습니다.

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

내가 'RdYlGn'컬러 맵을 선택했다. __call__의 일부로 clip 기능을 포함하지 않았지만 몇 가지 수정이 가능합니다. ,

는 전통적으로 당신은 norm 키워드를 사용하여 scatter 방법의 정상화를 테스트 할 수 있지만 scatter는 않는 경우, 당신이 자신의 문자열 값과 같은 색상으로 전달하는 가정이 문자열을 저장하는 경우에 볼 수있는 c 키워드를 테스트하고 예 'Red', 'Blue'등. 따라서 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