diff --git a/src/PythonicAPI/GeometricObjects/IsoparametricCellsDemo.md b/src/PythonicAPI/GeometricObjects/IsoparametricCellsDemo.md
index 2ad20d3636821ff6da1cc815065145181ee311a9..32dc37d671ea45a82196793a21755b1564bbb005 100644
--- a/src/PythonicAPI/GeometricObjects/IsoparametricCellsDemo.md
+++ b/src/PythonicAPI/GeometricObjects/IsoparametricCellsDemo.md
@@ -6,6 +6,9 @@ in [finite element analysis](https://en.wikipedia.org/wiki/Finite_element_method
 from the use of the same shape functions (or interpolation functions)  to define the element's geometric shape as are
 used to define the displacements within the element.
 
+Options are provided to show a wire frame (`-w`) or to add a back face color (`-b`). You can also remove the plinth with the (`-n`) option.
+If you want a single object, use `-o` followed by the object number.
+
 This example illustrates each cell's representation using its parametric coordinates (pcoords) as the vertices of the
 cell. In practice, the vertices will correspond to physical points in a finite element model. Use vtkTessellatorFilter
 to better see the shape of the cell. See for example, [QuadraticHexahedronDemo](../QuadraticHexahedronDemo)
diff --git a/src/PythonicAPI/GeometricObjects/IsoparametricCellsDemo.py b/src/PythonicAPI/GeometricObjects/IsoparametricCellsDemo.py
index 2ae798ac69a477582f885aaba3bfbbdb06cee9e6..428de8fb3ba7ac2a9ce4b73d335e634fd0632afa 100755
--- a/src/PythonicAPI/GeometricObjects/IsoparametricCellsDemo.py
+++ b/src/PythonicAPI/GeometricObjects/IsoparametricCellsDemo.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 
+from collections import namedtuple
 from dataclasses import dataclass
 
 # noinspection PyUnresolvedReferences
@@ -7,12 +8,16 @@ import vtkmodules.vtkInteractionStyle
 # noinspection PyUnresolvedReferences
 import vtkmodules.vtkRenderingOpenGL2
 from vtkmodules.vtkCommonColor import vtkNamedColors
+from vtkmodules.vtkCommonCore import vtkPoints
 from vtkmodules.vtkCommonDataModel import (
+    vtkPolyData,
+    vtkCellArray,
     vtkBiQuadraticQuad,
     vtkBiQuadraticQuadraticHexahedron,
     vtkBiQuadraticQuadraticWedge,
     vtkBiQuadraticTriangle,
     vtkCubicLine,
+    vtkPolyLine,
     vtkQuadraticEdge,
     vtkQuadraticHexahedron,
     vtkQuadraticLinearQuad,
@@ -26,7 +31,15 @@ from vtkmodules.vtkCommonDataModel import (
     vtkTriQuadraticHexahedron,
     vtkUnstructuredGrid
 )
-from vtkmodules.vtkFiltersSources import vtkSphereSource
+# noinspection PyUnresolvedReferences
+from vtkmodules.vtkCommonTransforms import vtkTransform
+from vtkmodules.vtkFiltersCore import vtkAppendPolyData
+# noinspection PyUnresolvedReferences
+from vtkmodules.vtkFiltersGeneral import vtkTransformFilter
+from vtkmodules.vtkFiltersSources import (
+    vtkCubeSource,
+    vtkSphereSource
+)
 from vtkmodules.vtkInteractionWidgets import (
     vtkTextRepresentation,
     vtkTextWidget
@@ -34,8 +47,12 @@ from vtkmodules.vtkInteractionWidgets import (
 from vtkmodules.vtkRenderingCore import (
     vtkActor,
     vtkActor2D,
+    vtkCoordinate,
     vtkDataSetMapper,
     vtkGlyph3DMapper,
+    vtkPolyDataMapper,
+    vtkPolyDataMapper2D,
+    vtkProperty,
     vtkRenderWindow,
     vtkRenderWindowInteractor,
     vtkRenderer,
@@ -45,154 +62,291 @@ from vtkmodules.vtkRenderingCore import (
 from vtkmodules.vtkRenderingLabel import vtkLabeledDataMapper
 
 
+def get_program_parameters():
+    import argparse
+    description = 'Demonstrate the isoparametric cell types found in VTK.'
+    epilogue = '''
+     The numbers define the ordering of the points making the cell.
+    '''
+    parser = argparse.ArgumentParser(description=description, epilog=epilogue,
+                                     formatter_class=argparse.RawDescriptionHelpFormatter)
+    group1 = parser.add_mutually_exclusive_group()
+    group1.add_argument('-w', '--wireframe', action='store_true',
+                        help='Render a wireframe.')
+    group1.add_argument('-b', '--backface', action='store_true',
+                        help='Display the back face in a different colour.')
+
+    parser.add_argument('-o', '--object_number', type=int, default=None,
+                        help='The name of the surface e.g. "Figure-8 Klein".')
+    parser.add_argument('-n', '--no_plinth', action='store_true',
+                        help='Remove the plinth.')
+    args = parser.parse_args()
+    return args.wireframe, args.backface, args.object_number, args.no_plinth
+
+
 def main():
-    colors = vtkNamedColors()
+    wireframe_on, backface_on, object_num, plinth_off = get_program_parameters()
 
-    # Set up the viewports.
-    x_grid_dimensions = 4
-    y_grid_dimensions = 4
-    renderer_size = 240
-    size = (renderer_size * x_grid_dimensions, renderer_size * y_grid_dimensions)
-    viewports = list()
-    for row in range(0, y_grid_dimensions):
-        for col in range(0, x_grid_dimensions):
-            # (xmin, ymin, xmax, ymax)
-            viewports.append([float(col) / x_grid_dimensions,
-                              float(y_grid_dimensions - (row + 1)) / y_grid_dimensions,
-                              float(col + 1) / x_grid_dimensions,
-                              float(y_grid_dimensions - row) / y_grid_dimensions])
-
-    ren_win = vtkRenderWindow(size=size, window_name='IsoparametricCellsDemo')
+    objects, object_order = specify_objects()
 
-    iren = vtkRenderWindowInteractor()
-    iren.render_window = ren_win
+    # Check for a single object.
+    single_object = None
+    if object_num:
+        if object_num in object_order:
+            single_object = True
+        else:
+            print('Object not found.\nPlease enter the number corresponding to the object.')
+            print('Available objects are:')
+            for obj in object_order:
+                print(f'{objects[obj]} (= {str(obj)})')
+            return
 
-    u_grids, titles = get_unstructured_grids()
+    colors = vtkNamedColors()
 
     # Create one sphere for all.
-    sphere = vtkSphereSource(phi_resolution=21, theta_resolution=21, radius=0.08)
+    sphere = vtkSphereSource(phi_resolution=21, theta_resolution=21, radius=0.04)
+
+    cells = get_unstructured_grids()
+    if single_object:
+        keys = [f'{objects[object_num]} (={str(object_num)})']
+    else:
+        keys = list(cells.keys())
+
+    add_plinth = ('VTK_QUADRATIC_TETRA (=24)',
+                  'VTK_QUADRATIC_HEXAHEDRON (=25)',
+                  'VTK_HEXAHEDRON (=12)',
+                  'VTK_QUADRATIC_WEDGE (=26)',
+                  'VTK_QUADRATIC_PYRAMID (=27)',
+                  'VTK_TRIQUADRATIC_HEXAHEDRON (=29)',
+                  'VTK_QUADRATIC_LINEAR_WEDGE (=31)',
+                  'VTK_BIQUADRATIC_QUADRATIC_WEDGE (=32)',
+                  'VTK_BIQUADRATIC_QUADRATIC_HEXAHEDRON (=33)',
+                  )
+    lines = ('VTK_QUADRATIC_EDGE (=21)', 'VTK_CUBIC_LINE (=35)')
+
+    # Set up the viewports.
+    if single_object:
+        grid_column_dimensions = 1
+        grid_row_dimensions = 1
+        renderer_size = 1200
+    else:
+        grid_column_dimensions = 4
+        grid_row_dimensions = 4
+        renderer_size = 300
+
+    window_size = (grid_column_dimensions * renderer_size, grid_row_dimensions * renderer_size)
+
+    viewports = dict()
+    VP_Params = namedtuple('VP_Params', ['viewport', 'border'])
+    last_col = False
+    last_row = False
+    blank = len(cells)
+    blank_viewports = list()
+
+    for row in range(0, grid_row_dimensions):
+        if row == grid_row_dimensions - 1:
+            last_row = True
+        for col in range(0, grid_column_dimensions):
+            if col == grid_column_dimensions - 1:
+                last_col = True
+            index = row * grid_column_dimensions + 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, and we want to draw the grid from top to down.
+            viewport = (float(col) / grid_column_dimensions,
+                        float(grid_row_dimensions - (row + 1)) / grid_row_dimensions,
+                        float(col + 1) / grid_column_dimensions,
+                        float(grid_row_dimensions - row) / grid_row_dimensions)
+
+            if last_row and last_col:
+                border = ViewPort.Border.TOP_LEFT_BOTTOM_RIGHT
+                last_row = False
+                last_col = False
+            elif last_col:
+                border = ViewPort.Border.RIGHT_TOP_LEFT
+                last_col = False
+            elif last_row:
+                border = ViewPort.Border.TOP_LEFT_BOTTOM
+            else:
+                border = ViewPort.Border.TOP_LEFT
+            vp_params = VP_Params(viewport, border)
+            if index < blank:
+                viewports[keys[index]] = vp_params
+            else:
+                s = f'vp_{col:d}_{row:d}'
+                viewports[s] = vp_params
+                blank_viewports.append(s)
 
     # Create one text property for all.
-    text_property = vtkTextProperty(color=colors.GetColor3d('LightGoldenrodYellow'), bold=True, italic=True,
-                                    shadow=True, font_family_as_string='Courier',
-                                    font_size=16, justification=TextProperty.Justification.VTK_TEXT_CENTERED)
+    text_property = vtkTextProperty(color=colors.GetColor3d('Black'),
+                                    bold=True, italic=False, shadow=False,
+                                    font_family_as_string='Courier',
+                                    font_size=int(renderer_size / 18),
+                                    justification=TextProperty.Justification.VTK_TEXT_CENTERED)
+
+    label_property = vtkTextProperty(color=colors.GetColor3d('DeepPink'),
+                                     bold=True, italic=False, shadow=True,
+                                     font_family_as_string='Courier',
+                                     font_size=int(renderer_size / 12),
+                                     justification=TextProperty.Justification.VTK_TEXT_CENTERED)
+
+    back_property = vtkProperty(color=colors.GetColor3d('DodgerBlue'))
 
     # Position text according to its length and centered in the viewport.
-    text_positions = get_text_positions(titles, justification=TextProperty.Justification.VTK_TEXT_CENTERED)
+    text_positions = get_text_positions(keys,
+                                        justification=TextProperty.Justification.VTK_TEXT_CENTERED,
+                                        vertical_justification=TextProperty.VerticalJustification.VTK_TEXT_BOTTOM,
+                                        width=0.85, height=0.1)
 
+    ren_win = vtkRenderWindow(size=window_size, window_name='LinearCellDemo')
+    ren_win.SetWindowName('LinearCellDemo')
+    iren = vtkRenderWindowInteractor()
+    iren.render_window = ren_win
+    iren.interactor_style.SetCurrentStyleToTrackballCamera()
+
+    renderers = dict()
     text_representations = list()
     text_actors = list()
     text_widgets = list()
-    renderers = list()
-
-    # Create and link the mappers actors and renderers together.
-    for i in range(0, len(u_grids)):
-        name = titles[i]
-        print('Creating:', titles[i])
 
-        renderer = vtkRenderer(background=colors.GetColor3d('SlateGray'), viewport=viewports[i])
-
-        # Create the text actor and representation.
-        text_actors.append(
-            vtkTextActor(input=name,
-                         text_scale_mode=vtkTextActor.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[i].GetPositionCoordinate().value = text_positions[name]['p']
-        text_representations[i].GetPosition2Coordinate().value = text_positions[name]['p2']
-
-        # Create the text widget, setting the default renderer and interactor.
-        text_widgets.append(
-            vtkTextWidget(representation=text_representations[i], text_actor=text_actors[i],
-                          default_renderer=renderer, interactor=iren, selectable=False))
+    # Create and link the mappers, actors and renderers together.
+    for key in keys:
+        print('Creating:', key)
 
         mapper = vtkDataSetMapper()
-        u_grids[i] >> mapper
-
+        cells[key][0] >> mapper
         actor = vtkActor(mapper=mapper)
-        actor.property.color = colors.GetColor3d('Tomato')
-        actor.property.edge_visibility = True
-        actor.property.line_width = 3
-        actor.property.opacity = 0.5
+        if wireframe_on or key in lines:
+            actor.property.representation = Property.Representation.VTK_WIREFRAME
+            actor.property.line_width = 2
+            actor.property.opacity = 1
+            actor.property.color = colors.GetColor3d('Black')
+        else:
+            actor.property.EdgeVisibilityOn()
+            actor.property.line_width = 3
+            actor.property.color = colors.GetColor3d('Snow')
+            if backface_on:
+                actor.property.opacity = 0.4
+                actor.SetBackfaceProperty(back_property)
+                back_property.opacity = 0.6
+            else:
+                actor.property.opacity = 0.8
 
         # Label the points.
         label_mapper = vtkLabeledDataMapper()
-        label_mapper.SetInputData(u_grids[i])
-        label_actor = vtkActor2D()
-        label_actor.SetMapper(label_mapper)
-
-        # Glyph the points
-        point_mapper = vtkGlyph3DMapper(input_data=u_grids[i], source_data=sphere.update().output, scaling=False,
-                                        scalar_visibility=False)
-
+        cells[key][0] >> label_mapper
+        label_mapper.label_text_property = label_property
+        label_actor = vtkActor2D(mapper=label_mapper)
+
+        # Glyph the points.
+        point_mapper = vtkGlyph3DMapper(scaling=True, scalar_visibility=False,
+                                        source_connection=sphere.output_port)
+        cells[key][0] >> point_mapper
         point_actor = vtkActor(mapper=point_mapper)
-        point_actor.property.diffuse_color = colors.GetColor3d('Banana')
-        point_actor.property.specular = 0.6
-        point_actor.property.specular_color = (1.0, 1.0, 1.0)
-        point_actor.property.specular_power = 100
+        point_actor.property.color = colors.GetColor3d('Gold')
+
+        viewport = viewports[key].viewport
+        border = viewports[key].border
+        renderer = vtkRenderer(background=colors.GetColor3d('LightSteelBlue'), viewport=viewport)
+        draw_viewport_border(renderer, border=border, color=colors.GetColor3d('MidnightBlue'), line_width=4)
+
+        renderer.AddActor(actor)
+        renderer.AddActor(label_actor)
+        renderer.AddActor(point_actor)
+        if not plinth_off:
+            # Add a plinth.
+            if key in add_plinth:
+                tile_actor = make_tile(cells[key][0].GetBounds(), expansion_factor=0.5, thickness_ratio=0.05)
+                tile_actor.GetProperty().SetColor(colors.GetColor3d('Lavender'))
+                tile_actor.GetProperty().SetOpacity(0.3)
+                renderer.AddActor(tile_actor)
 
-        renderer.AddViewProp(actor)
-        renderer.AddViewProp(label_actor)
-        renderer.AddViewProp(point_actor)
+        # Create the text actor and representation.
+        text_actor = vtkTextActor(input=key,
+                                  text_scale_mode=vtkTextActor.TEXT_SCALE_MODE_NONE,
+                                  text_property=text_property)
 
-        renderers.append(renderer)
+        # Create the text representation. Used for positioning the text actor.
+        text_representation = vtkTextRepresentation(enforce_normalized_viewport_bounds=True)
+        text_representation.GetPositionCoordinate().value = text_positions[key]['p']
+        text_representation.GetPosition2Coordinate().value = text_positions[key]['p2']
+
+        # Create the text widget, setting the default renderer and interactor.
+        text_widget = vtkTextWidget(representation=text_representation, text_actor=text_actor,
+                                    default_renderer=renderer, interactor=iren, selectable=False)
 
-        ren_win.AddRenderer(renderers[i])
+        text_actors.append(text_actor)
+        text_representations.append(text_representation)
+        text_widgets.append(text_widget)
 
-    for row in range(0, y_grid_dimensions):
-        for col in range(0, x_grid_dimensions):
-            index = row * x_grid_dimensions + col
+        renderer.ResetCamera()
+        renderer.active_camera.Azimuth(cells[key][1].azimuth)
+        renderer.active_camera.Elevation(cells[key][1].elevation)
+        renderer.active_camera.Dolly(cells[key][1].zoom)
+        renderer.ResetCameraClippingRange()
 
-            if index > (len(renderers) - 1):
-                # Add a renderer even if there is no actor.
-                # This makes the render window background all the same color.
-                ren = vtkRenderer(background=colors.GetColor3d('SlateGray'), viewport=viewports[index])
-                ren_win.AddRenderer(ren)
+        renderers[key] = renderer
 
-                continue
+        ren_win.AddRenderer(renderers[key])
 
-            renderers[index].ResetCamera()
-            renderers[index].active_camera.Azimuth(30)
-            renderers[index].active_camera.Elevation(-30)
-            renderers[index].ResetCameraClippingRange()
+    for name in blank_viewports:
+        viewport = viewports[name].viewport
+        border = viewports[name].border
+        renderer = vtkRenderer(background=colors.GetColor3d('LightSteelBlue'), viewport=viewport)
+        draw_viewport_border(renderer, border=border, color=colors.GetColor3d('MidnightBlue'), line_width=4)
+        ren_win.AddRenderer(renderer)
 
-    for i in range(0, len(titles)):
+    for i in range(0, len(text_widgets)):
         text_widgets[i].On()
 
-    iren.Initialize()
     ren_win.Render()
+    iren.Initialize()
     iren.Start()
 
 
+def specify_objects():
+    objects = {
+        21: 'VTK_QUADRATIC_EDGE',
+        22: 'VTK_QUADRATIC_TRIANGLE',
+        23: 'VTK_QUADRATIC_QUAD',
+        36: 'VTK_QUADRATIC_POLYGON',
+        24: 'VTK_QUADRATIC_TETRA',
+        25: 'VTK_QUADRATIC_HEXAHEDRON',
+        26: 'VTK_QUADRATIC_WEDGE',
+        27: 'VTK_QUADRATIC_PYRAMID',
+        28: 'VTK_BIQUADRATIC_QUAD',
+        29: 'VTK_TRIQUADRATIC_HEXAHEDRON',
+        30: 'VTK_QUADRATIC_LINEAR_QUAD',
+        31: 'VTK_QUADRATIC_LINEAR_WEDGE',
+        32: 'VTK_BIQUADRATIC_QUADRATIC_WEDGE',
+        33: 'VTK_BIQUADRATIC_QUADRATIC_HEXAHEDRON',
+        34: 'VTK_BIQUADRATIC_TRIANGLE',
+        35: 'VTK_CUBIC_LINE',
+    }
+    object_order = list(objects.keys())
+    return objects, object_order
+
+
 # These functions return a vtkUnstructured grid corresponding to the object.
 
-def make_unstructured_grid(a_cell):
-    pcoords = a_cell.GetParametricCoords()
-    for i in range(0, a_cell.number_of_points):
-        a_cell.point_ids.SetId(i, i)
-        a_cell.points.SetPoint(i, (pcoords[3 * i]), (pcoords[3 * i + 1]), (pcoords[3 * i + 2]))
+def make_ug(cell):
+    pcoords = cell.GetParametricCoords()
+    for i in range(0, cell.number_of_points):
+        cell.point_ids.SetId(i, i)
+        cell.points.SetPoint(i, (pcoords[3 * i]), (pcoords[3 * i + 1]), (pcoords[3 * i + 2]))
 
-    ug = vtkUnstructuredGrid(points=a_cell.points)
-    ug.InsertNextCell(a_cell.cell_type, a_cell.point_ids)
+    ug = vtkUnstructuredGrid(points=cell.points)
+    ug.InsertNextCell(cell.cell_type, cell.point_ids)
     return ug
 
 
 def make_quadratic_polygon():
-    quadratic_polygon = vtkQuadraticPolygon()
+    number_of_vertices = 8
 
-    quadratic_polygon.point_ids.SetNumberOfIds(8)
-    quadratic_polygon.point_ids.SetId(0, 0)
-    quadratic_polygon.point_ids.SetId(1, 1)
-    quadratic_polygon.point_ids.SetId(2, 2)
-    quadratic_polygon.point_ids.SetId(3, 3)
-    quadratic_polygon.point_ids.SetId(4, 4)
-    quadratic_polygon.point_ids.SetId(5, 5)
-    quadratic_polygon.point_ids.SetId(6, 6)
-    quadratic_polygon.point_ids.SetId(7, 7)
+    quadratic_polygon = vtkQuadraticPolygon()
 
     quadratic_polygon.points.SetNumberOfPoints(8)
+
     quadratic_polygon.points.SetPoint(0, 0.0, 0.0, 0.0)
     quadratic_polygon.points.SetPoint(1, 2.0, 0.0, 0.0)
     quadratic_polygon.points.SetPoint(2, 2.0, 2.0, 0.0)
@@ -203,79 +357,75 @@ def make_quadratic_polygon():
     quadratic_polygon.points.SetPoint(7, 0.0, 1.0, 0.0)
     quadratic_polygon.points.SetPoint(5, 3.0, 1.0, 0.0)
 
+    quadratic_polygon.point_ids.SetNumberOfIds(number_of_vertices)
+    for i in range(0, number_of_vertices):
+        quadratic_polygon.point_ids.SetId(i, i)
+
     ug = vtkUnstructuredGrid(points=quadratic_polygon.points)
     ug.InsertNextCell(quadratic_polygon.cell_type, quadratic_polygon.point_ids)
-    return ug
-
 
-def get_unstructured_grids():
-    u_grids = list()
-    titles = list()
-
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticEdge()))
-    titles.append('VTK_QUADRATIC_EDGE (= 21)')
-
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticTriangle()))
-    titles.append('VTK_QUADRATIC_TRIANGLE (= 22)')
-
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticQuad()))
-    titles.append('VTK_QUADRATIC_QUAD (= 23)')
-
-    u_grids.append(make_quadratic_polygon())
-    titles.append('VTK_QUADRATIC_POLYGON (= 36)')
-
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticTetra()))
-    titles.append('VTK_QUADRATIC_TETRA (= 24)')
-
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticHexahedron()))
-    titles.append('VTK_QUADRATIC_HEXAHEDRON (= 25)')
-
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticWedge()))
-    titles.append('VTK_QUADRATIC_WEDGE (= 26)')
+    return ug
 
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticPyramid()))
-    titles.append('VTK_QUADRATIC_PYRAMID (= 27)')
 
-    u_grids.append(make_unstructured_grid(
-        vtkBiQuadraticQuad()))
-    titles.append('VTK_BIQUADRATIC_QUAD (= 28)')
+def make_quadratic_pyramid():
+    cell = vtkQuadraticPyramid()
+    pcoords = cell.GetParametricCoords()
+    for i in range(0, cell.number_of_points):
+        cell.point_ids.SetId(i, i)
+        cell.points.SetPoint(i, (pcoords[3 * i]), (pcoords[3 * i + 1]), (pcoords[3 * i + 2]))
 
-    u_grids.append(make_unstructured_grid(
-        vtkTriQuadraticHexahedron()))
-    titles.append('VTK_TRIQUADRATIC_HEXAHEDRON (= 29)')
+    ug = vtkUnstructuredGrid(points=cell.points)
+    ug.InsertNextCell(cell.cell_type, cell.point_ids)
 
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticLinearQuad()))
-    titles.append('VTK_QUADRATIC_LINEAR_QUAD (= 30)')
+    # pd = vtkPolyData(points=quadratic_polygon.points)
+    t = vtkTransform()
+    t.RotateX(-90)
+    t.Translate(0, 0, 0)
+    tf = vtkTransformFilter(transform=t)
+    (ug >> tf).update()
+    # pts = tf.output.GetPoints()
+    # for i in range(0, pts.number_of_points):
+    #     print(f'quadratic_polygon.points.SetPoint({i}, {pts.GetPoint(i)})')
+    return tf.output
 
-    u_grids.append(make_unstructured_grid(
-        vtkQuadraticLinearWedge()))
-    titles.append('VTK_QUADRATIC_LINEAR_WEDGE (= 31)')
 
-    u_grids.append(make_unstructured_grid(
-        vtkBiQuadraticQuadraticWedge()))
-    titles.append('VTK_BIQUADRATIC_QUADRATIC_WEDGE (= 32)')
+def get_unstructured_grids():
+    """
+    Get the unstructured grid names, the unstructured grid and initial orientations.
 
-    u_grids.append(make_unstructured_grid(
-        vtkBiQuadraticQuadraticHexahedron()))
-    titles.append('VTK_BIQUADRATIC_QUADRATIC_HEXAHEDRON (= 33)')
+    :return: A dictionary of unstructured grids.
+    """
 
-    u_grids.append(make_unstructured_grid(
-        vtkBiQuadraticTriangle()))
-    titles.append('VTK_BIQUADRATIC_TRIANGLE (= 34)')
+    def make_orientation(azimuth: float = 0, elevation: float = 0, zoom: float = 1.0):
+        return Orientation(azimuth, elevation, zoom)
+
+    return {
+        'VTK_QUADRATIC_EDGE (=21)': (make_ug(vtkQuadraticEdge()), make_orientation(0, 0, 0.8)),
+        'VTK_QUADRATIC_TRIANGLE (=22)': (make_ug(vtkQuadraticTriangle()), make_orientation(0, 0, 0)),
+        'VTK_QUADRATIC_QUAD (=23)': (make_ug(vtkQuadraticQuad()), make_orientation(0, 0, 0)),
+        'VTK_QUADRATIC_POLYGON (=36)': (make_quadratic_polygon(), make_orientation(0, 0, 0)),
+        'VTK_QUADRATIC_TETRA (=24)': (make_ug(vtkQuadraticTetra()), make_orientation(20, 20, 1.0)),
+        'VTK_QUADRATIC_HEXAHEDRON (=25)': (make_ug(vtkQuadraticHexahedron()), make_orientation(-22.5, 15, 0.95)),
+        'VTK_QUADRATIC_WEDGE (=26)': (make_ug(vtkQuadraticWedge()), make_orientation(60, 22.5, 1.0)),
+        'VTK_QUADRATIC_PYRAMID (=27)': (make_quadratic_pyramid(), make_orientation(-90 - 60, 8, 1.0)),
+        'VTK_BIQUADRATIC_QUAD (=28)': (make_ug(vtkBiQuadraticQuad()), make_orientation(0, 0, 0)),
+        'VTK_TRIQUADRATIC_HEXAHEDRON (=29)': (make_ug(vtkTriQuadraticHexahedron()), make_orientation(-22.5, 15, 0.95)),
+        'VTK_QUADRATIC_LINEAR_QUAD (=30)': (make_ug(vtkQuadraticLinearQuad()), make_orientation(0, 0, 0)),
+        'VTK_QUADRATIC_LINEAR_WEDGE (=31)': (make_ug(vtkQuadraticLinearWedge()), make_orientation(60, 22.5, 1.0)),
+        'VTK_BIQUADRATIC_QUADRATIC_WEDGE (=32)': (
+            make_ug(vtkBiQuadraticQuadraticWedge()), make_orientation(70, 22.5, 1.0)),
+        'VTK_BIQUADRATIC_QUADRATIC_HEXAHEDRON (=33)': (
+            make_ug(vtkBiQuadraticQuadraticHexahedron()), make_orientation(-22.5, 15, 0.95)),
+        'VTK_BIQUADRATIC_TRIANGLE (=34)': (make_ug(vtkBiQuadraticTriangle()), make_orientation(0, 0, 0)),
+        'VTK_CUBIC_LINE (=35)': (make_ug(vtkCubicLine()), make_orientation(0, 0, 0.85)),
+    }
 
-    u_grids.append(make_unstructured_grid(
-        vtkCubicLine()))
-    titles.append('VTK_CUBIC_LINE (= 35)')
 
-    return u_grids, titles
+@dataclass(frozen=True)
+class Orientation:
+    azimuth: float
+    elevation: float
+    zoom: float
 
 
 def get_text_positions(names, justification=0, vertical_justification=0, width=0.96, height=0.1):
@@ -342,8 +492,167 @@ def get_text_positions(names, justification=0, vertical_justification=0, width=0
     return text_positions
 
 
+def draw_viewport_border(renderer, border, color=(0, 0, 0), line_width=2):
+    """
+    Draw a border around the viewport of a renderer.
+
+    :param renderer: The renderer.
+    :param border: The border to draw, it must be one of the constants in ViewPort.Border.
+    :param color: The color.
+    :param line_width: The line width of the border.
+    :return:
+    """
+
+    def generate_border_lines(border_type):
+        """
+        Generate the lines for the border.
+
+        :param border_type:  The border type to draw, it must be one of the constants in ViewPort.Border
+        :return: The points and lines.
+        """
+        if border_type >= ViewPort.Border.NUMBER_OF_BORDER_TYPES:
+            print('Not a valid border type.')
+            return None
+
+        # Points start at upper right and proceed anti-clockwise.
+        pts = (
+            (1, 1, 0),
+            (0, 1, 0),
+            (0, 0, 0),
+            (1, 0, 0),
+            (1, 1, 0),
+        )
+        pt_orders = {
+            ViewPort.Border.TOP: (0, 1),
+            ViewPort.Border.LEFT: (1, 2),
+            ViewPort.Border.BOTTOM: (2, 3),
+            ViewPort.Border.RIGHT: (3, 4),
+            ViewPort.Border.LEFT_BOTTOM: (1, 2, 3),
+            ViewPort.Border.BOTTOM_RIGHT: (2, 3, 4),
+            ViewPort.Border.RIGHT_TOP: (3, 4, 1),
+            ViewPort.Border.RIGHT_TOP_LEFT: (3, 4, 1, 2),
+            ViewPort.Border.TOP_LEFT: (0, 1, 2),
+            ViewPort.Border.TOP_LEFT_BOTTOM: (0, 1, 2, 3),
+            ViewPort.Border.TOP_LEFT_BOTTOM_RIGHT: (0, 1, 2, 3, 4)
+        }
+        pt_order = pt_orders[border_type]
+        number_of_points = len(pt_order)
+        points = vtkPoints(number_of_points=number_of_points)
+        i = 0
+        for pt_id in pt_order:
+            points.InsertPoint(i, *pts[pt_id])
+            i += 1
+
+        lines = vtkPolyLine()
+        lines.point_ids.SetNumberOfIds(number_of_points)
+        for i in range(0, number_of_points):
+            lines.point_ids.id = (i, i)
+
+        cells = vtkCellArray()
+        cells.InsertNextCell(lines)
+
+        # Make the polydata and return.
+        return vtkPolyData(points=points, lines=cells)
+
+    # Use normalized viewport coordinates since
+    # they are independent of window size.
+    coordinate = vtkCoordinate(coordinate_system=Coordinate.CoordinateSystem.VTK_NORMALIZED_VIEWPORT)
+    poly = vtkAppendPolyData()
+    if border == ViewPort.Border.TOP_BOTTOM:
+        (
+            generate_border_lines(ViewPort.Border.TOP),
+            generate_border_lines(ViewPort.Border.BOTTOM)
+        ) >> poly
+    elif border == ViewPort.Border.LEFT_RIGHT:
+        (
+            generate_border_lines(ViewPort.Border.LEFT),
+            generate_border_lines(ViewPort.Border.RIGHT)
+        ) >> poly
+    else:
+        generate_border_lines(border) >> poly
+
+    mapper = vtkPolyDataMapper2D(transform_coordinate=coordinate)
+    poly >> mapper
+    actor = vtkActor2D(mapper=mapper)
+    actor.property.color = color
+    # Line width should be at least 2 to be visible at the extremes.
+    actor.property.line_width = line_width
+
+    renderer.AddViewProp(actor)
+
+
+def make_tile(bounds, expansion_factor=0.1, thickness_ratio=0.05):
+    """
+    Make a tile slightly larger or smaller than the bounds in the
+      X and Z directions and thinner or thicker in the Y direction.
+
+    A thickness_ratio of zero reduces the tile to an XZ plane.
+
+    :param bounds: The bounds for the tile.
+    :param expansion_factor: The expansion factor in the XZ plane.
+    :param thickness_ratio: The thickness ratio in the Y direction, >= 0.
+    :return: An actor corresponding to the tile.
+    """
+
+    d_xyz = (
+        bounds[1] - bounds[0],
+        bounds[3] - bounds[2],
+        bounds[5] - bounds[4]
+    )
+    thickness = d_xyz[2] * thickness_ratio
+    center = ((bounds[1] + bounds[0]) / 2.0,
+              bounds[2] - thickness / 2.0,
+              (bounds[5] + bounds[4]) / 2.0)
+    x_length = bounds[1] - bounds[0] + (d_xyz[0] * expansion_factor)
+    z_length = bounds[5] - bounds[4] + (d_xyz[2] * expansion_factor)
+
+    plane = vtkCubeSource(center=center, x_length=x_length, y_length=thickness, z_length=z_length)
+    plane_mapper = vtkPolyDataMapper()
+    plane >> plane_mapper
+    tile_actor = vtkActor(mapper=plane_mapper)
+
+    return tile_actor
+
+
+@dataclass(frozen=True)
+class Coordinate:
+    @dataclass(frozen=True)
+    class CoordinateSystem:
+        VTK_DISPLAY: int = 0
+        VTK_NORMALIZED_DISPLAY: int = 1
+        VTK_VIEWPORT: int = 2
+        VTK_NORMALIZED_VIEWPORT: int = 3
+        VTK_VIEW: int = 4
+        VTK_POSE: int = 5
+        VTK_WORLD: int = 6
+        VTK_USERDEFINED: int = 7
+
+
+@dataclass(frozen=True)
+class Property:
+    @dataclass(frozen=True)
+    class Interpolation:
+        VTK_FLAT: int = 0
+        VTK_GOURAUD: int = 1
+        VTK_PHONG: int = 2
+        VTK_PBR: int = 3
+
+    @dataclass(frozen=True)
+    class Representation:
+        VTK_POINTS: int = 0
+        VTK_WIREFRAME: int = 1
+        VTK_SURFACE: int = 2
+
+
 @dataclass(frozen=True)
 class TextProperty:
+    @dataclass(frozen=True)
+    class FontFamily:
+        VTK_ARIAL: int = 0
+        VTK_COURIER: int = 1
+        VTK_TIMES: int = 2
+        VTK_UNKNOWN_FONT: int = 3
+
     @dataclass(frozen=True)
     class Justification:
         VTK_TEXT_LEFT: int = 0
@@ -357,5 +666,25 @@ class TextProperty:
         VTK_TEXT_TOP: int = 2
 
 
+@dataclass(frozen=True)
+class ViewPort:
+    @dataclass(frozen=True)
+    class Border:
+        TOP: int = 0
+        LEFT: int = 1
+        BOTTOM: int = 2
+        RIGHT: int = 3
+        LEFT_BOTTOM: int = 4
+        BOTTOM_RIGHT: int = 5
+        RIGHT_TOP: int = 6
+        RIGHT_TOP_LEFT: int = 7
+        TOP_LEFT: int = 8
+        TOP_LEFT_BOTTOM: int = 9
+        TOP_LEFT_BOTTOM_RIGHT: int = 10
+        TOP_BOTTOM: int = 11
+        LEFT_RIGHT: int = 12
+        NUMBER_OF_BORDER_TYPES: int = 13
+
+
 if __name__ == '__main__':
     main()
diff --git a/src/PythonicAPI/GeometricObjects/LinearCellDemo.md b/src/PythonicAPI/GeometricObjects/LinearCellDemo.md
index b0b8d3215785d7a64be96e5d19b1665199f71f97..e2828613805d0eeceb73ebf753dc6dc0cfd0acc2 100644
--- a/src/PythonicAPI/GeometricObjects/LinearCellDemo.md
+++ b/src/PythonicAPI/GeometricObjects/LinearCellDemo.md
@@ -5,5 +5,6 @@ Linear cell types found in VTK.
 The numbers define the ordering of the defining points.
 
 Options are provided to show a wire frame (`-w`) or to add a back face color (`-b`). You can also remove the plinth with the (`-n`) option.
+If you want a single object, use `-o` followed by the object number.
 
 With the back face option selected, the back face color will be visible as the objects are semitransparent.
diff --git a/src/PythonicAPI/GeometricObjects/LinearCellDemo.py b/src/PythonicAPI/GeometricObjects/LinearCellDemo.py
index 54aa9d080fc8a97afbec188949a290b8988986ec..b37f2b9c493bdc759b9080bd4eda25371229d49e 100755
--- a/src/PythonicAPI/GeometricObjects/LinearCellDemo.py
+++ b/src/PythonicAPI/GeometricObjects/LinearCellDemo.py
@@ -76,14 +76,30 @@ def get_program_parameters():
     group1.add_argument('-b', '--backface', action='store_true',
                         help='Display the back face in a different colour.')
 
+    parser.add_argument('-o', '--object_number', type=int, default=None,
+                        help='The name of the surface e.g. "Figure-8 Klein".')
     parser.add_argument('-n', '--no_plinth', action='store_true',
                         help='Remove the plinth.')
     args = parser.parse_args()
-    return args.wireframe, args.backface, args.no_plinth
+    return args.wireframe, args.backface, args.object_number, args.no_plinth
 
 
 def main():
-    wireframe_on, backface_on, plinth_off = get_program_parameters()
+    wireframe_on, backface_on, object_num, plinth_off = get_program_parameters()
+
+    objects, object_order = specify_objects()
+
+    # Check for a single object.
+    single_object = None
+    if object_num:
+        if object_num in object_order:
+            single_object = True
+        else:
+            print('Object not found.\nPlease enter the number corresponding to the object.')
+            print('Available objects are:')
+            for obj in object_order:
+                print(f'{objects[obj]} (={str(obj)})')
+            return
 
     colors = vtkNamedColors()
 
@@ -91,7 +107,10 @@ def main():
     sphere = vtkSphereSource(phi_resolution=21, theta_resolution=21, radius=0.04)
 
     cells = get_unstructured_grids()
-    keys = list(cells.keys())
+    if single_object:
+        keys = [f'{objects[object_num]} (={str(object_num)})']
+    else:
+        keys = list(cells.keys())
 
     add_plinth = ('VTK_TETRA (=10)',
                   'VTK_VOXEL (=11)',
@@ -104,9 +123,18 @@ def main():
     lines = ('VTK_LINE (=3)', 'VTK_POLY_LINE (=4)')
 
     # Set up the viewports.
-    grid_column_dimensions = 4
-    grid_row_dimensions = 4
-    renderer_size = 300
+    if single_object:
+        grid_column_dimensions = 1
+        grid_row_dimensions = 1
+        renderer_size = 1200
+    else:
+        grid_column_dimensions = 4
+        grid_row_dimensions = 4
+        renderer_size = 300
+    # Set up the viewports.
+    # grid_column_dimensions = 4
+    # grid_row_dimensions = 4
+    # renderer_size = 300
     window_size = (grid_column_dimensions * renderer_size, grid_row_dimensions * renderer_size)
 
     viewports = dict()
@@ -277,6 +305,29 @@ def main():
     iren.Start()
 
 
+def specify_objects():
+    objects = {
+        1: 'VTK_VERTEX',
+        2: 'VTK_POLY_VERTEX',
+        3: 'VTK_LINE',
+        4: 'VTK_POLY_LINE',
+        5: 'VTK_TRIANGLE',
+        6: 'VTK_TRIANGLE_STRIP',
+        7: 'VTK_POLYGON',
+        8: 'VTK_PIXEL',
+        9: 'VTK_QUAD',
+        10: 'VTK_TETRA',
+        11: 'VTK_VOXEL',
+        12: 'VTK_HEXAHEDRON',
+        13: 'VTK_WEDGE',
+        14: 'VTK_PYRAMID',
+        15: 'VTK_PENTAGONAL_PRISM',
+        16: 'VTK_HEXAGONAL_PRISM',
+    }
+    object_order = list(objects.keys())
+    return objects, object_order
+
+
 def get_unstructured_grids():
     """
     Get the unstructured grid names, the unstructured grid and initial orientations.