python - Matplotlib -3D 数据可视化
问题描述
我的实验测量在几个 txt 文件中(实际上我会有数百个文件,但为了演示绘图的想法,这里我只列出了 3 个文件,它们是 d_401.txt、d_402.txt、d_403.txt)每个文件有 4 列和 256 行数据。(只有第一列和第四列是我需要的 x 和 z 数据)
我想从这些文件中绘制一个 3D 曲面图/或等高线图。在 My 3D plot 中,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向量……</p>
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
运营商。它是unpack运算符,可以在赋值或表达式中使用。让我们来看看
>>> 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)
但是如果你使用解包操作符
>>> 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
现在,让我们看看 unpack 运算符在表达式中的作用
>>> print(*b)
2 3 4
使用星号语法解包列表,就像
>>> print(b[0], b[1], b[2])
2 3 4
现在,谈到您的问题,您已经在代码中使用了解包。即使你可能不知道......</p>
X, Y = np.meshgrid(x,y)
来到我的代码
surf = ax.plot_surface(*np.meshgrid(x,y), Z, cmap='magma')
在这一点上应该很清楚,我们正在解包返回的内容meshgrid
,这就像网格数组( )没有被引用并且它们使用的内存可以立即返回给解释器X, Y = meshgrid(...) ; surf = ...(X, Y, Z, ...)
的(小)优势一样。X, Y
关于您的最后一点,要创建颜色条 Matplotlib 需要所谓的标量可映射(sm),并且plt.colorbar
可以检查活动轴以查看是否有 sm 挂在附近。
许多艺术家(吸引到 Axes 的软件代理)喜欢imshow
创建一个 sm,一切都很好,但plot_surface
不会,所以可怜的程序员必须提供一个手工制作的 sm 到colorbar
.
要指定 sm,我们需要①一个规范和②一个颜色图。
规范是默认值,即 ,plt.Normalize
我们需要 的限制,Z
这些是 的值surf.get_clim()
,我再次使用星号语法来解包这两个值。
这个解释的长度是首先省略它的理由......</p>
推荐阅读
- python - Numpy 数组在编码和写入文件时以某种方式被破坏
- c++ - 如何从离线配置单元中读取注册表
- javascript - 如何从两个设备方向事件中找到用于控制 2D 游戏的相对滚动和俯仰角
- excel - Fix (force) loop to protect/unprotect/hide/show worksheets
- python - 如何将 pd.to_datetime() 用于具有年-月-日时:分:秒数据的列?
- android - SubArray 不会显示值
- bash - 预定事件的 Bash 条件
- javascript - 我想在使用 vanila javascript(无框架,无库)单击禁用按钮时显示工具提示
- javascript - SameSite cookie 未在后台调用中传递
- html - 每个 SVG 下方的可点击空白