2015-06-21 166 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