簡體   English   中英

Python:有沒有辦法用Matplotlib繪制“部分”曲面圖?

[英]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命令中使用vminvmax關鍵字,否則顏色縮放將被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()

結果表面看起來像這樣(從上面看): 圖1:表面包含原始數據

現在,如果我們調整數組以便將“缺失”值替換為該行中的先前值,我們可以省略表面的一部分:

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:右下角切出

這不是一個很好的解決方案,但它是一種方法。 我將以某種方式給你留下自動化“截止”的問題。

子陣列必須具有相同的長度。 例如:

X = np.array([[0,1,0,0],
              [0,1,2,0],
              [0,1,2,3]
             ])

等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM