我在一系列值上有3个不同的参数X,Y和Z,并且对于这些的每个组合都有一个特定的V值。为了使它更清晰,数据看起来像这样。
X Y Z V
1 1 2 10
1 2 3 15
etc...
我希望用表面/轮廓图可视化数据,使用V作为颜色来查看该点的值,但我不知道如何使用Python将自定义着色方案添加到混合中。关于如何做到这一点的任何想法(或者这种可视化是完全愚蠢的)?
非常感谢!
答案 0 :(得分:3)
Matplotlib允许人们将facecolors作为参数传递给例如
ax.plot_surface
这意味着你必须对你进行二维插值 当前的颜色数组,因为您目前只有颜色 矩形面的角(你确实提到你有一个直线的面) 网格)。
你可以使用
scipy.interpolate.interp2d
为此,但正如您从文档中看到的那样,建议使用
scipy.interpolate.RectBivariateSpline
举个简单的例子:
import numpy as np
y,x = np.mgrid[1:10:10j, 1:10:10j] # returns 2D arrays
# You have 1D arrays that would make a rectangular grid if properly reshaped.
y,x = y.ravel(), x.ravel() # so let's convert to 1D arrays
z = x*(x-y)
colors = np.cos(x**2) - np.sin(y)**2
现在我有一个类似的数据集(x, y, z
和的一维数组
colors
)。备注为颜色定义
每个点(x,y)。但是当你想用plot_surface
进行情节绘制时,你就可以了
生成矩形块,其角由这些点给出。
所以,然后进行插值:
from scipy.interpolate import RectBivariateSpline
# from scipy.interpolate import interp2d # could 've used this too, but docs suggest the faster RectBivariateSpline
# Define the points at the centers of the faces:
y_coords, x_coords = np.unique(y), np.unique(x)
y_centers, x_centers = [ arr[:-1] + np.diff(arr)/2 for arr in (y_coords, x_coords)]
# Convert back to a 2D grid, required for plot_surface:
Y = y.reshape(y_coords.size, -1)
X = x.reshape(-1, x_coords.size)
Z = z.reshape(X.shape)
C = colors.reshape(X.shape)
#Normalize the colors to fit in the range 0-1, ready for using in the colormap:
C -= C.min()
C /= C.max()
interp_func = RectBivariateSpline(x_coords, y_coords, C.T, kx=1, ky=1) # the kx, ky define the order of interpolation. Keep it simple, use linear interpolation.
在最后一步中,您还可以使用interp2d
(kind='linear'
替换kx=1, ky=1
)。但由于文档建议使用速度更快
RectBivariateSpline
...
现在你准备好了:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.cm as cm
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
r = ax.plot_surface(X,Y,Z,
facecolors=cm.hot(interp_func(x_centers, y_centers).T),
rstride=1, cstride=1) # only added because of this very limited dataset
如您所见,面上的颜色与数据集的高度无关。
请注意,您可能只是想将2D数组C传递给facecolors
就可以了,而matplotlib也不会抱怨。但是,结果并不准确,因为matplotlib将仅使用C的一个子集作为facecolors(它似乎忽略了C的最后一列和最后一行)。它相当于仅使用一个坐标(例如左上角)定义的颜色而不是整个补丁。
更简单的方法是让matplotlib进行插值并获取facecolors然后将它们传递给真实的图:
r = ax.plot_surface(X,Y,C, cmap='hot') # first plot the 2nd dataset, i.e. the colors
fc = r.get_facecolors()
ax.clear()
ax.plot_surface(X, Y, Z, facecolors=fc)
但是,由于this recently submitted bug,该版本无法在版本< = 1.4.1中使用。
答案 1 :(得分:0)
这实际上取决于您计划如何绘制这些数据。我喜欢用gnuplot
绘制图表:它简单,自由,直观。要使用gnuplot
绘制示例,您必须将这些行打印到文件中(仅包含这四列),并使用如下代码进行绘图
reset
set terminal png
set output "out.png"
splot "file.txt" using 1:2:3:4 with lines palette
假设您将数据保存到文件file.txt
中。 splot
代表表面情节。当然,这是一个最低限度的例子。
或者您可以使用matplotlib
,但在我看来,这不是直观的。虽然它具有将所有处理集中在python中的优势。