如何在python中将1d C数组绘制为曲面

时间:2015-11-26 14:43:38

标签: python c plot surface

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

我希望通过将此数组放置在一个平面上然后将每个条目视为平面上方数组的高度来显示此数组,从而创建一个表面。

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

更新

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

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

2 个答案:

答案 0 :(得分:1)

重塑错误会产生,因为当您阅读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是最优雅的方式,但可能是一个简单的解决方案。

答案 1 :(得分:0)

您可以将数据打印为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 巴尼