Reputation: 11
Although there are several sources on how to plot 3D surfaces with XYZ format. I have a CSV file from a scanning laser that provides no coordinate information on X and Y, just Z coordinates of a rectangular grid.
The file is 800 x 1600 with just z coordinates. Excel can plot it very easily with surface plot, but is limited by size.
How can I approach this problem?
Upvotes: 1
Views: 5479
Reputation: 89
I faced a similar problem and a reply from @tmdavison turn me on in the right direction. But this answer unclear in the part of retrieving data from the CSV file.
Here is my solution.
import csv
import matplotlib.pyplot as plt
import numpy
def csv_3d(file_name):
"""Draw content of csv file with matplotlib 3D like MS Excel."""
data = [
[float(i.replace(',', '.')) for i in row]
for row in csv.reader(open(file_name), delimiter=';')
]
# matplotlib/numpy magic
x_arr, y_arr = numpy.meshgrid(
numpy.arange(0.0, float(len(data[0])), 1.0), # x: number of columns in csv
numpy.arange(0.0, float(len(data)), 1.0), # y: number of rows in csv
)
z_arr = numpy.array(data) # transform csv data into 2D values numpy array
plt.figure(num=file_name)
axes = plt.axes(projection="3d")
axes.plot_surface(x_arr, y_arr, z_arr)
plt.show()
csv_3d('my.csv')
Upvotes: 0
Reputation: 69056
You just need to create arrays of the X
and Y
coordinates. We can do this with numpy.meshgrid
. In the example below, I set the cell size to 1., but you can easily scale that by changing the cellsize
variable.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
# Create x, y coords
nx, ny = 800, 1600
cellsize = 1.
x = np.arange(0., float(nx), 1.) * cellsize
y = np.arange(0., float(ny), 1.) * cellsize
X, Y = np.meshgrid(x, y)
# dummy data
Z = (X**2 + Y**2) / 1e6
# Create matplotlib Figure and Axes
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
print X.shape, Y.shape, Z.shape
# Plot the surface
ax.plot_surface(X, Y, Z)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
Upvotes: 2