Plotly 3d surface plot from latitude, longitude, elevation Data

Viewed 560

I have the following elevation data in a dict format from azure elevation API response and I am trying to plot an elevation profile based on that data.

I have reduced the size for sample purpose to a 4x4 lat/long square grid area for purpose of this query, the actual area is a much larger sample.

I am trying to generate a 3d surface-plot approximation using Plotly based on this data.

my understanding is

1)first need to convert the lat/long to an x,y coordinate? what is the best way f do this? 2) Also need to convert Z/ elevation to a 2d array? based on x,y from 1)?

import plotly.offline as py
import plotly.graph_objs as go
import pandas as pd

elevation = {'data': [{'coordinate': {'latitude': -33.88676483475523,
    'longitude': 150.84667222543544},
   'elevationInMeter': 59.76341},
  {'coordinate': {'latitude': -33.88676483475523,
    'longitude': 150.84689611369265},
   'elevationInMeter': 58.91294},
  {'coordinate': {'latitude': -33.88676483475523,
    'longitude': 150.8471200019499},
   'elevationInMeter': 58.2653},
  {'coordinate': {'latitude': -33.88676483475523,
    'longitude': 150.8473438902071},
   'elevationInMeter': 57.80102},
  {'coordinate': {'latitude': -33.88657811224419,
    'longitude': 150.84667222543544},
   'elevationInMeter': 60.25625},
  {'coordinate': {'latitude': -33.88657811224419,
    'longitude': 150.84689611369265},
   'elevationInMeter': 59.25375},
  {'coordinate': {'latitude': -33.88657811224419,
    'longitude': 150.8471200019499},
   'elevationInMeter': 58.59771},
  {'coordinate': {'latitude': -33.88657811224419,
    'longitude': 150.8473438902071},
   'elevationInMeter': 58.17687},
  {'coordinate': {'latitude': -33.88639138973315,
    'longitude': 150.84667222543544},
   'elevationInMeter': 60.63495},
  {'coordinate': {'latitude': -33.88639138973315,
    'longitude': 150.84689611369265},
   'elevationInMeter': 59.59782},
  {'coordinate': {'latitude': -33.88639138973315,
    'longitude': 150.8471200019499},
   'elevationInMeter': 58.97992},
  {'coordinate': {'latitude': -33.88639138973315,
    'longitude': 150.8473438902071},
   'elevationInMeter': 58.59934},
  {'coordinate': {'latitude': -33.8862046672221,
    'longitude': 150.84667222543544},
   'elevationInMeter': 61.03286},
  {'coordinate': {'latitude': -33.8862046672221,
    'longitude': 150.84689611369265},
   'elevationInMeter': 60.10513},
  {'coordinate': {'latitude': -33.8862046672221,
    'longitude': 150.8471200019499},
   'elevationInMeter': 59.54065},
  {'coordinate': {'latitude': -33.8862046672221,
    'longitude': 150.8473438902071},
   'elevationInMeter': 59.13883}]}


val_x = []
val_y = []
val_z = []

for entry in elevation['data']:
    x, y, zone, ut = utm.from_latlon(entry['coordinate']['latitude'], entry['coordinate']['longitude'])
    val_x.append(x)
    val_y.append(y)
    val_z.append(entry['elevationInMeter'])

    
fig = go.Figure(data=[go.Surface(x=val_x, y=val_y, z=val_z)])
  
fig.update_traces(contours_z=dict(
    show=True, usecolormap=True,
    highlightcolor="limegreen",
    project_z=True))
  
fig.show()

1 Answers
  • https://plotly.com/python/reference/surface/ The data the describes the coordinates of the surface is set in z. Data in z should be a 2D list. Coordinates in x and y can either be 1D lists or {2D arrays} (e.g. to graph parametric surfaces)
  • this is simple to achieve by shaping your data using pandas
# load data into dataframe
df = pd.json_normalize(elevation["data"])
# reshape so we have 2D matrix of elevations
df = df.set_index(["coordinate.latitude", "coordinate.longitude"]).unstack(
    "coordinate.longitude"
)
fig = go.Figure(
    go.Surface(z=df.values, y=df.index.values, x=df.columns.get_level_values(1).values)
)
fig.update_traces(
    contours_z=dict(
        show=True, usecolormap=True, highlightcolor="limegreen", project_z=True
    )
).update_layout( margin={"l":0,"r":0,"t":0,"b":0})

enter image description here

Related