簡體   English   中英

如何在 plotly 3D 表面 plot 中標記一個區域?

[英]How to mark an area in plotly 3D surface plot?

我使用 plotly 從 xyz 數據創建 3D 高程剖面,該剖面與以下代碼配合得很好:

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")

3D 高程圖

現在我想在這個表面上標記一個區域,如本例所示 或者只是這個區域的邊界會很好。

有沒有辦法通過提供一些 x,y 坐標來標記這個區域?

感謝@vestland 提出解決方案。 從您的方法開始,我已經實現了一個解決方案,該解決方案僅通過定義具有 x,y 坐標的多邊形來處理非矩形區域。

帶有標記多邊形區域的高程數據

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")

由於您尚未提供數據樣本,因此我根據Topographical 3D Surface Plot中的示例提出初步建議。 這可能需要一些額外的調整,但您可以使用fig.add_trace(go.Scatter3D)來突出顯示您的坐標子集,如下所示:

在此處輸入圖像描述

讓我知道這對你來說是如何工作的,我們可以仔細看看細節。

完整代碼:

import plotly.graph_objects as go

import pandas as pd

# Read data from a csv
z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')

fig = go.Figure(data=[go.Surface(z=z_data.values)])

fig.update_layout(title='Mt Bruno Elevation', autosize=False,
                  width=500, height=500,
                  margin=dict(l=65, r=50, b=65, t=90))
df2 = z_data.iloc[8:15, 7:21]
fig.add_trace(go.Surface(x = df2.columns, y = df2.index, z=df2.values,
                         colorscale = ['rgba(250,0,0,0.8)', 'rgba(250,0,0,0.8)'],
                         colorbar = None))

fig.show()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM