我想用Matplotlib绘制一个“部分”表面图,如下图所示
请注意,它不是X-Y平面上的完整网格网格,而是从顶视图中缺少一个角落。以下是我试过的代码,但没有用。
import numpy as np
from matplotlib import pyplot
from mpl_toolkits.mplot3d import Axes3D
X = np.array([[0,1],
[0,1,2],
[0,1,2,3],
])
Y = np.array([[0,0],
[1,1,1],
[2,2,2,2],
])
Z = np.array([[0.5, 0.6],
[0.7, 0.8, 0.9],
[1.0, 1.1, 1.2, 1.3],
])
fig = pyplot.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,Z)
错误是:
ValueError:使用序列设置数组元素。
任何指针都会受到赞赏! 谢谢!
答案 0 :(得分:6)
您可以在不想要绘制的区域中使用Z的np.nan
值轻松完成此操作。这是this example的修改版本,但有剪切,如下所示:
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(.5*R)
Z[X+Y>4.] = np.nan # the diagonal slice
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
linewidth=0, antialiased=False, vmin=-1, vmax=1)
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
另请注意,我必须在plot命令中使用vmin
和vmax
关键字,否则颜色缩放将被nans抛出。
答案 1 :(得分:1)
看起来matplotlib的plot_surface不接受np.nans作为坐标,所以这也不起作用。如果我正确理解你的问题,那么我至少要提供一个胶带解决方案:
如果不像MEVIS3000建议的那样将“切出”点设置为零,而是将它们设置为该维度中的最后一个值,那么您的2d阵列将具有相同的大小,并且表面看起来就像它在那里切割一样。
我为您的示例添加了更多数据点以使其更清晰。这是起点(整个表面可见的地方):
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
X = np.array([[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
])
Y = np.array([[0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
])
Z = np.array([[0.5, 0.4, 0.35, 0.32, 0.312, 0.3],
[0.9, 0.7, 0.60, 0.55, 0.525, 0.5],
[1.0, 1.1, 1.20, 1.30, 1.400, 1.5],
])
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,Z)
plt.show()
现在,如果我们调整数组以便将“缺失”值替换为该行中的先前值,我们可以省略表面的一部分:
X = np.array([[0, 1, 2, 2, 2, 2], # Notice the sequence 0, 1, 2, 2, 2...
[0, 1, 2, 3, 3, 3], # Here starting from 3
[0, 1, 2, 3, 4, 4], # Here starting from 4
])
Y = np.array([[0, 0, 0, 0, 0, 0], # Here we don't need to do anything
[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
])
Z = np.array([[0.5, 0.4, 0.35, 0.35, 0.35, 0.35], # Here like in X: repeats from 0.35
[0.9, 0.7, 0.60, 0.55, 0.55, 0.55],
[1.0, 1.1, 1.20, 1.30, 1.40, 1.40],
])
这不是一个很好的解决方案,但它是一种方法。我将以某种方式让你自动解决“截止”问题。
答案 2 :(得分:0)
子阵列必须具有相同的长度。 e.g:
X = np.array([[0,1,0,0],
[0,1,2,0],
[0,1,2,3]
])
等等。