简体   繁体   English

Matplotlib -3D 数据可视化

[英]Matplotlib -3D data visualization

here is example of one txt file这是一个 txt 文件的示例

My experiment measurements are in several txt files (in reality I will have hundreds of files, but to demonstrate the idea of plotting, here I only list out 3 files, they are d_401.txt, d_402.txt, d_403.txt) each file has 4 columns & 256 rows of data.我的实验测量是在几个txt文件中(实际上我会有数百个文件,但为了演示绘图的想法,这里我只列出了3个文件,它们是d_401.txt、d_402.txt、d_403.txt)每个文件有 4 列和 256 行数据。 (only the first & forth column are the data I need for x and z) (只有第一列和第四列是我需要的 x 和 z 数据)

I want to plot a 3D surface plot/or contour plot out of these files.我想从这些文件中绘制 3D 曲面图/或等高线图。 In My 3D plot, x-axis is universally the 1st column data from each file, z-axis is the 4th column data from each file (z value also needs to be color-coded in gradient), and finally y-axis is "line-up in y direction" of all the xz values plot from these three files.在我的 3D 图中,x 轴通常是每个文件的第 1 列数据,z 轴是每个文件的第 4 列数据(z 值也需要在渐变中进行颜色编码),最后 y 轴是“从这三个文件中绘制的所有 xz 值的“y 方向排列”。

How to generate the python code for this plot?如何为这个图生成 python 代码? I'm especially confused how to assign the matrix Z, would greatly appreciate if somebody could help me on this issue...I need to have the figure plotted soon.我特别困惑如何分配矩阵 Z,如果有人能在这个问题上帮助我,我将不胜感激......我需要尽快绘制该图。

I attached my pre-mature (supposedly full of error code)我附上了我的早熟(据说全是错误代码)

Thanks a million!!!太感谢了!!!

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()

The following in the hypotesis that all the files contain the same vector of x以下假设所有文件都包含相同的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()

在此处输入图片说明


Addendum附录

to address some questions raised in comment from OP解决 OP 评论中提出的一些问题

You ask about the *sequence operator.您询问*sequence运算符。 It is the unpack operator, that can be used either in an assignment or in an expression.它是解包运算符,可以在赋值或表达式中使用。 Let's see让我们来看看

>>> 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)

But if you use the unpack operator但是如果你使用 unpack 操作符

>>> a, *b = tup ; print(a, b)
1 [2, 3, 4, 5]

Python understand that b is a sequence and stores in this sequence the remaining elements of tup — incidentally, b is a list not a tuple. Python中了解到, b是该序列的其余元素的顺序和商店tup -顺便说一句, b是一个列表不是一个元组。

The unpack operator can be used in the middle of a left member, but just once because Python assign to the starred item what is left , and two starred items lead to ambiguity. 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

Now, let's see the unpack operator at work in an expression现在,让我们看看解包运算符在表达式中的作用

>>> print(*b)
2 3 4 

using the starred syntax the list is unpacked, it's like使用星号语法解压列表,就像

>>> print(b[0], b[1], b[2])
2 3 4

Now, coming to your question, you have already used unpacking in your code.现在,回到您的问题,您已经在代码中使用了解包。 even if you possibly was not aware of it…即使你可能不知道它......

    X, Y = np.meshgrid(x,y)

Coming to my code来到我的代码

surf = ax.plot_surface(*np.meshgrid(x,y), Z, cmap='magma')

at this point it should be clear, we are unpacking what is returned by meshgrid , it's like X, Y = meshgrid(...) ; surf = ...(X, Y, Z, ...)在这一点上应该很清楚,我们正在解包meshgrid返回的meshgrid ,就像X, Y = meshgrid(...) ; surf = ...(X, Y, Z, ...) X, Y = meshgrid(...) ; surf = ...(X, Y, Z, ...) with the (small) advantage that the grid arrays ( X, Y ) are not referenced and the memory they use can be immediately given back to the interpreter. X, Y = meshgrid(...) ; surf = ...(X, Y, Z, ...)具有(小)优势,即不引用网格数组 ( X, Y ) 并且它们使用的内存可以立即返回给解释器。

With respect to your last point, to create a colorbar Matplotlib needs what is called a scalar mappable (sm) and plt.colorbar can check the active Axes to see if there is a sm hanging around.关于您的最后一点,要创建颜色条 Matplotlib 需要所谓的标量可映射(sm),并且plt.colorbar可以检查活动轴以查看是否有 sm 挂在附近。
Many Artists (the software agents that draw into the Axes) like eg, imshow create a sm and all is well, but plot_surface won't, so the poor programmer has to provide a hand-made sm to colorbar .许多艺术家(绘制到 Axes 中的软件代理)例如imshow创建一个 sm 并且一切正常,但plot_surface不会,因此可怜的程序员必须为colorbar提供一个手工制作的 sm 。
To specify a sm we need ① a norm and ② a colormap.要指定 sm,我们需要 ① 范数和 ② 颜色图。
The norm is the default, ie, plt.Normalize , we need the limits of Z and these are the value of surf.get_clim() , again I used the starred syntax to unpack the two values.规范是默认值,即plt.Normalize ,我们需要Z的限制,这些是surf.get_clim()的值,我再次使用带星号的语法来解压这两个值。

The length of this explanation is a justification for having it omitted in the first place…这个解释的长度是首先省略它的理由......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM