Skip to main content
v2.2

3D Surface

3D surfaces can be created using Chart3D and Surface Grid Series. This series is optimized for massive amounts of surface grid data.

The grid is defined by imagining a plane along X and Z axis, split to < COLUMNS > (cells along X axis) and < ROWS > (cells along Z axis). The total amount of < CELLS > in a surface grid is calculated as columns * rows. Each < CELL > can be associated with DATA from an user data set.

See also Scrolling 3D Surface.

3D Surface3D Surface
import numpy as np
import lightningchart as lc
from scipy.interpolate import griddata

# Set your license key here
lc.set_license('my-license-key')

# Generate random data points
np.random.seed(0)
num_points = 500

# Generate random latitudes and longitudes
latitudes = np.random.uniform(-90, 90, num_points)
longitudes = np.random.uniform(-180, 180, num_points)
magnitudes = np.random.uniform(4.5, 6.5, num_points)

# Create a grid for interpolation
grid_lat, grid_lon = np.meshgrid(
np.linspace(latitudes.min(), latitudes.max(), 100),
np.linspace(longitudes.min(), longitudes.max(), 100)
)

# Interpolate magnitudes onto the grid
grid_mag = griddata(
(latitudes, longitudes), magnitudes,
(grid_lat, grid_lon),
method='linear' # You can use 'linear' or 'cubic'
)

# Fill NaN values with the mean of magnitudes
nan_mask = np.isnan(grid_mag)
grid_mag[nan_mask] = np.nanmean(magnitudes)

# Create a 3D chart
chart = lc.Chart3D(
theme=lc.Themes.Light,
title='3D Surface Grid Series'
)

# Create a surface grid series
surface_series = chart.add_surface_grid_series(
columns=grid_mag.shape[1],
rows=grid_mag.shape[0]
)

# Set the start and end points
surface_series.set_start(x=longitudes.min(), z=latitudes.min())
surface_series.set_end(x=longitudes.max(), z=latitudes.max())

# Set the steps
surface_series.set_step(
x=(longitudes.max() - longitudes.min()) / grid_mag.shape[1],
z=(latitudes.max() - latitudes.min()) / grid_mag.shape[0]
)

# Set the height map
surface_series.invalidate_height_map(grid_mag.tolist())

# Hide the wireframe
surface_series.hide_wireframe()

# Set palette colors
surface_series.set_palette_coloring(
steps=[
{"value": np.nanmin(grid_mag), "color": ('blue')},
{"value": np.nanpercentile(grid_mag, 25), "color": ('cyan')},
{"value": np.nanmedian(grid_mag), "color": ('green')},
{"value": np.nanpercentile(grid_mag, 75), "color": ('yellow')},
{"value": np.nanmax(grid_mag), "color": ('red')}
],
look_up_property='value',
percentage_values=False
)

# Invalidate intensity values
surface_series.invalidate_intensity_values(grid_mag.tolist())

# Set axis titles
chart.get_default_x_axis().set_title('Longitude')
chart.get_default_y_axis().set_title('Magnitude')
chart.get_default_z_axis().set_title('Latitude')

chart.open()