diff --git a/src/Cxx.md b/src/Cxx.md
index 58fea3881d30e4c62ab0def197b544f83a4f392b..0046562ea888a81206b3bb0e1a5dfa2883aad7cc 100644
--- a/src/Cxx.md
+++ b/src/Cxx.md
@@ -913,6 +913,7 @@ See [this tutorial](http://www.vtk.org/Wiki/VTK/Tutorials/3DDataTypes) for a bri
 [SceneBounds](/Cxx/Visualization/SceneBounds)| vtkRenderer |Get the bounds of the whole scene.
 [SelectWindowRegion](/Cxx/Visualization/SelectWindowRegion)| vtkInteractorStyleRubberBand2D |Select a region of a window.
 [StreamLines](/Cxx/Visualization/StreamLines) | vtkStreamTracer | Streamlines.
+[StreamlinesWithLineWidget](/Cxx/VisualizationAlgorithms/StreamlinesWithLineWidget)| vtkCallbackCommand vtkLineWidget | Using the vtkLineWidget to produce streamlines in the combustor dataset.  The StartInteractionEvent turns the visibility of the streamlines on; the InteractionEvent causes the streamlines to regenerate themselves.
 [TensorAxes](/Cxx/VisualizationAlgorithms/TensorAxes)| vtkPointLoad vtkTensorGlyph | Display the scaled and oriented principal axes of the stress tensor.
 [TensorEllipsoids](/Cxx/VisualizationAlgorithms/TensorEllipsoids)| vtkPointLoad vtkTensorGlyph | Display the scaled and oriented principal axes as tensor ellipsoids representing the stress tensor.
 [TensorGlyph](/Cxx/Visualization/TensorGlyph)| vtkTensorGlyph | Draw a rotated/scaled glyph at each point.
diff --git a/src/Cxx/VisualizationAlgorithms/CMakeLists.txt b/src/Cxx/VisualizationAlgorithms/CMakeLists.txt
index 86acab87a2f14bc9cb84b804607916c8cac0a92e..00bbafa97de3b95a414ba099f388ae8dc3ec3c08 100644
--- a/src/Cxx/VisualizationAlgorithms/CMakeLists.txt
+++ b/src/Cxx/VisualizationAlgorithms/CMakeLists.txt
@@ -47,6 +47,7 @@ set(NEEDS_ARGS
   OfficeTube
   SpikeFran
   SplatFace
+  StreamlinesWithLineWidget
   VelocityProfile
   WarpCombustor
 )
@@ -130,6 +131,9 @@ add_test(${KIT}-SpikeFran ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
 add_test(${KIT}-SplatFace ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
   TestSplatFace ${DATA}/fran_cut.vtk -E 50)
 
+add_test(${KIT}-StreamlinesWithLineWidget ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
+  TestStreamlinesWithLineWidget ${DATA}/combxyz.bin ${DATA}/combq.bin 10 1)
+
 add_test(${KIT}-VelocityProfile ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
   TestVelocityProfile ${DATA}/combxyz.bin ${DATA}/combq.bin)
 
diff --git a/src/Cxx/VisualizationAlgorithms/StreamlinesWithLineWidget.cxx b/src/Cxx/VisualizationAlgorithms/StreamlinesWithLineWidget.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2560cf295b58188f4b174dc40a71550e43e05d38
--- /dev/null
+++ b/src/Cxx/VisualizationAlgorithms/StreamlinesWithLineWidget.cxx
@@ -0,0 +1,286 @@
+/*
+Modified from VTK/Examples/GUI/Python/StreamlinesWithLineWidget.py.
+This program encompasses the functionality of
+StreamlinesWithLineWidget.tcl and LineWidget.tcl.
+
+        Produce streamlines in the combustor dataset.
+
+This example demonstrates how to use the vtkLineWidget to seed and
+manipulate streamlines. Two line widgets are created. The first is invoked
+by pressing 'i', the second by pressing 'L' (capital). Both can exist
+together.
+
+If the fourth parameter is non-zero:
+ 1) The third parameter value is changed to 25.
+ 2) The camera position and first line widget are positioned differently.
+ 3) The streamlines are displayed running from the first line widget.
+ 4) The second line widget is still available.
+This is used to test the code.
+
+*/
+
+#include <vtkActor.h>
+#include <vtkCallbackCommand.h>
+#include <vtkCamera.h>
+#include <vtkLineWidget.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMultiBlockPLOT3DReader.h>
+#include <vtkNamedColors.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkProperty.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkRenderer.h>
+#include <vtkRibbonFilter.h>
+#include <vtkRungeKutta4.h>
+#include <vtkSmartPointer.h>
+#include <vtkStreamTracer.h>
+#include <vtkStructuredGrid.h>
+#include <vtkStructuredGridOutlineFilter.h>
+
+namespace
+{
+
+class EnableActorCallback : public vtkCommand
+{
+public:
+  static EnableActorCallback* New() { return new EnableActorCallback; }
+  void Execute(vtkObject* /*caller*/, unsigned long, void*) override
+  {
+    this->actor->VisibilityOn();
+  }
+  EnableActorCallback()
+    : actor(nullptr)
+  {
+  }
+  vtkActor* actor;
+};
+
+// The Line Widget callback.
+class LWCallback : public vtkCommand
+{
+public:
+  static LWCallback* New() { return new LWCallback; }
+  void Execute(vtkObject* caller, unsigned long, void*) override
+  {
+    vtkLineWidget* lineWidget = reinterpret_cast<vtkLineWidget*>(caller);
+    lineWidget->GetPolyData(this->polyData);
+    this->renWin->Render();
+  }
+  LWCallback()
+    : polyData(nullptr)
+    , renWin(nullptr)
+  {
+  }
+  vtkPolyData* polyData;
+  vtkRenderWindow* renWin;
+};
+}
+
+int main(int argc, char* argv[])
+{
+  if (argc < 3)
+  {
+    std::cout << "Usage: " << argv[0]
+              << " filename1 filename2 [numOfStreamLines] [illustration]"
+              << std::endl;
+    std::cout << "where: filename1 is combxyz.bin and filename2 is combq.bin."
+              << std::endl;
+    std::cout
+      << "       numOfStreamLines is the number of streamlines, default 25"
+      << std::endl;
+    std::cout << "       illustration, if non-zero, reproduce Fig 7-39 of the "
+                 "VTK Textbook."
+              << std::endl;
+    return EXIT_FAILURE;
+  }
+  auto numOfStreamLines = 25;
+  auto illustration = 0;
+  std::string fileName1 = argv[1];
+  std::string fileName2 = argv[2];
+  if (argc > 3)
+  {
+    numOfStreamLines = atoi(argv[3]);
+  }
+  if (argc > 4)
+  {
+    illustration = atoi(argv[4]);
+    numOfStreamLines = 25;
+  }
+
+  vtkSmartPointer<vtkNamedColors> colors =
+    vtkSmartPointer<vtkNamedColors>::New();
+
+  // Start by loading some data.
+  vtkSmartPointer<vtkMultiBlockPLOT3DReader> pl3d =
+    vtkSmartPointer<vtkMultiBlockPLOT3DReader>::New();
+  pl3d->SetXYZFileName(fileName1.c_str());
+  pl3d->SetQFileName(fileName2.c_str());
+  pl3d->SetScalarFunctionNumber(100); // Density
+  pl3d->SetVectorFunctionNumber(202); // Momentum
+  pl3d->Update();
+
+  vtkStructuredGrid* pl3d_output =
+    vtkStructuredGrid::SafeDownCast(pl3d->GetOutput()->GetBlock(0));
+
+  // Create the Renderer, RenderWindow and RenderWindowInteractor.
+  vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
+  vtkSmartPointer<vtkRenderWindow> renWin =
+    vtkSmartPointer<vtkRenderWindow>::New();
+  renWin->AddRenderer(ren);
+  vtkSmartPointer<vtkRenderWindowInteractor> iren =
+    vtkSmartPointer<vtkRenderWindowInteractor>::New();
+  iren->SetRenderWindow(renWin);
+
+  // Needed by: vtkStreamTracer and vtkLineWidget.
+  vtkSmartPointer<vtkPolyData> seeds = vtkSmartPointer<vtkPolyData>::New();
+  vtkSmartPointer<vtkActor> streamline = vtkSmartPointer<vtkActor>::New();
+  vtkSmartPointer<vtkPolyData> seeds2 = vtkSmartPointer<vtkPolyData>::New();
+  vtkSmartPointer<vtkActor> streamline2 = vtkSmartPointer<vtkActor>::New();
+
+  // The line widget is used seed the streamlines.
+  vtkSmartPointer<vtkLineWidget> lineWidget =
+    vtkSmartPointer<vtkLineWidget>::New();
+  lineWidget->SetResolution(numOfStreamLines);
+  lineWidget->SetInputData(pl3d_output);
+  lineWidget->GetPolyData(seeds);
+  if (illustration != 0)
+  {
+    lineWidget->SetAlignToNone();
+    lineWidget->SetPoint1(0.974678, 5.073630, 31.217961);
+    lineWidget->SetPoint2(0.457544, -4.995921, 31.080175);
+  }
+  else
+  {
+    lineWidget->SetAlignToYAxis();
+  }
+  lineWidget->ClampToBoundsOn();
+  lineWidget->PlaceWidget();
+
+  lineWidget->SetInteractor(iren);
+
+  // Associate the line widget with the interactor and setup the callbacks.
+  vtkSmartPointer<LWCallback> GenerateStreamlines =
+    vtkSmartPointer<LWCallback>::New();
+  GenerateStreamlines->polyData = seeds;
+  GenerateStreamlines->renWin = renWin;
+  vtkSmartPointer<EnableActorCallback> BeginInteraction =
+    vtkSmartPointer<EnableActorCallback>::New();
+  BeginInteraction->actor = streamline;
+  lineWidget->AddObserver(vtkCommand::StartInteractionEvent, BeginInteraction);
+  lineWidget->AddObserver(vtkCommand::InteractionEvent, GenerateStreamlines);
+
+  // The second line widget is used seed more streamlines.
+  vtkSmartPointer<vtkLineWidget> lineWidget2 =
+    vtkSmartPointer<vtkLineWidget>::New();
+  lineWidget2->SetResolution(numOfStreamLines);
+  lineWidget2->SetInputData(pl3d_output);
+  lineWidget2->GetPolyData(seeds2);
+  lineWidget2->SetKeyPressActivationValue('L');
+  lineWidget2->SetAlignToZAxis();
+  lineWidget->ClampToBoundsOn();
+  lineWidget2->PlaceWidget();
+
+  lineWidget2->SetInteractor(iren);
+
+  // Associate the line widget with the interactor and setup the callbacks.
+  vtkSmartPointer<LWCallback> GenerateStreamlines2 =
+    vtkSmartPointer<LWCallback>::New();
+  GenerateStreamlines2->polyData = seeds2;
+  GenerateStreamlines2->renWin = renWin;
+  vtkSmartPointer<EnableActorCallback> BeginInteraction2 =
+    vtkSmartPointer<EnableActorCallback>::New();
+  BeginInteraction2->actor = streamline2;
+  lineWidget2->AddObserver(vtkCommand::StartInteractionEvent,
+                           BeginInteraction2);
+  lineWidget2->AddObserver(vtkCommand::InteractionEvent, GenerateStreamlines2);
+
+  // Here we set up two streamlines.
+  vtkSmartPointer<vtkRungeKutta4> rk4 = vtkSmartPointer<vtkRungeKutta4>::New();
+  vtkSmartPointer<vtkStreamTracer> streamer =
+    vtkSmartPointer<vtkStreamTracer>::New();
+  streamer->SetInputData(pl3d_output);
+  streamer->SetSourceData(seeds);
+  streamer->SetMaximumPropagation(100);
+  streamer->SetInitialIntegrationStep(0.2);
+  streamer->SetIntegrationDirectionToForward();
+  streamer->SetComputeVorticity(1);
+  streamer->SetIntegrator(rk4);
+  vtkSmartPointer<vtkRibbonFilter> rf = vtkSmartPointer<vtkRibbonFilter>::New();
+  rf->SetInputConnection(streamer->GetOutputPort());
+  rf->SetWidth(0.1);
+  rf->SetWidthFactor(5);
+  vtkSmartPointer<vtkPolyDataMapper> streamMapper =
+    vtkSmartPointer<vtkPolyDataMapper>::New();
+  streamMapper->SetInputConnection(rf->GetOutputPort());
+  streamMapper->SetScalarRange(pl3d_output->GetScalarRange());
+  streamline->SetMapper(streamMapper);
+  streamline->VisibilityOff();
+
+  vtkSmartPointer<vtkStreamTracer> streamer2 =
+    vtkSmartPointer<vtkStreamTracer>::New();
+  streamer2->SetInputData(pl3d_output);
+  streamer2->SetSourceData(seeds2);
+  streamer2->SetMaximumPropagation(100);
+  streamer2->SetInitialIntegrationStep(0.2);
+  streamer2->SetIntegrationDirectionToForward();
+  streamer2->SetComputeVorticity(1);
+  streamer2->SetIntegrator(rk4);
+  vtkSmartPointer<vtkRibbonFilter> rf2 =
+    vtkSmartPointer<vtkRibbonFilter>::New();
+  rf2->SetInputConnection(streamer2->GetOutputPort());
+  rf2->SetWidth(0.1);
+  rf2->SetWidthFactor(5);
+  vtkSmartPointer<vtkPolyDataMapper> streamMapper2 =
+    vtkSmartPointer<vtkPolyDataMapper>::New();
+  streamMapper2->SetInputConnection(rf2->GetOutputPort());
+  streamMapper2->SetScalarRange(pl3d_output->GetScalarRange());
+  streamline2->SetMapper(streamMapper2);
+  streamline2->VisibilityOff();
+
+  // Get an outline of the data set for context.
+  vtkSmartPointer<vtkStructuredGridOutlineFilter> outline =
+    vtkSmartPointer<vtkStructuredGridOutlineFilter>::New();
+  outline->SetInputData(pl3d_output);
+  vtkSmartPointer<vtkPolyDataMapper> outlineMapper =
+    vtkSmartPointer<vtkPolyDataMapper>::New();
+  outlineMapper->SetInputConnection(outline->GetOutputPort());
+  vtkSmartPointer<vtkActor> outlineActor = vtkSmartPointer<vtkActor>::New();
+  outlineActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData());
+  outlineActor->SetMapper(outlineMapper);
+
+  // Add the actors to the renderer, set the background and size.
+  ren->AddActor(outlineActor);
+  ren->AddActor(streamline);
+  ren->AddActor(streamline2);
+  renWin->SetSize(512, 512);
+  vtkCamera* cam = ren->GetActiveCamera();
+  if (illustration != 0)
+  {
+    // We need to directly display the streamlines in this case.
+    lineWidget->EnabledOn();
+    streamline->VisibilityOn();
+    lineWidget->GetPolyData(seeds);
+    renWin->Render();
+
+    cam->SetClippingRange(14.216207, 68.382915);
+    cam->SetFocalPoint(9.718210, 0.458166, 29.399900);
+    cam->SetPosition(-15.827551, -16.997463, 54.003120);
+    cam->SetViewUp(0.616076, 0.179428, 0.766979);
+    ren->SetBackground(colors->GetColor3d("Silver").GetData());
+  }
+  else
+  {
+    cam->SetClippingRange(3.95297, 50);
+    cam->SetFocalPoint(9.71821, 0.458166, 29.3999);
+    cam->SetPosition(2.7439, -37.3196, 38.7167);
+    cam->SetViewUp(-0.16123, 0.264271, 0.950876);
+    ren->SetBackground(colors->GetColor3d("Silver").GetData());
+  }
+
+  iren->Initialize();
+  renWin->Render();
+  iren->Start();
+  return EXIT_SUCCESS;
+}
diff --git a/src/Cxx/VisualizationAlgorithms/StreamlinesWithLineWidget.md b/src/Cxx/VisualizationAlgorithms/StreamlinesWithLineWidget.md
new file mode 100644
index 0000000000000000000000000000000000000000..54936e6e1db1f338c917e7765f16a3bef0fb1b08
--- /dev/null
+++ b/src/Cxx/VisualizationAlgorithms/StreamlinesWithLineWidget.md
@@ -0,0 +1,17 @@
+### Description
+#### Produce streamlines in the combustor dataset.
+
+This example demonstrates how to use the vtkLineWidget to seed and
+manipulate streamlines. Two line widgets are created. The first is invoked
+by pressing '**i**', the second by pressing '**L**' (capital). Both can exist
+together.
+
+If the fourth parameter is non-zero, it is used to generate an image with streamlines:
+ 1) The third parameter value is changed to 25.
+ 2) The camera position and first line widget are positioned differently.
+ 3) The streamlines are displayed running from the first line widget.
+ 4) The second line widget is still available.
+ 
+In the C++ version, note how we handle callbacks by first implementing a class, then instantiating it and then passing references to the needed variables to it. Finally we add it as an observer.
+
+For the Python version the process is slightly different. We simply define a function with references to the needed variables from the outer scope (or they could be global). Finally add it as an observer.
diff --git a/src/Python.md b/src/Python.md
index 20ed2ef921d04cf98c0db431486f3d025dacaff7..b8981a6bd9b313ab5f2433d7d1e57188da06b5d7 100644
--- a/src/Python.md
+++ b/src/Python.md
@@ -199,6 +199,7 @@ This section includes examples of manipulating meshes.
 [QuadraticSurface](/Python/Visualization/QuadraticSurface) | vtkQuadric |
 [SphereTexture](/Python/Visualization/SphereTexture) | vtkTextureMapToSphere | Apply an ImageData texture to an sphere
 [Streamlines](/Python/Visualization/Streamlines) | vtkStreamLine | Seed streamlines with vectors from a structured grid
+[StreamlinesWithLineWidget](/Python/VisualizationAlgorithms/StreamlinesWithLineWidget)| vtkCallbackCommand vtkLineWidget | Using the vtkLineWidget to produce streamlines in the combustor dataset.  The StartInteractionEvent turns the visibility of the streamlines on; the InteractionEvent causes the streamlines to regenerate themselves.
 [TensorAxes](/Python/VisualizationAlgorithms/TensorAxes)| vtkPointLoad vtkTensorGlyph | Display the scaled and oriented principal axes of the stress tensor.
 [TensorEllipsoids](/Python/VisualizationAlgorithms/TensorEllipsoids)| vtkPointLoad vtkTensorGlyph | Display the scaled and oriented principal axes as tensor ellipsoids representing the stress tensor.
 [TextSource](/Python/Visualization/TextSource) | vtkTextSource |
diff --git a/src/Python/VisualizationAlgorithms/StreamlinesWithLineWidget.md b/src/Python/VisualizationAlgorithms/StreamlinesWithLineWidget.md
new file mode 100644
index 0000000000000000000000000000000000000000..54936e6e1db1f338c917e7765f16a3bef0fb1b08
--- /dev/null
+++ b/src/Python/VisualizationAlgorithms/StreamlinesWithLineWidget.md
@@ -0,0 +1,17 @@
+### Description
+#### Produce streamlines in the combustor dataset.
+
+This example demonstrates how to use the vtkLineWidget to seed and
+manipulate streamlines. Two line widgets are created. The first is invoked
+by pressing '**i**', the second by pressing '**L**' (capital). Both can exist
+together.
+
+If the fourth parameter is non-zero, it is used to generate an image with streamlines:
+ 1) The third parameter value is changed to 25.
+ 2) The camera position and first line widget are positioned differently.
+ 3) The streamlines are displayed running from the first line widget.
+ 4) The second line widget is still available.
+ 
+In the C++ version, note how we handle callbacks by first implementing a class, then instantiating it and then passing references to the needed variables to it. Finally we add it as an observer.
+
+For the Python version the process is slightly different. We simply define a function with references to the needed variables from the outer scope (or they could be global). Finally add it as an observer.
diff --git a/src/Python/VisualizationAlgorithms/StreamlinesWithLineWidget.py b/src/Python/VisualizationAlgorithms/StreamlinesWithLineWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..4f21a0f3757cb2d42c669e6ecefc620f89586cce
--- /dev/null
+++ b/src/Python/VisualizationAlgorithms/StreamlinesWithLineWidget.py
@@ -0,0 +1,202 @@
+#!/usr/bin/env python
+
+"""
+Modified from VTK/Examples/GUI/Python/StreamlinesWithLineWidget.py.
+This program encompasses the functionality of
+  StreamlinesWithLineWidget.tcl and LineWidget.tcl.
+"""
+
+import vtk
+
+
+def main():
+    colors = vtk.vtkNamedColors()
+
+    fileName1, fileName2, numOfStreamLines, illustration = get_program_parameters()
+    if illustration:
+        numOfStreamLines = 25
+
+    # Start by loading some data.
+    pl3d = vtk.vtkMultiBlockPLOT3DReader()
+    pl3d.SetXYZFileName(fileName1)
+    pl3d.SetQFileName(fileName2)
+    pl3d.SetScalarFunctionNumber(100)  # Density
+    pl3d.SetVectorFunctionNumber(202)  # Momentum
+    pl3d.Update()
+
+    pl3d_output = pl3d.GetOutput().GetBlock(0)
+
+    # Create the Renderer, RenderWindow and RenderWindowInteractor.
+    ren = vtk.vtkRenderer()
+    renWin = vtk.vtkRenderWindow()
+    renWin.AddRenderer(ren)
+    iren = vtk.vtkRenderWindowInteractor()
+    iren.SetRenderWindow(renWin)
+
+    # Needed by: vtkStreamTracer and vtkLineWidget.
+    seeds = vtk.vtkPolyData()
+    streamline = vtk.vtkActor()
+    seeds2 = vtk.vtkPolyData()
+    streamline2 = vtk.vtkActor()
+
+    # The line widget is used seed the streamlines.
+    lineWidget = vtk.vtkLineWidget()
+    lineWidget.SetResolution(numOfStreamLines)
+    lineWidget.SetInputData(pl3d_output)
+    lineWidget.GetPolyData(seeds)
+    if illustration:
+        lineWidget.SetAlignToNone()
+        lineWidget.SetPoint1(0.974678, 5.073630, 31.217961)
+        lineWidget.SetPoint2(0.457544, -4.995921, 31.080175)
+    else:
+        lineWidget.SetAlignToYAxis()
+    lineWidget.ClampToBoundsOn()
+    lineWidget.PlaceWidget()
+
+    # Callback functions that actually generate streamlines.
+    def EnableActorCallback(obj, event):
+        # global streamline
+        streamline.VisibilityOn()
+
+    def GenerateStreamlinesCallback(obj, event):
+        # global seeds, renWin
+        obj.GetPolyData(seeds)
+        renWin.Render()
+
+    # Associate the line widget with the interactor and setup callbacks.
+    lineWidget.SetInteractor(iren)
+    lineWidget.AddObserver("StartInteractionEvent", EnableActorCallback)
+    lineWidget.AddObserver("InteractionEvent", GenerateStreamlinesCallback)
+
+    # The second line widget is used seed more streamlines.
+    lineWidget2 = vtk.vtkLineWidget()
+    lineWidget2.SetResolution(numOfStreamLines)
+    lineWidget2.SetInputData(pl3d_output)
+    lineWidget2.GetPolyData(seeds2)
+    lineWidget2.SetKeyPressActivationValue('L')
+    lineWidget2.SetAlignToZAxis()
+    lineWidget.ClampToBoundsOn()
+    lineWidget2.PlaceWidget()
+
+    def EnableActorCallback2(obj, event):
+        # global streamline2
+        streamline2.VisibilityOn()
+
+    def GenerateStreamlinesCallback2(obj, event):
+        # global seeds2, renWin
+        obj.GetPolyData(seeds2)
+        renWin.Render()
+
+    lineWidget2.SetInteractor(iren)
+    lineWidget2.AddObserver("StartInteractionEvent", EnableActorCallback2)
+    lineWidget2.AddObserver("EndInteractionEvent", GenerateStreamlinesCallback2)
+
+    # Here we set up two streamlines.
+    rk4 = vtk.vtkRungeKutta4()
+    streamer = vtk.vtkStreamTracer()
+    streamer.SetInputData(pl3d_output)
+    streamer.SetSourceData(seeds)
+    streamer.SetMaximumPropagation(100)
+    streamer.SetInitialIntegrationStep(0.2)
+    streamer.SetIntegrationDirectionToForward()
+    streamer.SetComputeVorticity(1)
+    streamer.SetIntegrator(rk4)
+    rf = vtk.vtkRibbonFilter()
+    rf.SetInputConnection(streamer.GetOutputPort())
+    rf.SetWidth(0.1)
+    rf.SetWidthFactor(5)
+    streamMapper = vtk.vtkPolyDataMapper()
+    streamMapper.SetInputConnection(rf.GetOutputPort())
+    streamMapper.SetScalarRange(pl3d_output.GetScalarRange())
+    streamline.SetMapper(streamMapper)
+    streamline.VisibilityOff()
+
+    streamer2 = vtk.vtkStreamTracer()
+    streamer2.SetInputData(pl3d_output)
+    streamer2.SetSourceData(seeds2)
+    streamer2.SetMaximumPropagation(100)
+    streamer2.SetInitialIntegrationStep(0.2)
+    streamer2.SetIntegrationDirectionToForward()
+    streamer2.SetComputeVorticity(1)
+    streamer2.SetIntegrator(rk4)
+    rf2 = vtk.vtkRibbonFilter()
+    rf2.SetInputConnection(streamer2.GetOutputPort())
+    rf2.SetWidth(0.1)
+    rf2.SetWidthFactor(5)
+    streamMapper2 = vtk.vtkPolyDataMapper()
+    streamMapper2.SetInputConnection(rf2.GetOutputPort())
+    streamMapper2.SetScalarRange(pl3d_output.GetScalarRange())
+    streamline2.SetMapper(streamMapper2)
+    streamline2.VisibilityOff()
+
+    # Get an outline of the data set for context.
+    outline = vtk.vtkStructuredGridOutlineFilter()
+    outline.SetInputData(pl3d_output)
+    outlineMapper = vtk.vtkPolyDataMapper()
+    outlineMapper.SetInputConnection(outline.GetOutputPort())
+    outlineActor = vtk.vtkActor()
+    outlineActor.GetProperty().SetColor(colors.GetColor3d("Black"))
+    outlineActor.SetMapper(outlineMapper)
+
+    # Add the actors to the renderer, set the background and size.
+    ren.AddActor(outlineActor)
+    ren.AddActor(streamline)
+    ren.AddActor(streamline2)
+    renWin.SetSize(512, 512)
+    cam = ren.GetActiveCamera()
+    if illustration:
+        # We need to directly display the streamlines in this case.
+        lineWidget.EnabledOn()
+        streamline.VisibilityOn()
+        lineWidget.GetPolyData(seeds)
+        renWin.Render()
+
+        cam.SetClippingRange(14.216207, 68.382915)
+        cam.SetFocalPoint(9.718210, 0.458166, 29.399900)
+        cam.SetPosition(-15.827551, -16.997463, 54.003120)
+        cam.SetViewUp(0.616076, 0.179428, 0.766979)
+        ren.SetBackground(colors.GetColor3d("Silver"))
+    else:
+        cam.SetClippingRange(3.95297, 50)
+        cam.SetFocalPoint(9.71821, 0.458166, 29.3999)
+        cam.SetPosition(2.7439, -37.3196, 38.7167)
+        cam.SetViewUp(-0.16123, 0.264271, 0.950876)
+        ren.SetBackground(colors.GetColor3d("Silver"))
+
+    iren.Initialize()
+    renWin.Render()
+    iren.Start()
+
+
+def get_program_parameters():
+    import argparse
+    description = 'Produce streamlines in the combustor dataset.'
+    epilogue = '''
+        Produce streamlines in the combustor dataset.
+
+This example demonstrates how to use the vtkLineWidget to seed and
+manipulate streamlines. Two line widgets are created. The first is invoked
+by pressing 'i', the second by pressing 'L' (capital). Both can exist
+together.
+
+If the fourth parameter is non-zero, it is used to generate
+ an image with streamlines:
+ 1) The third parameter value is changed to 25.
+ 2) The camera position and first line widget are positioned differently.
+ 3) The streamlines are displayed running from the first line widget.
+ 4) The second line widget is still available.
+
+   '''
+    parser = argparse.ArgumentParser(description=description, epilog=epilogue,
+                                     formatter_class=argparse.RawDescriptionHelpFormatter)
+    parser.add_argument('filename1', help='combxyz.bin.')
+    parser.add_argument('filename2', help='combq.bin.')
+    parser.add_argument('numOfStreamLines', default=25, type=int, nargs='?', help='The number of stream lines.')
+    parser.add_argument('illustration', default=0, type=int, nargs='?',
+                        help='If non-zero, reproduce Fig 7-39 of the VTK Textbook.')
+    args = parser.parse_args()
+    return args.filename1, args.filename2, args.numOfStreamLines, args.illustration
+
+
+if __name__ == '__main__':
+    main()