彩色3D表面基于通过散点的类别

时间:2016-08-16 17:42:11

标签: python matlab matplotlib 3d plotly

我的数据格式如下:

X,Y,Z,类别

我使用plotly生成散点图,然后使用以下代码在散点图中拟合曲线。

from scipy.interpolate import griddata
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

x=np.asarray([3,5,9,3,3,7,6,9,1,9]);
y=np.asarray([4,3,3,10,8,2,4,10,9,3]);
z=np.asarray([1,2,4,10,1,7,10,3,1,7]);
# x = np.random.random(100)

xi=np.linspace(min(x), max(x),50)
#print xi
yi=np.linspace(min(y),max(y),50)


X,Y= np.meshgrid(xi,yi)
Z = np.nan_to_num(griddata((x,y), z, (X, Y), method='cubic'))

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False,alpha=0.4)
plt.show()

我想要做的是根据类似的类别为情节着色: enter image description here 其中红色代表类别1,蓝色代表类别2。 因此,为了获得这样的东西,我需要生成一个2D数组,然后使用colormap / colorscale来相应地为颜色着色。

以上输出是使用 XLSTAT 创建的,其中类别为第4列作为类别。

有人可以解释我如何生成Z数据,这将帮助我以不同的方式为类别着色?

我尝试过将2D矩阵划分为0和1的两半并得到类似的输出。

enter image description here

考虑以下样本数据:

x   y   z   Category
3   4   1   Cat 1
5   3   2   cat2
9   3   4   cat2
3   10  10  cat3
3   8   1   cat3
7   2   7   cat2
6   4   10  Cat 1
9   10  3   Cat 4
1   9   1   Cat 1
9   3   7   cat2

我需要生成2D数据,用自定义颜色表示不同类别的表面颜色和颜色

1 个答案:

答案 0 :(得分:1)

正如griddata可用于将1D z数组插值到2D网格一样,您可以使用griddata将1D color数组插值到同一个2D格:

color = [colormap[cat] for cat in category]
C = np.nan_to_num(griddata((x, y), color, (X, Y), method='cubic'))

然后,您可以使用色彩映射cm.coolwarmC中的值映射到RGBA facecolors

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cmap,
                linewidth=0, antialiased=False, alpha=0.4, facecolors=cmap(C))
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import scipy.interpolate as interpolate

x = np.asarray([3, 5, 9, 3, 3, 7, 6, 9, 1, 9])
y = np.asarray([4, 3, 3, 10, 8, 2, 4, 10, 9, 3])
z = np.asarray([1, 2, 4, 10, 1, 7, 10, 3, 1, 7])
category = np.array(['Cat 1', 'cat2', 'cat2', 'cat3', 'cat3',
                     'cat2', 'Cat 1', 'Cat 4', 'Cat 1', 'cat2'])
# coolwarm: 0 --> blue, 1 --> red
# want: 'Cat 1' --> blue, 'cat2' --> red, 'cat3' --> ?, 'Cat 4' --> ?
colormap = {'Cat 1': 0, 'cat2': 1, 'cat3': 0.333, 'Cat 4': 0.666}
color = np.array([colormap[cat] for cat in category])

xi = np.linspace(min(x), max(x), 50)
yi = np.linspace(min(y), max(y), 50)
X, Y = np.meshgrid(xi, yi)
Z = np.nan_to_num(interpolate.griddata((x, y), z, (X, Y), method='cubic'))
C = interpolate.griddata((x, y), color, (X, Y), method='cubic')

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
cmap = cm.coolwarm
ax.scatter(x, y, z, c=color, cmap=cmap)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cmap,
                linewidth=0, antialiased=False, alpha=0.4, facecolors=cmap(C))
plt.show()

enter image description here