Create a surface plot of xyz altitude data
Asked Answered
W

3

11

I am trying to create a surface plot of a mountain in python, of which I have some xyz data. The end result should look something like that. The file is formatted as follows:

616000.0 90500.0 3096.712
616000.0 90525.0 3123.415
616000.0 90550.0 3158.902
616000.0 90575.0 3182.109
616000.0 90600.0 3192.991
616025.0 90500.0 3082.684
616025.0 90525.0 3116.597
616025.0 90550.0 3149.812
616025.0 90575.0 3177.607
616025.0 90600.0 3191.986

and so on. The first column represents the x coordinate, the middle one the y coordinate, and z the altitude that belongs to the xy coordinate.

I read in the data using pandas and then convert the columns to individual x, y, z NumPy 1D arrays. So far I managed to create a simple 3D scatter plot with a for loop iterating over each index of each 1D array, but that takes ages and makes the appearance of being quite inefficient.

I've tried to work with scipy.interpolate.griddata and plt.plot_surface, but for z data I always get the error that data should be in a 2D array, but I cannot figure out why or how it should be 2D data. I assume that given I have xyz data, there should be a way to simply create a surface from it. Is there a simple way?

Welcome answered 17/8, 2018 at 8:42 Comment(0)
A
8

Using functions plot_trisurf and scatter from matplotlib, given X Y Z data can be plotted similar to given plot.

import sys
import csv
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d

# Read CSV
csvFileName = sys.argv[1]
csvData = []
with open(csvFileName, 'r') as csvFile:
    csvReader = csv.reader(csvFile, delimiter=' ')
    for csvRow in csvReader:
        csvData.append(csvRow)

# Get X, Y, Z
csvData = np.array(csvData)
csvData = csvData.astype(np.float)
X, Y, Z = csvData[:,0], csvData[:,1], csvData[:,2]

# Plot X,Y,Z
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(X, Y, Z, color='white', edgecolors='grey', alpha=0.5)
ax.scatter(X, Y, Z, c='red')
plt.show()

Here,

  • file containing X Y Z data provided as argument to above script
  • in plot_trisurf, parameters used to control appearance. e.g. alpha used to control opacity of surface
  • in scatter, c parameter specifies color of points plotted on surface

For given data file, following plot is generated

enter image description here

Note: Here, the terrain is formed by triangulation of given set of 3D points. Hence, contours along surface in plot are not aligned to X- and Y- axes

Achitophel answered 8/3, 2019 at 15:42 Comment(0)
D
2
import numpy as np  
import matplotlib.pyplot as plt  
import mpl_toolkits.mplot3d 
import pandas as pd 
 
df = pd.read_csv("/content/1.csv") 
X = df.iloc[:, 0] 
Y = df.iloc[:, 1] 
Z = df.iloc[:, 2] 
 
fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
ax.plot_trisurf(X, Y, Z, color='white', edgecolors='grey', alpha=0.5) 
ax.scatter(X, Y, Z, c='red') 
plt.show()

My output image below - I had a lot of data points: enter image description here

Dowd answered 15/1, 2022 at 13:57 Comment(0)
S
0

There is an easier way to achieve your goal without using pandas.

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

x, y = np.mgrid[-2 : 2 : 20j, -2 : 2 : 20j]
z = 50 * np.sin(x + y)                     # test data
output = plt.subplot(111, projection = '3d')   # 3d projection
output.plot_surface(x, y, z, rstride = 2, cstride = 1, cmap = plt.cm.Blues_r)
output.set_xlabel('x')                         # axis label
output.set_xlabel('y')
output.set_xlabel('z')

plt.show()

plot example

Secateurs answered 17/8, 2018 at 8:57 Comment(1)
hi thanks for your answer. When I try to use my x,y,z data, it also says that Z must be 2-dimensional. My z data are altitude values, so they cant be computed by inputs x and y.Welcome

© 2022 - 2024 — McMap. All rights reserved.