如何在 python 中将一维 C 数组绘制为曲面

How to plot 1d C array as surface in python

假设我在 C 中有一个大小为 NxN 的一维数组,我认为它是一个二维数组,即每 N 个条目,一个新行开始。

我想将这个数组可视化,将它放在一个平面上,然后将每个条目视为数组在平面上方的高度,从而创建一个表面。

我如何将数据从 C 传输到 Python,以便 Python 可以将其作为二维数组读取,然后在三维中绘制?


更新

按照 barny 的回答和 joao 在评论中的建议,将数据写入 CSV 文件效果很好:

FILE *datafile = fopen("data.csv", "w");
for(int i = 0; i < N; i++) {
    for(int j = 0; j < N; j++) {
        fprintf(datafile, "%g, ", data[i * N + j]);
    }
    fprintf(datafile, "\n");
}

将其读入 python 中的列表也很容易:

import csv
data = list(csv.reader(open("data.csv")))

不幸的是,将此数据输出到曲面图中会导致问题。我的 python 脚本读取

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

import csv
data = list(csv.reader(open("data.csv")))

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = y = np.arange(0, 1, 1.0/len(data))
X, Y = np.meshgrid(x, y)
data = np.array(data).reshape(Y.size,X.size)

ax.plot_surface(X, Y, data)

plt.show

如果我尝试 运行 它,我会在第 12 行 (data = np.array(data).reshape(Y.size,X.size) ) 上收到一个错误 ValueError: total size of new array must be unchanged。我也尝试 np.sqrt(len(data)) 而不是 len(data) 256,这恰好是我的 N 的值。但是,错误在每种情况下都存在。


更新 2

最终对我有用的是 Emilie 的建议,即简单地线性写出 C 数组,即

FILE *datafile = fopen("data.dat", "w");
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++) {
    fwrite(&array[i * N + j], sizeof(double), 1, datafile);
}

然后通过

读入
data = np.fromfile('data.dat', dtype=float, count=-1, sep='')

在Python之后是

array = data.reshape((np.sqrt(len(data)), np.sqrt(len(data))))

为数组提供所需的形状。 (注意:如果您的数组长度不是平方数,此步骤可能会出现问题。)

完整的工作绘图脚本是

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

data = np.fromfile('data.dat', dtype=float, count=-1, sep='')

array = data.reshape((np.sqrt(len(data)), np.sqrt(len(data))))

fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
x = y = np.arange(0, 1, 1.0/np.sqrt(len(data)))
X, Y = np.meshgrid(x, y)
array = np.array(data)

ax.plot_surface(X, Y, array)

plt.show()

您可以将数据打印为 python 表达式,如下所示:

printf( "data2d = [\n" );
for ( y = 0; y < N ; y++ ) {
    printf( "  [" );
    for ( x = 0 ; x < n ; x++ ) {
        printf( " %d,", datalist[y*N+x] );
    }
    printf( " ],\n" );
}
printf( "]\n" );

还没有测试过这个,虽然因为我做了任何 C,但它会是这样的。

(我认为尾随逗号不重要 - 如果重要,请不要在每行的最后一个条目上打印它们)

或者,也许更简单,将其打印为普通 csv 文件 - 数组的每一行一行,值之间有 , 然后使用 csv 模块读取它。

HTH 巴尼

重塑错误的产生是因为当您读取 csv 时,您的 data 已经是一个列表列表,您可以使用 np.array(data).

将其简单地转换为一个 numpy 数组

例如,如果我有这个文件:

/tmp$ cat foo.csv 
1,2,3
4,5,6

我能做到:

>>> import csv
>>> data = list(csv.reader(open("foo.csv")))
>>> data
[['1', '2', '3'], ['4', '5', '6']]
>>> import numpy as np
>>> np.array(data)
array([['1', '2', '3'],
       ['4', '5', '6']], 
      dtype='|S1')

根据您想对这个 numpy 数组执行的操作,您可能还需要更改元素的类型。您也可以线性写入数据,然后使用 np.reshape。我不确定 csv 是最优雅的方式,但可能是一个简单的解决方案。