Point cloud viewer

The pptk.viewer() function enables one to directly visualize large point clouds in Python. It accepts as input any Python variable that can be cast as a 3-column numpy array (i.e. via np.asarray()). It interprets the columns of such input as the x, y, and z coordinates of a point cloud.

The viewer itself runs as a standalone operating system process separate from Python. The user can query and manipulate the viewer via the handle that is returned by pptk.viewer(). The handle encapsulates the details of communicating with the viewer (e.g. the viewer process’s port number) and provides methods for querying and manipulating the viewer.

The viewer supports interactive visualization of tens of millions of points via an octree-based level-of-detail renderer. At startup the viewer organizes the input points into an octree. As the viewpoint is being manipulated, the octree is used to approximate groups of far away points as single points and cull points that are outside the view frustum, thus greatly reducing the number of points being rendered. Once there are no more changes to the viewpoint, the viewer then proceeds to perform a more time consuming detailed rendering of the points.


Currently the viewer crashes for larger number of points. The actual number depends on system and GPU memory. On certain machines this is known to start happening around 100M points.


View manipulation. The camera look at position is denoted by a red-green-blue cursor, with segments corresponding to x, y and z axes. Perform LMB drag to rotate the viewpoint in a turntable fashion. Perform LMB drag while hold Shift to pan the viewpoint. Double clicking the LMB moves the look at position to a point near the mouse cursor.


LMB/RMB stands for left/right mouse button

Point selection. Hold Ctrl/Ctrl-Shift while LMB dragging a box to add/remove points to the current selection. Hold Ctrl/Ctrl-Shift while LMB clicking on a point to add/remove a single point from the current selection. Click the RMB to clear the current selection. Use pptk.viewer.get() to query the selected point indices.


If you are using a Mac, use in place of Ctrl.

Hot keys.

key Description
5 Toggle between orthographic/perspective projection
1 Look along +y direction
3 Look along -x direction
7 Look along -z direction
C Set look at position to mean position of selected points
[ Toggle previous attribute set
] Toggle next attribute set


class pptk.viewer(*args, **kwargs)
__init__(*args, **kwargs)

Opens a point cloud viewer


Create 100 random points

>>> xyz = pptk.rand(100, 3)

Visualize the points

>>> v = pptk.viewer(xyz)
>>> v.set(point_size=0.005)

Visualize points shaded by height

>>> v = pptk.viewer(xyz, xyz[:, 2])
>>> v.set(point_size=0.005)

Visualize points shaded by random RGB color

>>> rgb = pptk.rand(100, 3)
>>> pptk.viewer(xyz, rgb)
>>> v.set(point_size=0.005)

Loads point attributes

The loaded attributes are used to clor the currently loaded point cloud. Supposing n points loaded, this function accepts attributes of the following forms:

  • scalars: 1-d array of length 1 or n
  • RGB colors: 2-d array of shape (1, 3) or (n, 3)
  • RGBA colors: 2-d array of shape (1, 4) or (n, 4)

Passing in no arguments clears all existing attribute sets and colors all points white. Cycle through attribute sets via [ and ] keys.


>>> xyz = pptk.rand(100, 3)
>>> v = pptk.viewer(xyz)
>>> attr1 = pptk.rand(100)     # 100 random scalars
>>> attr2 = pptk.rand(100, 3)  # 100 random RGB colors
>>> attr3 = pptk.rand(100, 4)  # 100 random RGBA colors
>>> attr4 = pptk.rand(1)       # 1 random scalar
>>> attr5 = pptk.rand(1, 3)    # 1 random RGB color
>>> attr6 = pptk.rand(1, 4)    # 1 random RGBA color
>>> v.attributes(attr1, attr2, attr3, attr4, attr5, attr6)
>>> v.set(point_size=0.005)

Take screen shot of current view and save to filename


>>> v = pptk.viewer(xyz)
>>> v.capture('screenshot.png')

Removes the current point cloud in the viewer


>>> v.clear()

Closes the point cloud viewer


>>> v.close()
color_map(c, scale=None)

Specifies how scalar attributes are used to color points in the viewer.

Input c is expected to be an array of n RGB (or RGBA) vectors (i.e. c is a n x 3 or n x 4 numpy array). Upon return, scalar values equal to scale 0 are colored with c[0], scale[1] with c[-1], and scalars in between appropriately interpolated. If scale is None, scale is automatically set as the minimum and maximum scalar values in the current attribute set.

Alternatively, one can choose from a number of preset color maps by passing the corresponding string instead.

Preset color maps  
‘jet’ (default) _images/colormap_jet.png
‘hsv’ _images/colormap_hsv.png
‘hot’ _images/colormap_hot.png
‘cool’ _images/colormap_cool.png
‘spring’ _images/colormap_spring.png
‘summer’ _images/colormap_summer.png
‘autumn’ _images/colormap_autumn.png
‘winter’ _images/colormap_winter.png
‘gray’ _images/colormap_gray.png


>>> xyz = np.c_[np.arange(10), np.zeros(10), np.zeros(10)]
>>> scalars = np.arange(10)
>>> v = pptk.viewer(xyz, scalars)
>>> v.set(point_size=0.1)
>>> v.color_map('cool', scale=[0, 5])
>>> v.color_map([[0, 0, 0], [1, 1, 1]])

Gets viewer property

Property Name Return Type Description
curr_atribute_id uint Current attribute set index
eye 3 x float64 Camera position
lookat 3 x float64 Camera look-at position
mvp 4 x 4 float64  
num_points uint Number of points loaded
num_attributes uint Number of attribute sets loaded
phi float64 Camera azimuthal angle (radians)
r float64 Camera distance to look-at point
right 3 x float64 Camera Right vector
selected ? x int32 Indices of selected points
theta float64 Camera elevation angle (radians)
up 3 x float64 Camera up vector
view 3 x float64 Camera view vector


>>> v = pptk.viewer(xyz)
>>> v.get('selected')
play(poses, ts=[], tlim=[-inf, inf], repeat=False, interp='cubic_natural')

Plays back camera path animation specified by poses

  • poses – Key poses. e.g. a list of 6-tuples (x, y, z, phi, theta, r) poses, or anything convertible to a 6-column array by np.array
  • ts (optional) – Key pose times. If unspecified key poses are placed at 1 second intervals.
  • tlim (optional) – Play back time range (in seconds)
  • repeat (optional) – Toggles infinite play back loop. Works well with interp=’cubic_periodic’.
  • interp (optional) – Interpolation method. Should be one of ‘constant’, ‘linear’, ‘cubic_natural’, or ‘cubic_periodic’.


Rotate camera about origin at 1/8 Hz.

>>> poses = []
>>> poses.append([0, 0, 0, 0 * np.pi/2, np.pi/4, 5])
>>> poses.append([0, 0, 0, 1 * np.pi/2, np.pi/4, 5])
>>> poses.append([0, 0, 0, 2 * np.pi/2, np.pi/4, 5])
>>> poses.append([0, 0, 0, 3 * np.pi/2, np.pi/4, 5])
>>> poses.append([0, 0, 0, 4 * np.pi/2, np.pi/4, 5])
>>> v.play(poses, 2 * np.arange(5), repeat=True, interp='linear')
record(folder, poses, ts=[], tlim=[-inf, inf], interp='cubic_natural', shutter_speed=inf, fps=24, prefix='frame_', ext='png')

Records camera animation to a sequence of images. Usage of this method is very similar to viewer.play(…).



Assuming poses defined as in the example for :meth:pptk.viewer.play

>>> mkdir 'recording'
>>> v.record('recording', poses)

Tip: Uses ffmpeg to generate a video from the resulting image sequence

>>> ffmpeg -i "frame_%03d.png" -c:v mpeg4 -qscale:v 0 -r 24 output.mp4

Resets the viewer


Sets viewer property

Property Name Value Type Description
bg_color 4 x float32 Background color in RGBA [0, 1]
bg_color_top 4 x float32 Top background color
bg_color_bottom 4 x float32 Bottom background color
color_map ? x 4 x float32 Color map; array of RGBA’s [0, 1]
color_map_scale 2 x float32 Color map scaling interval
curr_attribute_id uint Current attribute set index
floor_level float32 Floor z-level
floor_color 4 x float32 Floor color in RGBA [0, 1]
lookat 3 x float32 Camera look-at position
phi float32 Camera azimuthal angle (radians)
point_size float32 Point size in world space
r float32 Camera distance to look-at point
selected ? x uint Indices of selected points
show_grid bool Show floor grid
show_info bool Show information text overlay
show_axis bool Show axis / look-at cursor
theta float32 Camera elevation angle (radians)

(phi, theta, r) are spherical coordinates specifying camera position relative to the look at position.

(right, up, view) are orthogonal vectors forming the camera coordinate frame, where view is pointed away from the look at position, and view is the cross product of up with right


>>> v = pptk.viewer(xyz)
>>> v.set(point_size = 0.01)

Blocks until Enter/Return key is pressed in viewer


>>> v = pptk.viewer(xyz)
>>> v.wait()

Press enter in viewer to return control to python terminal.