【问题标题】:How to mark an area in plotly 3D surface plot?如何在 plotly 3D 曲面图中标记一个区域?
【发布时间】:2021-12-28 20:29:19
【问题描述】:

我使用 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")

现在我想在这个表面上标记一个区域 就像在这个example 中一样。 或者只是这个区域的边界会很好。

有没有办法通过提供一些 x,y 坐标来标记这个区域?

【问题讨论】:

    标签: python plot 3d plotly geospatial


    【解决方案1】:

    由于您没有提供数据样本,我基于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()
    

    【讨论】:

    • 感谢您指出 iloc。我正在寻找一种方法来标记不得为矩形的区域。
    【解决方案2】:

    感谢 @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")
    

    【讨论】:

      猜你喜欢
      • 2021-12-06
      • 2018-05-06
      • 2017-02-08
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 2021-05-08
      • 1970-01-01
      相关资源
      最近更新 更多