我有三个独立的1-D阵列,包含椭圆体表面的数据点.数据点是通过C代码生成的,并且这些点存储在.CSV文件中.
我想使用matplotlib中的plot_surface函数从这些数据点绘制3D表面.我开始绘制一个三维散点图作为一个健全性检查,以确保我所属的数据点属于一个椭球而不是一些随机的形状.
然后我在matplotlib中尝试了plot_surface()函数,并尝试了迄今为止在SO上讨论过的各种方法,你可以在最后给出的代码中看到它们.我将列出两个输出,因为我的低代表不允许我发布我的所有结果.
>帖子标题为“matplotlib中的表面图”,
这导致了输出:
这个方法在我的代码注释方法-4下实现.我也实现了类似的东西,但没有unique()函数,它再次给了我类似的输出.最后一部分是在我的代码中的方法-3下实现的.
>帖子标题为“在表面上绘制3元组数据点”,
这导致了输出:
该部分在代码中的方法-2下实现.
正如您所看到的,这些方法都没有真正起作用,虽然散点图确认数据点确实属于椭圆体,但表面图给出了错误的结果.
难道我做错了什么?如果没有,那么你可以建议一种替代方法来正确绘制我的案例的3D表面吗?我正在使用的数据可以在以下链接中找到:https://drive.google.com/file/d/0BwTffmdLhwB3b0JOMXdHYzFTSGc/view?usp=sharing
我使用的是python2.7,操作系统:ubuntu-14.04.我是python的新手,所以如果你能提供解释和解决方案,那将会很棒.非常感谢你.
'''
Copyright (c) 2016 Abhishek Agrawal (abhishek.agrawal@protonmail.com)
Distributed under the MIT License.
See accompanying file LICENSE.md or copy at http://opensource.org/licenses/MIT
'''
# Set up modules and packages
# I/O
import csv
from pprint import pprint
# Numerical
import numpy as np
import pandas as pd
from scipy.interpolate import griddata
import math
# 3D visualization special package
import mayavi
from mayavi import mlab
# System
import sys
import time
from tqdm import tqdm
print ""
print "---------------------------------------------------------------------------------"
print " NAOS "
print " "
print " Copyright (c) 2016, A. Agrawal (abhishek.agrawal@protonmail.com) "
print "---------------------------------------------------------------------------------"
print ""
# Start timer.
start_time = time.time( )
# Get plotting packages
import matplotlib
import matplotlib.colors
import matplotlib.axes
import matplotlib.lines as mlines
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
from matplotlib import rcParams
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d import axes3d
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.tri as tri
# Operations
# Read data in csv file. data returned as a panda series.
data = pd.read_csv( '../data/ellipsoidSurfacePoints.csv' )
# Plot 3D surface of the ellipsoid
fig = plt.figure()
ax = fig.gca( projection = '3d' )
ax.set_xlabel('x [km]')
ax.set_ylabel('y [km]')
ax.set_zlabel('z [km]')
ax.ticklabel_format(style='sci', axis='both', scilimits=(0,0))
x = data['X'].values
# print x[1:100]
y = data['Y'].values
# print y
z = data['Z'].values
# print z
r = np.sqrt( x**2 + y**2 + z**2 )
# **************** trisurf, scatter and wireframe ************ #
# triang = tri.Triangulation( x, y )
# ax.plot_trisurf( x, y, z, triangles=triang.triangles, cmap=cm.jet, linewidth=0.1 )
# ax.scatter( x, y, z )
# ax.plot_wireframe( x, y, z )
# plt.show()
# **************** Method - 1 ******************************** #
# pts = mayavi.mlab.points3d( x, y, z, z )
# mesh = mayavi.mlab.pipeline.delaunay2d( pts )
# pts.remove( )
# surf = mayavi.mlab.pipeline.surface( mesh )
# mayavi.mlab.show( )
# **************** Method - 2 ******************************** #
# x1 = np.linspace( x.min(), x.max() )
# y1 = np.linspace( y.min(), y.max() )
# xx, yy = np.meshgrid( x1, y1 )
# zz = griddata( ( x, y ), z, ( x1, y1 ), method='cubic' )
# ax.plot_surface( xx, yy, zz, rstride=5, cstride=5, cmap=cm.jet, linewidth=0.1, antialiased=False )
# plt.show()
# **************** Method - 3 ******************************** #
x1 = np.linspace( x.min(), x.max() )
y1 = np.linspace( y.min(), y.max() )
xx, yy = np.meshgrid( x1, y1 )
zz = griddata( ( x, y ), z, ( xx, yy ), method='cubic' )
ax.plot_surface( xx, yy, zz, rstride=5, cstride=5, cmap=cm.jet, linewidth=0.1, antialiased=False )
plt.show()
# **************** Method - 4 ******************************** #
# x1 = np.linspace( x.min(), x.max(), len( data['X'].unique() ) )
# y1 = np.linspace( y.min(), y.max(), len( data['Y'].unique() ) )
# xx, yy = np.meshgrid( x1, y1 )
# zz = griddata( ( x, y ), z, ( xx, yy ), method='cubic' )
# ax.plot_surface( xx, yy, zz, rstride=5, cstride=5, cmap=cm.jet, linewidth=0.1, antialiased=False )
# plt.show()
# **************** Method - 5 ******************************** #
# xx, yy = np.mgrid[ min(x):max(x):100j, min(y):max(y):100j ]
# zz = griddata( ( x, y ), z, ( xx, yy ), method='cubic' )
# ax.plot_surface( xx, yy, zz, rstride=5, cstride=5, cmap=cm.jet, linewidth=0.1, antialiased=False )
# plt.show()
# Stop timer
end_time = time.time( )
# Print elapsed time
print "Script time: " + str("{:,g}".format(end_time - start_time)) + "s"
print ""
print "------------------------------------------------------------------"
print " Exited successfully! "
print "------------------------------------------------------------------"
print ""
最佳答案 我认为你正在寻找的是plot_trisurf,它可以处理非结构化的1D数据向量.下面的代码使用您的数据来制作图表.数据的关键问题是每个X / Y点都有3个z值,plot_trisurf无法自动处理(尽管有一些方法可以解决这个问题,例如有关绘制球体的问题).我通过将复制的X / Y点拆分为单独的数据帧来处理这个问题.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
fileDir = "data.csv"
data = pd.read_csv(fileDir, engine = 'c', float_precision = 'round_trip', dtype=np.float64)
dataTop = data.drop_duplicates(subset=['x', 'y'], keep='first', inplace=False)
XTop = dataTop['x']
YTop = dataTop['y']
ZTop = dataTop['z']
dataMid = data.drop_duplicates(subset=['x', 'y'], keep=False, inplace=False)
XMid = dataMid['x']
YMid = dataMid['y']
ZMid = dataMid['z']
dataBottom = data.drop_duplicates(subset=['x', 'y'], keep='last', inplace=False)
XBottom = dataBottom['x']
YBottom = dataBottom['y']
ZBottom = dataBottom['z']
fig = plt.figure(figsize=(11.5, 8.5))
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(XTop, YTop, ZTop, cmap='viridis', alpha=0.5)
ax.plot_trisurf(XMid, YMid, ZMid, cmap='viridis', alpha=0.5)
ax.plot_trisurf(XBottom, YBottom, ZBottom, cmap='viridis', alpha=0.5)
plt.show()
如果你能告诉我更多关于你希望看到的情节,我可以尝试更具体.有关三角测量的更多信息,请参见Matplotlib like matlab’s trisurf.