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 a user data set.

See also Scrolling 3D Surface.

3D Surface3D Surface

Creating 3D Surface

series = chart.add_surface_grid_series(columns=3, rows=3)

Configuring 3D Surface Coordinates

These methods allow you to define the spatial positioning of 3D Surface samples.

Set Start Coordinate

# Set the start coordinate to (0, 0)
series.set_start(x=0, z=0)

Set End Coordinate

# Set the end coordinate to (100, 50)
series.set_end(x=100, z=50)

Set Step Between Samples

# Set the step between samples to 10 in X and 5 in Z
series.set_step(x=10, z=5)

Data input and Intensity Invalidation

Invalidate Intensity Values

This method helps update the 3D Surface's intensity values:

# Define a 2D matrix for new intensity values:
data_matrix = [
[1.0, 2.0, 3.0],
[2.5, 3.5, 4.0],
[3.0, 4.0, 5.0]
]
# Update the intensity values.
series.invalidate_intensity_values(data=data_matrix)

Intensity interpolation

# Enable smooth intensity interpolation:
series.set_intensity_interpolation(True)

Invalidate Height Map

Similar to intensity invalidation, you can update the surface's vertical (Y-axis) heights in a sub-region:

# Define a matrix of new height values
height_matrix = [
[0.5, 1.0, 0.8],
[0.7, 1.2, 0.9],
[0.6, 1.1, 1.3],
]

# Update starting at column 0, row 0
series.invalidate_height_map(data=height_matrix, column_index=0, row_index=0)
  • invalidate_height_map(data, column_index, row_index) Replaces the height values (Y) for the grid cells beginning at the given column/row.

Contour Lines

Add contour lines to visualize specific value thresholds on 3D surfaces.

Basic Contours

series.set_contours(
levels=[
{'value': 10},
{'value': 50},
{'value': 90}
]
)

Styled Contours

series.set_contours(
levels=[
{
'value': 25,
'stroke_style': {'thickness': 2, 'color': '#0000FF'}
},
{
'value': 75,
'stroke_style': {'thickness': 3, 'color': '#FF0000'}
}
]
)

Extrapolating surface data from scatter data set

One common way of using surface charts is to extrapolate a surface height map from a scattered 3D data set. For example, see the video below, which displays both Raw samples (as scatter points) and the extrapolated surface:

Culling, Depth Test & Shading

Control back-face/front-face culling, depth buffering, and shading style on the 3D surface:

# Disable culling to render both sides of surface polygons
series.set_cull_mode('disabled') # options: 'disabled', 'cull-back', 'cull-front'

# Turn off depth testing so overlapping parts draw in append order
series.set_depth_test_enabled(False)

# Choose between Phong (smooth) or simple flat shading
series.set_color_shading_style(
phong_shading=True, # True = Phong, False = flat
specular_reflection=0.5, # specular strength [0–1]
specular_color='#FFFFFF' # highlight color
)
  • set_cull_mode(mode) Controls which polygon faces to discard:

    • "cull-back" (default) discards faces pointing away from camera
    • "cull-front" discards faces pointing toward camera
    • "disabled" renders both sides
  • set_depth_test_enabled(enabled) Enables/disables GPU depth buffering (occlusion) for this mesh.

  • set_color_shading_style(phong_shading, specular_reflection, specular_color) Switches between realistic Phong shading and a simple lighting model, with tunable specular highlight.

Customizing Fill Coloring

Set Palette Coloring

import lightningchart as lc
# Create a palette that transitions from blue to red:

series.set_palette_coloring(
steps=
[
{'value': 0, 'color': ('#0000FF')},
{'value': 50, 'color': ('red')}
]
, look_up_property='value'
, interpolate=True
)

# With formatted legend display:
series.set_palette_coloring(
steps=[
{'value': 0, 'color': '#0000FF'},
{'value': 100, 'color': '#FF0000'},
],
look_up_property='value',
formatter_precision=2, # Decimal places
formatter_unit='mag', # Unit suffix
formatter_scale=1.5, # Scale values
formatter_type='scientific', # 'standard', 'compact', 'engineering', 'scientific'
formatter_operation='floor', # 'none', 'round', 'ceil', 'floor'
)

Solid Fill Color

import lightningchart as lc

# Set the fill color to a light gray:
series.set_color((200, 200, 200))

Removing Color

# Remove the fill color:
series.set_empty_color_fill()

Wireframe Configuration

Set Wireframe Stroke

import lightningchart as lc

# Set a wireframe with 2px thickness in black:
series.set_wireframe_stroke(thickness=2, color='black')

Hide Wireframe

# Hide the 3D surface wireframe:
series.hide_wireframe()

Series Utility Methods:

# Set a name for the series (used in legend and tooltip)
series.set_name("3D Surface")

# Highlight the series fully (1.0 = max highlight)
series.set_highlight(1.0)

# Enable or disable theme-based visual effects
series.set_effect(True)

# Toggle series visibility (False hides it from view)
series.set_visible(True)

# Permanently remove the series from the chart
series.dispose()

Legend

Please see common legend section.

Examples

Link to the examples