在matplotlib中对3D曲线进行着色



我有4个长度为n的数组x,y,zT,我想使用matplotlib绘制3D曲线。(x, y, z)是点的位置,T是每个点的值(用颜色表示),就像每个点的温度一样。我该怎么做呢?

示例代码:

import numpy as np
from matplotlib import pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
n = 100
cmap = plt.get_cmap("bwr")
theta = np.linspace(-4 * np.pi, 4 * np.pi, n)
z = np.linspace(-2, 2, n)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
T = (2*np.random.rand(n) - 1)  # All the values are in [-1, 1]

我在网上找到的:

  • 可以使用cmapscatter,如在文档和在这个stackoverflow问题
ax = plt.gca()
ax.scatter(x, y, z, cmap=cmap, c=T)

问题是scatter是一组点,而不是一条曲线。

  • 在这个stackoverflow问题中,解决方案被划分为n-1间隔,每个间隔我们使用不同的颜色,如
t = (T - np.min(T))/(np.max(T)-np.min(T))  # Normalize
for i in range(n-1):
plt.plot(x[i:i+2], y[i:i+2], z[i:i+2], c=cmap(t[i])

问题是每个片段只有一种颜色,但它应该是渐变的。最后一个值甚至没有使用。

的有用链接:

  • Matplotlib - Colormaps
  • Matplotlib - Tutorial 3D

在这种情况下您可能需要使用Line3DCollection。这是配方:

  1. 从你的坐标数组中创建段。
  2. 创建Line3DCollection对象
  3. 将集合添加到轴上。
  4. 设置轴限制。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Line3DCollection
from matplotlib.cm import ScalarMappable
from matplotlib.colors import Normalize
def get_segments(x, y, z):
"""Convert lists of coordinates to a list of segments to be used
with Matplotlib's Line3DCollection.
"""
points = np.ma.array((x, y, z)).T.reshape(-1, 1, 3)
return np.ma.concatenate([points[:-1], points[1:]], axis=1)
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
n = 100
cmap = plt.get_cmap("bwr")
theta = np.linspace(-4 * np.pi, 4 * np.pi, n)
z = np.linspace(-2, 2, n)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
T = np.cos(theta)
segments = get_segments(x, y, z)
c = Line3DCollection(segments, cmap=cmap, array=T)
ax.add_collection(c)
fig.colorbar(c)
ax.set_xlim(x.min(), x.max())
ax.set_ylim(y.min(), y.max())
ax.set_zlim(z.min(), z.max())
plt.show()