2015-06-21 134 views
0

加入第四尺寸我想通過定義取決於變量的標記的橢圓率的第四維添加到散點圖。這有可能嗎?matplotlib散點圖:由標記形狀

編輯:

我想避免一個3D情節。在我看來,這些情節通常不是很有意義。

+0

前三個維度是什麼? x,y和顏色還是x,y,z?或x,y,大小? – xnx

回答

1

您可以直接放在Ellipse補丁到您的軸,在this matplotlib example證明。要適應它使用偏心作爲你的「第三維」),保持標記區恆:

from pylab import figure, show, rand 
from matplotlib.patches import Ellipse 
import numpy as np 
import matplotlib.pyplot as plt 
N = 25 

# ellipse centers 
xy = np.random.rand(N, 2)*10 
# ellipse eccentrities 
eccs = np.random.rand(N) * 0.8 + 0.1 

fig = plt.figure() 
ax = fig.add_subplot(111, aspect='equal') 

A = 0.1 
for pos, e in zip(xy, eccs): 
    # semi-minor, semi-major axes, b and a: 
    b = np.sqrt(A/np.pi * np.sqrt(1-e**2)) 
    a = A/np.pi/b 
    ellipse = Ellipse(xy=pos, width=2*a, height=2*b) 
    ax.add_artist(ellipse) 

ax.set_xlim(0, 10) 
ax.set_ylim(0, 10) 

show() 

enter image description here

當然,你需要在你的標記區域擴展到您的x,y值這個案例。

+0

是的,目前我正在玩這個想法。工作得很好。 – Moritz

1

您可以使用colorbar作爲第四層面,你的3D繪圖。一個例子如下所示:

import matplotlib.cm as cmx 
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 
import matplotlib 
import numpy as np 

def scatter3d(x,y,z, cs, colorsMap='jet'): 
    cm = plt.get_cmap(colorsMap) 
    cNorm = matplotlib.colors.Normalize(vmin=min(cs), vmax=max(cs)) 
    scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cm) 
    fig = plt.figure() 
    ax = Axes3D(fig) 
    ax.scatter(x, y, z, c=scalarMap.to_rgba(cs)) 
    scalarMap.set_array(cs) 
    fig.colorbar(scalarMap,label='Test') 
    plt.show() 

x = np.random.uniform(0,1,50) 
y = np.random.uniform(0,1,50) 
z = np.random.uniform(0,1,50) 

所以scatter3D(x,y,z,x+y)生產:

x+y在顏色被示出的第四尺寸。您可以根據您的特定變量而不是x+y添加計算出的橢圓率以獲得所需的值。

enter image description here

+0

有用的答案,但我想避免3D地塊 – Moritz

1

要改變,你將不得不手動創建爲這樣的功能尚未實現標記的橢圓。不過,我相信你可以通過使用顏色和大小作爲附加尺寸來顯示具有2D散點圖的4維。您必須自己照顧從數據到標記大小的縮放比例。我添加了一個簡單的函數來處理,在下面的例子:

import matplotlib.pyplot as plt 
import numpy as np 

data = np.random.rand(60,4) 

def scale_size(data, data_min=None, data_max=None, size_min=10, size_max=60): 

    # if the data limits are set to None we will just infer them from the data 
    if data_min is None: 
     data_min = data.min() 
    if data_max is None: 
     data_max = data.max() 

    size_range = size_max - size_min 
    data_range = data_max - data_min 

    return ((data - data_min) * size_range/data_range) + size_min 


plt.scatter(data[:,0], data[:,1], c=data[:,2], s=scale_size(data[:,3])) 
plt.colorbar() 
plt.show() 

結果:

enter image description here