Say I have a one-dimensional array of size NxN in C which I think of as a two-dimensional array, i.e. every N entries, a new row begins.
I would like to visualise this array by laying it onto a plane and then treating every entry as the height of the array above the plane, thereby creating a surface.
How would I go about transferring the data from C to Python in such a way that Python can read it in as a two-dimensional array and then plot it in three dimensions?
Update
Writing the data to a CSV file, as suggested in barny's answer and by joao in the comments, worked well:
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");
}
Reading it into a list in python was easy too:
import csv
data = list(csv.reader(open("data.csv")))
Unfortunately, outputting this data into a surface plot is causing problems. My python script reads
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
If I try to run it, I get an error on line 12 (data = np.array(data).reshape(Y.size,X.size)
) saying ValueError: total size of new array must be unchanged. I tried np.sqrt(len(data)) instead of len(data) as well 256which happens to be the value of N in my case. However, the error persisted in every case.
Update 2
What finally worked for me was the suggestion by Emilie to simply write the C array out linearly, i.e.
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);
}
and then read it in via
data = np.fromfile('data.dat', dtype=float, count=-1, sep='')
in Python followed by
array = data.reshape((np.sqrt(len(data)), np.sqrt(len(data))))
to give the array its required shape. (Note: This step will likely cause problems if your array length is not a square number.)
The complete working plotting script is
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()
jsonthat python handles well. Otherwise you can write integers or floats in your machine's representation and read them back into python using thestructmodule.