[英]Matplotlib -3D data visualization
我的實驗測量是在幾個txt文件中(實際上我會有數百個文件,但為了演示繪圖的想法,這里我只列出了3個文件,它們是d_401.txt、d_402.txt、d_403.txt)每個文件有 4 列和 256 行數據。 (只有第一列和第四列是我需要的 x 和 z 數據)
我想從這些文件中繪制 3D 曲面圖/或等高線圖。 在我的 3D 圖中,x 軸通常是每個文件的第 1 列數據,z 軸是每個文件的第 4 列數據(z 值也需要在漸變中進行顏色編碼),最后 y 軸是“從這三個文件中繪制的所有 xz 值的“y 方向排列”。
如何為這個圖生成 python 代碼? 我特別困惑如何分配矩陣 Z,如果有人能在這個問題上幫助我,我將不勝感激......我需要盡快繪制該圖。
我附上了我的早熟(據說全是錯誤代碼)
太感謝了!!!
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
z_txt = np.array(['d_401.txt', 'd_402.txt', 'd_403.txt'])
zarray = np.zeros([z_txt.size])
y = np.arange(3)
x = np.zeros(256)
Z = np.zeros((len(y),len(x)))
for i in range(z_txt.size):
zarray[i] = np.loadtxt(z_txt[i])
x[i] = zarray[i,0]
X, Y = np.meshgrid(x,y)
Z[i] = zarray[i,3]
ax.plot_surface(X, Y, Z, cmap=cm.magma, shade=True, lw=3)
plt.show()
以下假設所有文件都包含相同的x向量……
In [146]: import numpy as np
...: import matplotlib.pyplot as plt
...: from matplotlib.cm import ScalarMappable as sm
...: from glob import glob
...:
...: # create fake data and put it in files
...: x0, y0 = np.arange(11.0), np.arange(3)+1.0
...: z0 = x0+y0[:,None]
...: for i in range(3):
...: with open('delendo%d'%(i+1), 'w') as out:
...: for x0z0 in zip(x0, x0+x0, x0-x0, z0[i]):
...: print(*x0z0, sep='\t', file=out)
...:
...: # sorted list of "interesting" files
...: files = sorted(glob('delendo*'))
...:
...: # read the matrix of z values
...: Z = np.array([np.loadtxt(f, usecols=3) for f in files])
...: # read the vector of x values (the same for all files, I hope so!)
...: x = np.loadtxt(files[0], usecols=0)
...: # we have as many y's as rows in Z, and we count from 1
...: y = np.arange(Z.shape[0])+1
...:
...: # prepare for a 3D plot and plot as a surface
...: fig, ax = plt.subplots(constrained_layout=1,
...: subplot_kw={"projection" : "3d"})
...: surf = ax.plot_surface(*np.meshgrid(x,y), Z, cmap='magma')
...: norm = plt.Normalize(*surf.get_clim())
...: plt.colorbar(sm(norm=norm, cmap='magma'))
...: plt.show()
解決 OP 評論中提出的一些問題
您詢問*sequence
運算符。 它是解包運算符,可以在賦值或表達式中使用。 讓我們來看看
>>> tup = (1,2,3,4,5)
>>> a = tup ; print(a)
(1, 2, 3, 4, 5)
>>> a, b = tup
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
但是如果你使用 unpack 操作符
>>> a, *b = tup ; print(a, b)
1 [2, 3, 4, 5]
Python中了解到, b
是該序列的其余元素的順序和商店tup
-順便說一句, b
是一個列表不是一個元組。
unpack 操作符可以用在 left 成員的中間,但只能使用一次,因為 Python 將剩余的內容分配給帶星號的項目,而兩個帶星號的項目會導致歧義。
>>> a,*b, c = tup ; print(a, b, c)
1 [2, 3, 4] 5
>>> a,*b, *c = tup ; print(a, b, c)
File "<stdin>", line 1
SyntaxError: multiple starred expressions in assignment
現在,讓我們看看解包運算符在表達式中的作用
>>> print(*b)
2 3 4
使用星號語法解壓列表,就像
>>> print(b[0], b[1], b[2])
2 3 4
現在,回到您的問題,您已經在代碼中使用了解包。 即使你可能不知道它......
X, Y = np.meshgrid(x,y)
來到我的代碼
surf = ax.plot_surface(*np.meshgrid(x,y), Z, cmap='magma')
在這一點上應該很清楚,我們正在解包meshgrid
返回的meshgrid
,就像X, Y = meshgrid(...) ; surf = ...(X, Y, Z, ...)
X, Y = meshgrid(...) ; surf = ...(X, Y, Z, ...)
具有(小)優勢,即不引用網格數組 ( X, Y
) 並且它們使用的內存可以立即返回給解釋器。
關於您的最后一點,要創建顏色條 Matplotlib 需要所謂的標量可映射(sm),並且plt.colorbar
可以檢查活動軸以查看是否有 sm 掛在附近。
許多藝術家(繪制到 Axes 中的軟件代理)例如imshow
創建一個 sm 並且一切正常,但plot_surface
不會,因此可憐的程序員必須為colorbar
提供一個手工制作的 sm 。
要指定 sm,我們需要 ① 范數和 ② 顏色圖。
規范是默認值,即plt.Normalize
,我們需要Z
的限制,這些是surf.get_clim()
的值,我再次使用帶星號的語法來解壓這兩個值。
這個解釋的長度是首先省略它的理由......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.