2017-04-19 40 views
1

我正在使用下面的代碼在pyplot中生成一個散點圖,我希望9個類中的每一個都以不同的顏色繪製。每個班級有多個點。Pyplot scatterplot圖例不適用於較小的樣本尺寸

我不明白爲什麼圖例不適用於較小的樣本量。

def plot_scatter_test(x, y, c, title): 
    data = pd.DataFrame({'x': x, 'y': y, 'c': c}) 
    classes = len(np.unique(c)) 
    colors = cm.rainbow(np.linspace(0, 1, classes)) 

    ax = plt.subplot(111) 
    for s in range(0,classes): 
     ss = data[data['c']==s] 
     plt.scatter(x=ss['x'], y=ss['y'],c=colors[s], label=s) 

    ax.legend(loc='lower left',scatterpoints=1, ncol=3, fontsize=8, bbox_to_anchor=(0, -.4), title='Legend') 
    plt.show() 

我的數據是這樣的

Data

當我通過調用

plot_scatter_test(test['x'], test['y'],test['group']) 

我得到的圖表中不同的顏色繪製這一點,但傳說是單一顏色

Chart 1

所以爲了確保我的數據正常,我使用相同類型的數據創建了一個隨機數據幀。現在我得到了不同的顏色,但由於它們不是連續的,所以還是有些問題。

test2 = pd.DataFrame({ 
    'y': np.random.uniform(0,1400,36), 
    'x': np.random.uniform(-250,-220,36), 
    'group': np.random.randint(0,9,36) 
}) 
plot_scatter_test(test2['x'], test2['y'],test2['group']) 

colors2

最後,我創建的360個數據點的更大的陰謀,一切看起來我希望它的方式。我究竟做錯了什麼?

test3 = pd.DataFrame({ 
    'y': np.random.uniform(0,1400,360), 
    'x': np.random.uniform(-250,-220,360), 
    'group': np.random.randint(0,9,360) 
}) 

plot_scatter_test(test3['x'], test3['y'],test3['group']) 

chart3

+0

您嘗試分配顏色的方式對我來說沒有意義。你能非常精確地知道顏色應該代表什麼? – ImportanceOfBeingErnest

+0

顏色只是每個組的任意視覺差異。我一直在仔細查看併發布它作爲答案,所以我碰巧找到了一個修復程序。 – ElPresidente

+0

這不是一個修復,請參閱我的答案。 – ImportanceOfBeingErnest

回答

1

你需要確保不要混淆類本身與您用於索引號。

爲了更好地觀察我的意思,使用下面的數據集與功能:

np.random.seed(22) 
X,Y= np.meshgrid(np.arange(3,7), np.arange(4,8)) 
test2 = pd.DataFrame({ 
    'y': Y.flatten(), 
    'x': X.flatten(), 
    'group': np.random.randint(0,9,len(X.flatten())) 
}) 
plot_scatter_test(test2['x'], test2['y'],test2['group']) 

這會導致下面的圖形,其中點丟失。

enter image description here

所以,賺了指數和類,例如有明顯的區別從它確實是沒有必要的顏色4元組提供直接c,因爲這如下

import numpy as np; np.random.seed(22) 
import matplotlib.pyplot as plt 
import pandas as pd 

def plot_scatter_test(x, y, c, title="title"): 
    data = pd.DataFrame({'x': x, 'y': y, 'c': c}) 
    classes = np.unique(c) 
    print classes 
    colors = plt.cm.rainbow(np.linspace(0, 1, len(classes))) 
    print colors 
    ax = plt.subplot(111) 
    for i, clas in enumerate(classes): 
     ss = data[data['c']==clas] 
     plt.scatter(ss["x"],ss["y"],c=[colors[i]]*len(ss), label=clas) 

    ax.legend(loc='lower left',scatterpoints=1, ncol=3, fontsize=8, title='Legend') 
    plt.show() 

X,Y= np.meshgrid(np.arange(3,7), np.arange(4,8)) 
test2 = pd.DataFrame({ 
    'y': Y.flatten(), 
    'x': X.flatten(), 
    'group': np.random.randint(0,9,len(X.flatten())) 
}) 
plot_scatter_test(test2['x'], test2['y'],test2['group']) 

enter image description here

除了將被解釋爲四個單顏色。

-1

我在這盯着一段時間後現在感覺很傻。錯誤是在顏色被傳遞。我正在向.scatter函數傳遞一個顏色。但是,由於有多個點,您需要傳遞相同數量的顏色。因此

plt.scatter(x=ss['x'], y=ss['y'],c=colors[s], label=s) 

可以是這樣的

plt.scatter(x=ss['x'], y=ss['y'],c=[colors[s]]*len(ss), label=s) 
+0

小心,這還是沒有意義,因爲你正在混合類與唯一類的索引。 – ImportanceOfBeingErnest

+0

我明白你的意思了。在我的數據中,我總是有從0到N連續的一系列組,所以我只是迭代索引。它在您的示例中失敗,因爲並非所有組都可能存在。您的答案是更完整的解決方案。謝謝。 – ElPresidente