[英]Python: Is there a way to plot a “partial” surface plot with Matplotlib?
我想用Matplotlib繪制一個“部分”表面圖,如下圖所示
請注意,它不是XY平面上的完整網格網格,而是從頂視圖中缺少一個角。 以下是我試過的代碼,但沒有用。
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:使用序列設置數組元素。
任何指針將不勝感激! 謝謝!
您可以通過在不想繪制的區域中使用Z的np.nan
值來輕松完成此操作。 這是此示例的修改版本,但有剪切,如下所示:
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拋出。
編輯:請看tom10的答案。 他的解決方案通過將排除部分的值設置為np.nans來工作。
看起來像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],
])
這不是一個很好的解決方案,但它是一種方法。 我將以某種方式給你留下自動化“截止”的問題。
子陣列必須具有相同的長度。 例如:
X = np.array([[0,1,0,0],
[0,1,2,0],
[0,1,2,3]
])
等等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.