我正在尝试读取流数据并将数据分发到网格文件中以进行最终绘图。我有一个用于处理的 MATLAB 代码,它运行成功。我需要将此代码传输到 Python 中,但我是初学者。调试时总是崩溃,谁能告诉我我做错了什么?提前感谢!
数据文件(总共约100mb(:
https://www.dropbox.com/sh/3gtsmatq56pm0gc/AADUnNLjdrELjvdUy4wtDiiBa?dl=0
MATLAB 代码
%% Read Grid grid file is used as a guide for the positon where data is put
fid = fopen('FLOW_phys_GRID_1.xyz', 'r');
a = fread(fid, 3, 'int');
Nx = a(1); % number of points in x direction
Ny = a(2); % number of points in y direction
Nz = a(3); % numebr of points in z direction
xx = fread(fid, Nx*Ny*Nz, 'float');
yy = fread(fid, Nx*Ny*Nz, 'float');
xx = reshape(xx, [Nx, Ny]);
yy = reshape(yy, [Nx, Ny]);
fclose(fid);
x = squeeze(xx(:,1));
y = squeeze(yy(1,:));
%% Read Data
fid = fopen('FLOW_phys.raw', 'r'); %flow data in binary format
a = fread(fid, 3, 'int');
Nx = a(1); % number of points in x direction
Ny = a(2); % number of points in y direction
Nz = a(3); % number of points in z direction
Ma = fread(fid, 1, 'float');
some_num = fread(fid, 1, 'float');
Re = fread(fid, 1, 'float');
time = fread(fid, 1, 'float');
xx1 = fread(fid, 2*Nx*Ny*Nz, 'float');
xx1 = reshape(xx1, [Nx, 2*Ny, Nz]);
fclose(fid);
[XX, YY] = meshgrid(x, y);
% plot (squeeze(xx1(2,:,1)));
h = pcolor(XX, YY, squeeze(xx1)');
set(h, 'EdgeColor', 'none');
colorbar
蟒蛇代码:
import struct
import numpy
import matplotlib
unpackformat_int = '<i'
unpackformat_flo = '<f'
fid = open('FLOW_phys_GRID_1.xyz', 'r+')
Nx = struct.unpack(unpackformat_int,fid.read(4))[0]
Ny = struct.unpack(unpackformat_int,fid.read(4))[0]
Nz = struct.unpack(unpackformat_int,fid.read(4))[0]
aa = Nx*Ny*Nz
xx = struct.unpack('i'*aa, fid.read(aa*4))[0]
yy = struct.unpack('i'*aa, fid.read(aa*4))[0]
xx = xx.reshape([Nx, Ny])
yy = yy.reshape([Nx, Ny])
fid.close()
fid = open('FLOW_phys.raw', 'r+')
Nx = struct.unpack(unpackformat_int,fid.read(4))[0]
Ny = struct.unpack(unpackformat_int,fid.read(4))[0]
Nz = struct.unpack(unpackformat_int,fid.read(4))[0]
Ma = struct.unpack(unpackformat_flo, fid.read(4))[0]
some = struct.unpack(unpackformat_flo, fid.read(4))[0]
Re = struct.unpack(unpackformat_flo, fid.read(4))[0]
time = struct.unpack(unpackformat_flo, fid.read(4))[0]
bb = Nx*Ny*Nz
xx1 = struct.unpack('f'*bb, fid.read(bb*4))[0]
xx2 = struct.unpack('f'*bb, fid.read(bb*4))[0]
xx1 = xx1.reshape([Nx, Ny, Nz])
xx2 = xx2.reshape ([Nx, Ny, Nz])
fid.close()
[XX, YY] = numpy.meshgrid(xx, yy)
matplotlib.plot(XX,YY,xx2)
如果没有特定的错误消息,很难说。 但是,我看到了一系列可能的问题。
第一:
fid = open('FLOW_phys_GRID_1.xyz', 'r+')
这应该是'rb'
,意思是"读取二进制"。这是一个二进制文件,而不是文本文件。 'r+'
的意思是"读写",但你不是在写作。 另外,您应该始终使用 with open('FLOW_phys_GRID_1.xyz', 'r+') as fid:
,因为这会在您完成文件后自动安全地关闭文件。
此外,在 MATLAB 中,打开的文件由特殊编号表示,这些数字向 MATLAB 解释器标识文件。 然而,在 Python 中,它们是不同的对象,所以为了更好地记住这一点,最好使用 fobj
而不是 fid
作为变量名。
下一个:
xx = struct.unpack('i'*aa, fid.read(aa*4))[0]
yy = struct.unpack('i'*aa, fid.read(aa*4))[0]
在 MATLAB 中,你可以将其读作浮点数,但在 python 中,你可以将其读作整数。 更重要的是,您正在读取aa
数字,但[0]
只保留第一个数字。 在 MATLAB 中,您可以保留所有这些。
下一个:
xx = xx.reshape([Nx, Ny])
yy = yy.reshape([Nx, Ny])
unpack
返回一个元组,该元组本质上是一维的。 它没有reshape
方法,这是 numpy 数组所具有的,但不是 python 列表或元组。 您需要使用 xx = np.array(xx).reshape([Nx, Ny])
之类的东西将 xx
和 yy
转换为 numpy 数组,或者最好使用 numpy 的fromfile
,例如 xx = np.fromfile(fid, dtype='float', count=aa)
。 这会直接将数据作为 numpy 数组读取。
事实上,我建议你在任何地方都使用它。 获得Nx
、Ny
和Nz
的部分可以简化为Nx, Ny, Nz = np.fromfile(fid, dtype='i', count=3)
。 该语法实际上也适用于unpack
,但是在处理文件时,numpy方法稍微简单一些。
此外,numpy 和 MATLAB 中的维度顺序也不同。 numpy(默认情况下(使用从 C 编程语言数组派生的排序,而 MATLAB 专门使用 Fortran 编程语言的排序。 因此,要在 Python 中获得与 MATLAB 中相同的数组形状,您需要将第一个反转为轴,以便reshape([Ny, Nx])
,或稍后reshape([Ny, Nx, Nz])
。
此外,这仅在Nz
始终为 1 时才有效。 如果是任何其他数字,即使在 MATLAB 中也会失败。
接下来,从 MATLAB 代码:
x = squeeze(xx(:,1));
y = squeeze(yy(1,:));
你永远不会在 Python 中这样做。 这也意味着 Python 中的以下部分与你在 MATLAB 中所做的不同:
[XX, YY] = numpy.meshgrid(xx, yy)
下一个:
bb = Nx*Ny*Nz
xx1 = struct.unpack('f'*bb, fid.read(bb*4))[0]
xx2 = struct.unpack('f'*bb, fid.read(bb*4))[0]
在 MATLAB 中,你读取2*Nx*Ny*Nz
,但在 Python 中,你Nx*Ny*Nz
读入两个不同的数组,你永远不会将它们组合成一个数组。 这意味着你在Python中绘制的东西与在MATLAB中绘制的东西不同。 您也永远不会squeeze
或转置 numpy 数组。
最后:
matplotlib.plot(XX,YY,xx2(
首先,你在MATLAB中做pcolor
,但在Python中plot
。 这些是完全不同的。 matplotlib 有像 MATLAB 这样的pcolor
,所以使用它。
其次,没有matplotlib.plot
这样的东西. 你需要做一些类似的事情 from matplotlib import pyplot
然后pyplot.plot
. 然后你需要做pyplot.show()
才能实际显示情节。 然而,通常惯例是做import matplotlib.pyplot as plt
(和import numpy as np
(以保持更短。
如果你是交互式地执行此操作,而不是在脚本中,你可以做plt.ion()
使情节立即显示(或者更好的是使用 IPython shell 并使用 %matplotlib
(。 但是在脚本中,您需要在所有格式化完成后调用plt.show()
。
因此,这就是我将如何(大致(实现您正在做的事情。 我没有要测试的示例文件,因此它可能无法完全正常工作,但希望它足以让您入门:
import numpy as np
import matplotlib.pyplot as plt
with open('FLOW_phys_GRID_1.xyz', 'rb') as fobj:
Nx, Ny, Nz = np.fromfile(fobj, 'int32', 3)
x = np.fromfile(fobj, 'float32', Nx*Ny*Nz).reshape(Ny, Nx, Nz)[:, 0, 0])
y = np.fromfile(fobj, 'float32', Nx*Ny*Nz).reshape(Ny, Nx, Nz)[0, :, 0]
with open('FLOW_phys.raw', 'rb') as fobj:
Nx, Ny, Nz = np.fromfile(fobj, 'int32', 3)
xx1 = np.fromfile(fobj, 'float32', 2*Nx*Ny*Nz).reshape(2*Ny, Nx, Nz).squeeze().T
plt.pcolor(*np.meshgrid(x, y), xx1)
plt.show()