2013-06-23 168 views
0

我需要在Pylab中創建一個圖形,其中我將繪製沿着Y軸的彩色點。 y軸從0到100. 我也有一個100個元素的列表,元素是+1或-1。 該列表必須與圖形的Y軸對應。例如,如果列表中的第五個元素是+1,我需要在Y軸上繪製y = 5的綠點。如果列表中的第五個元素是-1,則該點必須是紅色的。Pylab/Matplotlib圖形

我必須爲列表中的所有元素執行此操作。

我在Pylab中繪製了簡單的圖,但在這種情況下我完全失去了。 任何幫助將不勝感激。謝謝!!

回答

2
import matplotlib.pyplot as plt 
import numpy as np 

data = np.array([1,1,-1,-1,1]) 
cmap = np.array([(1,0,0), (0,1,0)]) 
uniqdata, idx = np.unique(data, return_inverse=True) 

N = len(data) 
fig, ax = plt.subplots() 
plt.scatter(np.zeros(N), np.arange(1, N+1), s=100, c=cmap[idx]) 
plt.grid() 
plt.show() 

產生

enter image description here


說明:

如果打印出來np.unique(data, return_inverse=True),你會看到它返回數組的一個元組:

In [71]: np.unique(data, return_inverse=True) 
Out[71]: (array([-1, 1]), array([1, 1, 0, 0, 1])) 

第一陣列說,在data唯一值是-1,並且無論是data 1.實質上1.第二陣列將值0的地方data是-1和值1,np.unique允許我們變換[1,1,-1,-1,1][1, 1, 0, 0, 1]。現在cmap[idx]是RGB值的數組:

In [74]: cmap[idx] 
Out[74]: 
array([[0, 1, 0], 
     [0, 1, 0], 
     [1, 0, 0], 
     [1, 0, 0], 
     [0, 1, 0]]) 

這是所謂的"fancy indexing" on NumPy arrays的應用程序。 cmap[0]cmap的第一行。 cmap[1]cmap的第二行。 cmap[idx]是一個數組,使得cmap[idx]中的第i個元素是cmap[idx[i]]。所以,最終cmap[idx]是一個二維數組,其中第i行是cmap[idx[i]]。因此cmap[idx]可以被認爲是RGB顏色值的序列。


如果你有一組以上的點,你想畫出他們在專欄中,我能想到的最簡單的方法是調用一次ax.scatterdata每個列表:

import matplotlib.pyplot as plt 
import numpy as np 

def plot_data(ax, data, xval): 
    N = len(data) 
    uniqdata, idx = np.unique(data, return_inverse=True) 
    ax.scatter(np.ones(N)*xval, np.arange(1, N+1), s=100, c=cmap[idx]) 

cmap = np.array([(1,0,0), (0,1,0)]) 
fig, ax = plt.subplots() 

data = np.array([1,1,-1,-1,1]) 
data2 = np.array([1,-1,1,1,-1]) 

plot_data(ax, data, 0) 
plot_data(ax, data2, 1) 

plt.grid() 
plt.show() 

enter image description here

這樣做的好處是它比較容易理解。壞消息是它多次呼叫ax.scatter。如果您有很多數據集,整理數據和調用ax.scatter一次會更高效。這是Matplotlib更快,但它多了幾分複雜的代碼:

import matplotlib.pyplot as plt 
import numpy as np 
import itertools as IT 

def plot_dots(ax, datasets): 
    N = sum(len(data) for data in datasets) 
    x = np.fromiter(
     (i for i, data in enumerate(datasets) for j in np.arange(len(data))), 
     dtype='float', count=N) 
    y = np.fromiter(
     (j for data in datasets for j in np.arange(1, len(data)+1)), 
     dtype='float', count=N) 
    c = np.fromiter(
     (val for data in datasets 
     for rgb in cmap[np.unique(data, return_inverse=True)[-1]] 
     for val in rgb), 
     dtype='float', count=3*N).reshape(-1,3) 
    ax.scatter(x, y, s=100, c=c) 

cmap = np.array([(1,0,0), (0,1,0)]) 
fig, ax = plt.subplots() 

N = 100 
datasets = [np.random.randint(2, size=5) for i in range(N)] 

plot_dots(ax, datasets) 

plt.grid() 
plt.show() 

enter image description here


參考文獻:

+0

非常感謝!我試圖在Pylab中做這樣的事情,但我一直在得到其他東西 – user2509830

+0

一個更快的問題,我自己的參考。 所以cmap是用於顏色的,對吧? 另外,什麼是numpy.unique()告訴python做? – user2509830

+0

最後,如果我想以同樣的方式繪製另一個列表,以便這些點距離第一組點較遠,那麼我該怎麼做?它不斷繪製第一組點的圖形兩次 – user2509830