diff --git a/src/PythonicAPI.md b/src/PythonicAPI.md
index f8eab46a0dc5099bd037d11143c15b02781fadb9..24beee78b121ac78b4ef1bc246f5a757a3776bb9 100644
--- a/src/PythonicAPI.md
+++ b/src/PythonicAPI.md
@@ -69,6 +69,7 @@ This Python script, [SelectExamples](../Python/Utilities/SelectExamples), will l
 
 | Example Name | Description | Image |
 | -------------- | ------------- | ------- |
+[GeometricObjectsDemo](/PythonicAPI/GeometricObjects/GeometricObjectsDemo) |
 [SourceObjectsDemo](/PythonicAPI/GeometricObjects/SourceObjectsDemo) | Examples of source objects that procedurally generate polygonal models.  These nine images represent just some of the capability of VTK. From upper left in reading order: sphere, cone, cylinder, cube, plane, text, random point cloud, disk (with or without hole), and line source. Other polygonal source objects are available; check subclasses of vtkPolyDataAlgorithm.
 
 ### Cells
diff --git a/src/PythonicAPI/GeometricObjects/GeometricObjectsDemo.py b/src/PythonicAPI/GeometricObjects/GeometricObjectsDemo.py
new file mode 100755
index 0000000000000000000000000000000000000000..0cc8aae222b6c5cb077a9b9bc21e440154f4e4c0
--- /dev/null
+++ b/src/PythonicAPI/GeometricObjects/GeometricObjectsDemo.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python3
+
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkInteractionStyle
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkRenderingFreeType
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkRenderingOpenGL2
+from vtkmodules.vtkCommonColor import vtkNamedColors
+from vtkmodules.vtkFiltersSources import (
+    vtkArrowSource,
+    vtkConeSource,
+    vtkCubeSource,
+    vtkCylinderSource,
+    vtkDiskSource,
+    vtkLineSource,
+    vtkRegularPolygonSource,
+    vtkSphereSource
+)
+from vtkmodules.vtkInteractionStyle import vtkInteractorStyleTrackballCamera
+from vtkmodules.vtkInteractionWidgets import (
+    vtkTextRepresentation,
+    vtkTextWidget
+)
+from vtkmodules.vtkRenderingCore import (
+    vtkActor,
+    vtkPolyDataMapper,
+    vtkProperty,
+    vtkRenderWindow,
+    vtkRenderWindowInteractor,
+    vtkRenderer,
+    vtkTextActor,
+    vtkTextProperty
+)
+
+
+def main():
+    colors = vtkNamedColors()
+
+    # Set the background color.
+    colors.SetColor("BkgColor", [51, 77, 102, 255])
+
+    # Create container to hold the 3D object generators (sources)
+    geometric_object_sources = list()
+
+    # Populate the container with the various object sources to be demonstrated
+    geometric_object_sources.append(vtkArrowSource())
+    geometric_object_sources.append(vtkConeSource())
+    geometric_object_sources.append(vtkCubeSource())
+    geometric_object_sources.append(vtkCylinderSource())
+    geometric_object_sources.append(vtkDiskSource())
+    geometric_object_sources.append(vtkLineSource())
+    geometric_object_sources.append(vtkRegularPolygonSource())
+    geometric_object_sources.append(vtkSphereSource())
+
+    # Define the size of the grid that will hold the objects.
+    grid_cols = 3
+    grid_rows = 3
+    # Define side length (in pixels) of each renderer square.
+    renderer_size = 300
+    size = (renderer_size * grid_cols, renderer_size * grid_rows)
+    render_window = vtkRenderWindow(size=size, window_name='GeometricObjectsDemo')
+
+    interactor = vtkRenderWindowInteractor()
+    interactor.SetRenderWindow(render_window)
+    style = vtkInteractorStyleTrackballCamera()
+    interactor.SetInteractorStyle(style)
+
+    # Create one text property for all.
+    text_scale_mode = {'none': 0, 'prop': 1, 'viewport': 2}
+    justification = {'left': 0, 'centered': 1, 'right': 2}
+    text_property = vtkTextProperty(color=colors.GetColor3d('LightGoldenrodYellow'), bold=True, italic=True,
+                                    shadow=True,
+                                    font_size=16, justification=justification['left'])
+
+    # Position text according to its length and centered in the viewport.
+    name_len_min = 0
+    name_len_max = 0
+    for i in range(0, len(geometric_object_sources)):
+        sz = len(geometric_object_sources[i].class_name)
+        if i == 0:
+            name_len_min = name_len_max = sz
+        else:
+            name_len_min = min(name_len_min, sz)
+            name_len_max = max(name_len_max, sz)
+    text_positions = list()
+    for i in range(0, len(geometric_object_sources)):
+        sz = len(geometric_object_sources[i].class_name)
+        delta_sz = 0.95 * sz / name_len_max
+        x0 = 0.5 - delta_sz / 2.0
+        x1 = delta_sz
+        # print(f'{i}: {x0:3.2f}, {x1:3.2f} len: {x0 + x1:3.2f}')
+        text_positions.append(
+            {'p': [x0, 0.01, 0], 'p2': [x1, 0.2, 0]})
+
+    back_property = vtkProperty(color=colors.GetColor3d('Tomato'))
+
+    mappers = list()
+    actors = list()
+    text_representations = list()
+    text_actors = list()
+    text_widgets = list()
+
+    for row in range(0, grid_rows):
+        for col in range(0, grid_cols):
+            index = row * grid_cols + col
+
+            # Set the renderer's viewport dimensions (xmin, ymin, xmax, ymax) within the render window.
+            # Note that for the Y values, we need to subtract the row index from grid_rows
+            # because the viewport Y axis points upwards, but we want to draw the grid from top to down.
+            viewport = (
+                float(col) / grid_cols,
+                float(grid_rows - row - 1) / grid_rows,
+                float(col + 1) / grid_cols,
+                float(grid_rows - row) / grid_rows
+            )
+
+            # Create a renderer for this grid cell.
+            renderer = vtkRenderer(background=colors.GetColor3d('BkgColor'), viewport=viewport)
+
+            # Add the corresponding actor and label for this grid cell, if they exist.
+            if index < len(geometric_object_sources):
+                # Create the mappers and actors for each object.
+                mappers.append(vtkPolyDataMapper())
+                geometric_object_sources[index] >> mappers[index]
+
+                actors.append(vtkActor(mapper=mappers[index]))
+                actors[index].property.color = colors.GetColor3d('PeachPuff')
+                # actors[index].backface_property = back_property
+
+                renderer.AddActor(actors[index])
+
+                # Create the text actor and representation.
+                text_actors.append(
+                    vtkTextActor(input=geometric_object_sources[index].class_name,
+                                 text_scale_mode=text_scale_mode['none'],
+                                 text_property=text_property))
+
+                # Create the text representation. Used for positioning the text actor.
+                text_representations.append(vtkTextRepresentation(enforce_normalized_viewport_bounds=True))
+                text_representations[index].GetPositionCoordinate().value = text_positions[index]['p']
+                text_representations[index].GetPosition2Coordinate().value = text_positions[index]['p2']
+
+                # Create the text widget, setting the default renderer and interactor.
+                text_widgets.append(
+                    vtkTextWidget(representation=text_representations[index], text_actor=text_actors[index]))
+                text_widgets[index].SetDefaultRenderer(renderer)
+                text_widgets[index].SetInteractor(interactor)
+                text_widgets[index].SelectableOff()
+
+                renderer.ResetCamera()
+
+            render_window.AddRenderer(renderer)
+
+    render_window.Render()
+
+    for i in range(0, len(geometric_object_sources)):
+        text_widgets[i].On()
+
+    interactor.Start()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/Testing/Baseline/PythonicAPI/GeometricObjects/TestGeometricObjectsDemo.png b/src/Testing/Baseline/PythonicAPI/GeometricObjects/TestGeometricObjectsDemo.png
new file mode 100644
index 0000000000000000000000000000000000000000..baa9aa7c87a1f37d25096cb0d8d3ce571e66f302
--- /dev/null
+++ b/src/Testing/Baseline/PythonicAPI/GeometricObjects/TestGeometricObjectsDemo.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:35b2cde14d7691f7ff71d404ccef13e75f4b92ba8e5f552c79044da033283d1c
+size 61974