是否有适用于 Pandas 的 python 3d 地形图?

Is there a python 3d topographical plot that works with Pandas?

我正在处理 x、y 和 z 数据以获得带有高点和低点的平面图。 Z是位移传感器。我需要绘制带有渐变的地形图。我目前有一个 3D 散点图和一个使用 matplotlib 小部件的等高线图。这些效果很好,但线框地图或地形图效果最好。 2D 或 3D 也可以。提前致谢!

当前输出:

3D Scatter

3D Contour

我正在努力实现的示例:

Bokeh surface 3D plot

2D plot

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import holoviews as hv
from bokeh.models import ColumnDataSource
from mpl_toolkits.mplot3d import Axes3D
from holoviews import opts
hv.extension('bokeh', 'matplotlib')
%matplotlib widget
%matplotlib inline
%matplotlib nbagg
%matplotlib ipympl
plt.style.use('seaborn-white')


#Extend width of Jupyter Notebook
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))

#Read CSV
df = pd.read_csv('Floor Scan.csv')
clean_df = df.dropna(axis = 0, how ='any')
print(clean_df)
print('')

z_offset = (clean_df['Displacement (in)'].min())
z_offset_abs = abs(z_offset)
print("Minimum Z:" + str(z_offset))

#3D SCATTER

fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(111, projection='3d')

x = clean_df['fActualPosition_X (-)']
y = clean_df['fActualPosition_Y (-)']
z = clean_df['Displacement (in)']

ax.scatter(x, y, (z + z_offset_abs), c='b', marker='^')
plt.xlabel("fActualPosition_X (-)")
plt.ylabel("fActualPosition_Y (-)")

plt.show()
plt.savefig('Floor_Map_Scatter_3D.svg')

#3D CONTOUR

fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(111, projection='3d')

X = clean_df['fActualPosition_X (-)'].astype(np.uint8)
Y = clean_df['fActualPosition_Y (-)'].astype(np.uint8)
Z = clean_df['Displacement (in)'].astype(np.uint8)

flatX = np.asarray(clean_df['fActualPosition_X (-)'])
flatY = np.asarray(clean_df['fActualPosition_Y (-)'])
flatZ = np.asarray(clean_df['Displacement (in)'])

# flatX, flatY = np.meshgrid(X, Y)
# flatZ = function(flatX, flatY, Z)

# print(flatX)
# print('')
# print(flatY)
# print('')
# print(flatZ)
# print('')

plt.tricontourf(flatX, flatY, (flatZ+z_offset_abs),20)
plt.show();
plt.savefig('Floor_Map_Contour_3D.svg')

听起来你的原始数据是孤立点的形式(来自像 LIDAR 这样的 range-measuring 设备?),你想要的不仅仅是绘制这些点,而是首先推断或插值从这些点绘制一个表面,然后 然后 绘制该表面。两个所需的示例都采用已经计算出的值网格并将它们绘制为表面或图像,因此首先您需要制作这样的网格,这不是严格意义上的绘图问题,而是数据处理问题之一。

创建网格的一种典型方法是将值聚合到笛​​卡尔坐标中,基本上只是计算每个网格单元散点的平均值。另一种是将所有点连接成一个三角形网格,它实际上可能会或可能不会形成一个表面(从 x,y -> z 的函数映射)。

您可以使用我们的图书馆 Datashader to aggregate just about any set of data into a regular grid, and can then display it as images or contours using hvPlot (https://hvplot.holoviz.org/user_guide/Gridded_Data.html) or as a surface or wireframe using HoloViews (http://holoviews.org/reference/elements/plotly/Surface.html#elements-plotly-gallery-surface)。

如果您想要非结构化网格,可以使用 scipy.spatial 计算三角剖分,然后使用 HoloViews 对其进行可视化 (http://holoviews.org/reference/elements/bokeh/TriMesh.html#elements-bokeh-gallery-trimesh)。