如何在可绘制的 3D 曲面图中标记区域? [英] How to mark an area in plotly 3D surface plot?

查看:22
本文介绍了如何在可绘制的 3D 曲面图中标记区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 plotly 从 xyz 数据创建一个 3D 高程剖面,它与以下代码配合得很好:

按原样导入 plotly.graph_objects将熊猫导入为 pd将 numpy 导入为 np# 读取数据contour_data = pd.read_csv(r"C:Elevation.xyz", delimiter='', names=["x","y","z"])打印(contour_data.head())# 为 X、Y 和 Z 创建 2D 网格Z = contour_data.pivot_table(index='x', columns='y', values='z').T.valuesX_unique = np.sort(contour_data.x.unique())Y_unique = np.sort(contour_data.y.unique())X, Y = np.meshgrid(X_unique, Y_unique)# 生成 3D 绘图fig = go.Figure(data=[go.Surface(z=Z,x=X_unique,y=Y_unique)])fig.update_layout(title='Elevation', autosize=True, margin=dict(l=65, r=50, b=65, t=90))fig.update_layout(scene=dict(aspectratio=dict(x=2, y=2, z=0.4)))fig.show(渲染器=浏览器")

现在我想在这个表面上标记一个区域在这个

将 matplotlib.pyplot 导入为 plt从 matplotlib 导入 rcParams导入 plotly.graph_objects as go将熊猫导入为 pd将 numpy 导入为 npfrom shapely.geometry 导入点、多边形# 读取数据contour_data = pd.read_csv(r"C:Elevation.xyz", delimiter='', names=["x","y","z"])# 为 X、Y 和 Z 创建 2D 网格# https://alex.miller.im/posts/contour-plots-in-python-matplotlib-x-y-z/Z = contour_data.pivot_table(index='x', columns='y', values='z').TX_unique = np.sort(contour_data.x.unique())Y_unique = np.sort(contour_data.y.unique())X, Y = np.meshgrid(X_unique, Y_unique)# 生成 3D 绘图# https://www.geodose.com/2019/09/3d-terrain-modelling-in-python.html# https://plotly.com/python/3d-surface-plots/fig = go.Figure(data=go.Surface(z=Z,x=X_unique,y=Y_unique))fig.update_layout(场景=字典(xaxis = dict(title='x 经度',dtick=0.005),yaxis = dict(title='y 纬度',dtick=0.005),zaxis = dict(title='z Elevation',range=[100, 400])))fig.update_layout(title='Elevation',autosize=True, margin=dict(l=65, r=50, b=65, t=90))fig.update_layout(scene=dict(aspectratio=dict(x=2, y=2, z=0.3)))# 创建一个多边形坐标 = [(9.185, 51.39), (9.175, 51.39), (9.175, 51.4), (9.2, 51.395)]poly = 多边形(坐标)标记区域=Z.copy()我=0对于 X_unique 中的 x:j=0对于 Z.iloc[i] 中的 z:if (Point(x,Y_unique[j]).within(poly)):标记区域.iloc[i,j]=z+0.1别的:标记区域.iloc[i,j]=0j=j+1我=我+1fig.add_trace(go.Surface(z=marked_area,x=X_unique,y=Y_unique,colorscale = ['rgba(0,0,250,1)', 'rgba(0,0,250,1)'],colorbar = None,showlegend=False))fig.show(渲染器=浏览器")

I use plotly to create a 3D elevation profile from xyz data which works pretty well with the following code:

import plotly.graph_objects as go
import pandas as pd
import numpy as np

# Read data
contour_data = pd.read_csv(r"C:Elevation.xyz", delimiter=' ', names=["x","y","z"])
print(contour_data.head())

# Create 2D grids for X,Y and Z
Z = contour_data.pivot_table(index='x', columns='y', values='z').T.values
X_unique = np.sort(contour_data.x.unique())
Y_unique = np.sort(contour_data.y.unique())
X, Y = np.meshgrid(X_unique, Y_unique)

# Generate 3D plot
fig = go.Figure(data=[go.Surface(z=Z,x=X_unique,y=Y_unique)])
fig.update_layout(title='Elevation', autosize=True, margin=dict(l=65, r=50, b=65, t=90))
fig.update_layout(scene=dict(aspectratio=dict(x=2, y=2, z=0.4)))
fig.show(renderer="browser")

Now I want to mark an area on this surface as in this example. Alternatively just the border of this area would be nice.

Is there a way to mark this area by just providing some x,y coordinates?

解决方案

Thank you @vestland for suggesting a solution. Starting from your approach I have implemented a solution that is working with non-rectangle areas by just defining a polygon with x,y coordinates.

import matplotlib.pyplot as plt
from matplotlib import rcParams
import plotly.graph_objects as go
import pandas as pd
import numpy as np
from shapely.geometry import Point, Polygon

# Read data
contour_data = pd.read_csv(r"C:Elevation.xyz", delimiter=' ', names=["x","y","z"])

# Create 2D grids for X,Y and Z
# https://alex.miller.im/posts/contour-plots-in-python-matplotlib-x-y-z/
Z = contour_data.pivot_table(index='x', columns='y', values='z').T
X_unique = np.sort(contour_data.x.unique())
Y_unique = np.sort(contour_data.y.unique())
X, Y = np.meshgrid(X_unique, Y_unique)

# Generate 3D plot
# https://www.geodose.com/2019/09/3d-terrain-modelling-in-python.html
# https://plotly.com/python/3d-surface-plots/ 
fig = go.Figure(data=go.Surface(z=Z,x=X_unique,y=Y_unique))
fig.update_layout(scene = dict(
        xaxis = dict(title='x Longitude',dtick=0.005),
        yaxis = dict(title='y Latitude',dtick=0.005),
        zaxis = dict(title='z Elevation',range=[100, 400])))
fig.update_layout(title='Elevation',autosize=True, margin=dict(l=65, r=50, b=65, t=90))
fig.update_layout(scene=dict(aspectratio=dict(x=2, y=2, z=0.3)))

# Create a Polygon
coords = [(9.185, 51.39), (9.175, 51.39), (9.175, 51.4), (9.2, 51.395)]
poly = Polygon(coords)

marked_area=Z.copy()
i=0
for x in X_unique:
    j=0
    for z in Z.iloc[i]:
        if (Point(x,Y_unique[j]).within(poly)):
            marked_area.iloc[i,j]=z+0.1
        else:
            marked_area.iloc[i,j]=0
        j=j+1
    i=i+1
    
fig.add_trace(go.Surface(z=marked_area,x=X_unique,y=Y_unique,
                         colorscale = ['rgba(0,0,250,1)', 'rgba(0,0,250,1)'],
                         colorbar = None,showlegend=False))

fig.show(renderer="browser")

这篇关于如何在可绘制的 3D 曲面图中标记区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆