Quantcast
Channel: The Kitware Blog
Viewing all 14 articles
Browse latest View live

matplotlib View coming in ParaView 4.1

$
0
0

matplotlib is a Python module that can be used to make publication-quality plots. We have recently integrated matplotlib into ParaView as a new type of view called a "Python View". This new view will be available in the ParaView 4.1 release. Below is a screenshot of the new Python View (right) next to a 3D rendering (left) of the momentum vector glyphs in the bluntfin.vts example dataset. The top subplot in the Python View is a matplotlib scatterplot of momentum magnitude versus density. The bottom subplot is a matplotlib histogram of the same density data.

The Python View has a single property, a Python script that contains the matplotlib rendering commands. All the Python bindings for ParaView and VTK that are available in the Python scripting module are available from within the script, making it possible to plot any array from just about any dataset that can be loaded into ParaView.

The view requires that the Python script where the plotting occurs define two functions. In the first function, you request which arrays you would like to transfer to the client for rendering (at present, all rendering in this view takes place on the client, even in client-server mode). These arrays can be point data, cell data, field data, and table row data. This function runs only on data server processes. It provides access to the underlying data object on the server so that you can query any aspect of the data using the Python-wrapped parts of VTK and ParaView.

The second function is where you put matplotlib rendering commands. This function runs only on the ParaView client. It has access to the complete data object gathered from the data server nodes, but only the arrays requested in the first function. This component will typically set up one or more matplotlib subplots, convert data from VTK to a form that can be passed to matplotlib, and plot the data.

Selecting data arrays to plot

Because a dataset residing on the ParaView server may be large, transferring all the data to the client may not be possible or practical. For that reason, we have provided a mechanism to select which data arrays to transfer to the client. The overall structure of the data object, however, including cell connectivity, point positions, and hierarchical block structure, is always transferred to the client.

The Python script for the view must define a function called setup_data(view). The "view" argument is the VTK object for the Python View. Through the view object, the current datasets loaded into ParaView may be accessed.

Here's an example of this function that was used to generate the image above:

defsetup_data(view):# Iterate over visible data objectsfor i inxrange(view.GetNumberOfVisibleDataObjects()):# You need to use GetVisibleDataObjectForSetup(i) in setup_data to access the data object.
    dataObject = view.GetVisibleDataObjectForSetup(i)# The data object has the same data type and structure as the data object that# sits on the server. You can query the size of the data, for instance, or do anything# else you can do through the Python wrapping.print"Memory size:", dataObject.GetActualMemorySize(), "kilobytes"# Clean up from previous calls here. We want to unset any of the arrays requested# in previous calls to this function.
    view.DisableAllAttributeArrays()# By default, no arrays will be passed to the client. You need to explicitly request# the arrays you want. Here, we'll request the Density point data array
    view.SetAttributeArrayStatus(i, vtkDataObject.POINT, "Density", 1)
    view.SetAttributeArrayStatus(i, vtkDataObject.POINT, "Momentum", 1)# Other attribute arrays can be set similarly
    view.SetAttributeArrayStatus(i, vtkDataObject.FIELD, "fieldData", 1)

The vtkPythonView class passed in as the "view" argument to setup_data(view) defines several methods useful for specifying which data arrays to copy:

  • GetNumberOfVisibleDataObjects() - Returns the number of visible data objects in the view. If an object is not visible, it should not show up in the rendering, so all the methods provided by the view deal only with visible objects.
  • GetVisibleDataObjectForSetup(visibleObjectIndex) - This returns the visibleObjectIndex-th visible data object in the view (the data object will have an open eye next to it in the pipeline browser).
  • GetNumberOfAttributeArrays(visibleObjectIndex, attributeType) - Returns the number of attribute arrays for the visibleObjectIndex-th visible object and the given attribute type (e.g., vtkDataObject.POINT, vtkDataObject.CELL, etc.).
  • GetAttributeArrayName(visibleObjectIndex, attributeType, arrayIndex) - Returns the name of the array of the given attribute type at the given array index for the visibleObjectIndex-th object.
  • SetAttributeArrayStatus(visibleObjectIndex, vtkDataObject.POINT, "Density", 1) - Sets the array status of an attribute array. The first argument is the visible object index, the second object is the attribute association of the array, the third argument is the name of the array, and the last argument specifies if the array is to be copied (1) or not (0).
  • GetAttributeArrayStatus(visibleObjectIndex, vtkDataObject.POINT, "Density") - Retrieves the array status for the object with the given visible index with a given attribute association (second argument) and name (last argument).
  • DisableAllAttributeArrays() - Set all arrays to not be copied.
The methods GetNumberOfVisibleDataObjects(), GetVisibleDataObjectForSetup(...), GetNumberOfAttributeArrays(...), and GetAttributeArrayName(...) are all convenience methods for obtaining information about visible data objects in the view. The latter three methods are valid only from within the setup_data(view) function. You could instead iterate over all the representations in the vtkPythonView, check for the representation's visibility, and query the data from the representation directly, but the convenience methods make this somewhat less cumbersome. No matter how you choose to query the available data, you must mark which arrays to copy with SetAttributeArrayStatus(...).
 
Plotting with matplotlib

After the setup_data(view) function has been called, ParaView will transfer the data object and selected arrays to the client. When that is done, it will call the render(view, figure) function you have defined in your script.

The "view" argument to the render(view, figure) function is the vtkPythonView object on the client. The "figure" argument is a matplotlib FigureCanvasAgg object that is automatically created by vtkPythonView. This figure object is the hook into the matplotlib library.

The methods in the vtkPythonView class that are useful within the render function are:

  • GetNumberOfVisibleDataObjects() - Returns the number of visible data objects in the view.
  • GetVisibleDataObjectForRendering(visibleObjectIndex) - Returns the dataset that has been transferred to the client with the selected arrays.
Here is an example of the render(view, figure) function used to generate the figure above:
 
defrender(view, figure):# Set the border color of the figure
  figure.set_facecolor('white')# Set up a new subplot within the given figure
  ax1 = figure.add_subplot(2,1,1)
  ax1.minorticks_on()
  ax1.set_title('Momentum magnitude vs. density')
  ax1.set_xlabel('Density')
  ax1.set_ylabel('Momentum magnitude')

  ax2 = figure.add_subplot(2,1,2)
  ax2.set_title('Density histogram')# Iterate over visible data objectsfor i inxrange(view.GetNumberOfVisibleDataObjects()):# You need to use GetVisibleDataObjectForRendering(i) in this function because# it returns the copy of the data on the client, and this function runs only on the client.
    dataObject = view.GetVisibleDataObjectForRendering(i)# Now plot a 2D histogram of momentum magnitude vs. density
    density = dataObject.GetPointData().GetArray("Density")
    npDensity = ns.vtk_to_numpy(density)

    momentum = dataObject.GetPointData().GetArray("Momentum")
    npMomentum = ns.vtk_to_numpy(momentum)
    npMomentumAbs = sqrt(npMomentum[:,0]**2+ npMomentum[:,1]**2+ npMomentum[:,2]**2)
    ax1.scatter(npDensity, npMomentumAbs)
    ax2.hist(npDensity,bins=30)

One of the first steps in this render function involves obtaining a matplotlib Axes object as a subplot in the figure. The Axes object provides many of the actual plotting commands in matplotlib. For a complete set of plot types available, please see the Axes documentation.

Enabling Python View in ParaView

To enable the Python View in ParaView, configure ParaView in CMake with the PARAVIEW_ENABLE_PYTHON and PARAVIEW_ENABLE_MATPLOTLIB options set to ON. You will also need to have matplotlib installed on your system.

Limitations

The pre-built ParaView binaries include matplotlib 1.1. Some features available in newer versions will not be available if you are using the these binaries.

For multiblock datasets, the methods GetNumberOfAttributeArrays(...) and GetAttributeArrayName(...) should not be used. Instead, you should query the individual blocks through the vtkMultiblockDataSet API to determine the available attribute array names. You can do this directly on the data object returned with GetVisibleDataObjectForSetup(...). You will still need to use SetAttributeArrayStatus(...) to select which arrays to copy; any block with an array with the type and name given in the SetAttributeArrayStatus(...) will have that array copied to the client. At this time, there is no per-block array selection mechanism available.

Plotting with matplotlib is not currently available for datasets stored as vtkImageData objects because there is limited support for distributing and reassembling these objects in parallel in ParaView. As a workaround, you can convert vtkImageData datasets into vtkUnstructuredGrids using the "Append Datasets" filter and plot the output with matplotlib.

Conclusion

ParaView now makes it possible to view plots made with matplotlib side-by-side with ParaView's existing view types in a single window. To try out matplotlib in ParaView yourself, you can get started by downloading the statefile attached to this post. To get the bluntfin.vts dataset, you will need the data you can download from the ParaView downloads page by selecting Data, Documentation, and Tutorials.


New in ParaView: Settings UI

$
0
0

One of the few things that has remained unchanged in the ParaView UI since 3.0 was released is the settings dialog: a dialog born from the days when serious applications needed to have lots of complicated settings. Not any more! Soon to land in ParaView's development repository is a brand new way to set application preferences.

 

Figure 1: Settings/Preferences dialog in ParaView.

Figure 2: Use Search to find the option based on the text in description.

The dialog consists of searchable tabs that allow you to search for parameters by name or description as well as scan through available options for both basic and advanced users. If the pattern looks similar to the Properties panel or Color Map Editor panel, that's because the dialog indeed uses the same underpinnings as those with a minor twist to show descriptive text for parameters rather than a terse label.

The implementation provides flexibility, extensibility, as well as customizability for custom applications and plugins alike. Also site mainters can now deploy ParaView instances with default settings for their choice. More on that in a follow up post coming soon(ish).

New in ParaView: Specifying custom default values

$
0
0

Update: File names for user and site settings have been corrected.


In past versions, the ability to customize ParaView by changing default values for properties of sources, filters, views, and representations was somewhat limited:

  • Relatively few property defaults were modifiable
  • Customized property defaults could only be saved for the user login under which ParaView was run
  • Customized property defaults were not preserved across different installed versions of ParaView
  • Property defaults specified in the ParaView application were not available in other programs such as pvpython and pvbatch.

The upcoming release of ParaView remedies these shortcomings by adding a new way to specify arbitrary property defaults in ParaView. All the previously available property defaults (as well as other application settings) are still accessible through the Edit -> Settings menu item. However, even more defaults can be set by modifying a JSON configuration file.

Specifying custom defaults with JSON

Let's look at a concrete example of how to specify a property default that is not exposed in ParaView's settings dialog. Suppose you are not happy with the default tessellation of the Sphere Source in ParaView and would like to increase it to produce a smoother sphere. You can do this every time you create a Sphere Source, but that gets tiresome after a while. Instead, you can change the default tesselation values when the sphere source is created with a little JSON:

{
  "sources" : {
    "SphereSource" : {
      "ThetaResolution" : 32,
      "PhiResolution" : 32
    }
  }
}

This is a simple JSON file where the top level specifies the group of the object whose default you want to change -- in this case, the "sources" group. The second level ("SphereSource") specifies the name of the object. Finally, the third level ("ThetaResolution", "PhiResolution") names the setting whose default value you want to change. When ParaView creates a Sphere Source object, it consults these JSON settings for any default values that should be used in place of those embedded in the ParaView application.

On Windows 7, this file must be located under %APPDATA%\ParaView\ParaView-UserSettings.json where the APPDATA environment variable is usually something like C:\Users\USERNAME\AppData\Roaming. On Unix-like systems, it is located under ~/.config/ParaView/ParaView-UserSettings.json. This file will already exist if you have made any settings changes through the settings user interface in the ParaView application. It is absolutely okay and encouraged to modify this file in your favorite text editor to change settings not exposed in the GUI. Of course, making a backup copy of this file before you edit it is always a good idea.

You can also specify defaults for properties that are arrays of values. For example, to specify the default surface color of objects displayed with the Surface representation, you can write

{
  "representations" : {
    "GeometryRepresentation" : {
      "DiffuseColor" : [0, 0.65, 1.0]
    }
  }
}

With this JSON, all newly created objects in ParaView that have a Geometry Representation (i.e., polygonal geometry) will have a light blue color when the Coloring option is set to Solid Color and the Representation is set to Surface or Surface With Edges.

As another example, suppose you want the default background for 3D views to be a gradient from black to dark gray. You can specify this with

{
  "views" : {
    "RenderView" : {
      "Background" : [0.0, 0.0, 0.0],
      "Background2" : [0.3, 0.3, 0.3],
      "UseGradientBackground" : true
    }
  }
}

You can also change setting defaults for filters. For example, to change the Shrink Factor in the Shrink filter, you can write

{
  "filters" : {
    "ShrinkFilter" : {
      "ShrinkFactor" : 0.75
    }
  }
}

Putting these four examples together, our ParaView-UserSettings.json file will look like

{
  "sources" : {
    "SphereSource" : {
      "ThetaResolution" : 32,
      "PhiResolution" : 32
    }
  },
  "representations" : {
    "GeometryRepresentation" : {
      "DiffuseColor" : [0, 0.65, 1.0]
    }
  },
  "views" : {
    "RenderView" : {
      "Background" : [0.0, 0.0, 0.0],
      "Background2" : [0.3, 0.3, 0.3],
      "UseGradientBackground" : true
    },
  "filters" : {
    "ShrinkFilter" : {
      "ShrinkFactor" : 0.75
    }
  }
}

The names of groups and objects come from the XML proxy definition files in the ParaView source code in the directory ParaView/ParaViewCore/ServerManager/SMApplication/Resources. The group name is defined by the "name" attribute in a "ProxyGroup" element. The object name comes from the "name" attribute in the "Proxy" element (or elements of vtkSMProxy subclasses). We are considering how to make setting defaults simpler in a future version of ParaView.

Site-wide custom defaults

Site administrators can install site-wide custom defaults using another JSON file if that is desired. The JSON file must be named ParaView-SiteSettings.json and can be placed in the same directory as the ParaView executable, in a lib directory next to the the ParaView executable, or one directory level above the ParaView executable. ParaView will search these directories in that order, reading in the first ParaView-SiteSettings.json file it finds.

If the same default is specified in the ParaView-SiteSettings.json and ParaView-UserSettings.json file in a user's directory, the default specified in the ParaView-UserSettings.json file is used.

Keeping settings when installing new versions of ParaView

Unlike previous versions of ParaView, the ParaView-UserSettings.json and ParaView-SiteSettings.json files are not tied to any ParaView version, so installations of newer versions of ParaView will pick up these settings when you run them.

Using custom defaults in pvpython and pvbatch

Perhaps the most exciting aspect of the new defaults file is that settings are now available in other applications in the ParaView ecosystem, including pvpython and pvbatch. These applications read the same files in the same locations described in this post. This makes it possible to set up a visualization in the ParaView GUI application with some custom settings, then generate a full animation in pvpython or pvbatch with those same settings.

New in ParaView: Easy saving of custom defaults in ParaView

$
0
0

In a previous blog post, we described ParaView's new settings mechanism for specifying custom default property values for pipeline objects, representations, views, etc. This involved manually editing a text file with JSON and knowing or being able to look up some potentially obscure names associated with ParaView's filters, so it wasn't the most straightforward process.

Coming to ParaView 4.2 is a much easier way to specify custom default property values. The different sections in the Properties panel now have two additional buttons. These buttons are circled in red in the image below. The button with the disk icon is used to save the current property values as applied to the pipeline object, representation, or view. The button with the circular arrow (or reload icon) is used to restore any custom property values set in the object to ParaView's defaults. Once you save the current property values as defaults for a ParaView object (a pipeline object, representation, or view), those settings will be applied as the defaults for any new instance of that object. The saved defaults are written to the JSON file described in the linked blog post above so that they are available the next time you launch ParaView.

Let's look at an example. Say you want to change the default background color in the Render View. To do this, scroll down to the View section of the Properties panel and click on the combo box that shows the current background color. Select a new color, and click OK. Next, scroll up to the View section header (it should say "View (Render View)" and click on the disk button to the right of the header. This will save the new background color as the default for new views. To see this, click on the "+" sign next to the tab above the 3D view to create a new layout. Click on the "Render View" button. A new render view will be created with the custom background color you just saved as default.

You can undo your changes to the default background color by clicking on the circular arrow button. This will reset the current view properties to ParaView's application defaults. To fully restore ParaView's defaults, you need to click the disk button again. If you don't, the restored defaults will be applied only to the current object, and new instances of that object will have your custom defaults saved the last time you clicked the disk button. After saving the restored property values, create a new Render View. It should have ParaView's original default background color.

This feature works with much more than just the background color of the Render View. In fact, with a few exceptions, almost any object property's default value can be set using this mechanism.

ParaView: Python View is now more versatile

$
0
0

In ParaView 4.1, the Python View was capable of generating visualizations using matplotlib only. We recently made some changes to the Python View to make it possible to use just about any Python library to generate images displayed in the view. The only restriction on Python libraries that can be used for this purpose is that there must be a way to access pixel data from a plot generated by the library. Matplotlib plots are still fully supported in a backwards-compatible way, so no changes to existing Python View scripts are required to use the now more versatile Python View

In a previous blog post, we detailed using the Python View to plot data loaded into ParaView. At a high-level view, the Python View requires two functions to be defined in the Python script. One function, called setup_data(), is used to request data arrays in data objects that should be copied to the ParaView client. This step remains unchanged. The second function, called render() has a new signature that makes it more widely useful. That change is the subject of the rest of this post.

The new render() function signature

Previously, the render function had the signature

defrender(view, figure)

where view was the Python View object of type vtkPythonView calling this function and figure was a matplotlib.figure.Figure object that was set up by the view automatically. The function was not expected to return a value.

Now, the render function has the signature

defrender(view, width, height)

where view is still the vtkPythonView object and the width and height parameters are the width and height of the current render window in the view.

One of the most important changes to this function is that it is now expected to return a vtkImageData object containing the image content to display in the view render window. If no vtkImageData object is returned, the view window will be black.

Writing new Python View scripts that use matplotlib

No changes are necessary for Python View scripts used in ParaView 4.1 that define a render() function that takes a matplotlib.figure.Figure object as the second argument. However, for new matplotlib-based Python View scripts, we recommend using the new signature render(view, width, height).

If you want to use matplotlib for plotting while using the new signature for render(), your function needs to create a matplotlib.figure.Figure object internally to do the plotting. This can be done with some utility code in the python_view module.

fromparaviewimport python_view
figure = python_view.matplotlib_figure(width, height)

This figure object can be used in the same way as the figure argument in the previous signature of the render() function.

After matplotlib plotting commands have been added, the figure must be converted to a vtkImageData object. A convenience function has been added to the python_view module to do this. It is used as follows:

fromparaviewimport python_view
vtk_image = python_view.figure_to_image(figure)

The last step when using the new signature of the render() function is to return the vtkImageData:

return vtk_image

Pulling it all together, here is an example of a function with the new signature that generates a histogram of an array named 'X' associated with the point data in the first visible object in the pipeline browser:

defrender(view, width, height):fromparaviewimport python_view
  figure = python_view.matplotlib_figure(width, height)

  ax = figure.add_subplot(1,1,1)
  ax.minorticks_on()
  ax.set_title('Plot title')
  ax.set_xlabel('X label')
  ax.set_ylabel('Y label')# Process only the first visible object in the pipeline browser
  dataObject = view.GetVisibleDataObjectForRendering(0)

  x = dataObject.GetPointData().GetArray('X')# Convert VTK data array to numpy array for plottingfromparaview.numpy_supportimport vtk_to_numpy
  np_x = vtk_to_numpy(x)

  ax.hist(np_x, bins=10)return python_view.figure_to_image(figure)

 

Generating views with numpy

An example of a library that can be used to generate images to be displayed in the Python View is numpy. Images in numpy may be defined as 3D arrays (height, width, color components). The python_view module provides a convenience function to convert numpy arrays to vtkImageData objects. As an example, the render() function below generates a solid red image to display in the view.

defrender(view, width, height)
  import numpy
  cb = numpy.zeros((height, width, 4), dtype=numpy.uint8)
  cb[:,:,0] =255# Red channel
  cb[:,:,3] =255# Alpha channelfromparaview.python_viewimport numpy_to_imagereturn numpy_to_image(cb)

This is not a terribly interesting use of the Python View, but it illustrates a minimal example of using numpy to generate content for display in the view window.

Using other plotting libraries

A collection of Python libraries that could potentially be used in the Python View can be found here. Note that aside from matplotlib, the libraries listed on this page have not been tested with the Python View. We would love to hear if you use any of these libraries in the Python View.

ParaView technique: Curved and nicely spaced arrow glyphs

$
0
0

ParaView has a number of great filters for generating visualizations of 3D vector fields. This post describes a recipe I learned from Russell M Taylor II at UNC's Department of Computer Science. The recipe combines several of ParaView's filters to produce curved arrow glyphs that are laid end-to-end at a good density in the image, resulting in improved perception of the vector field. The technique is inspired by the 2D vector field visualizaton technique Turk and Banks presented in their Image-Guided Streamline Placement paper at SIGGRAPH 1996.

This recipe can be used to generate images like this:

Compared to the image below created with the standard Glyph filter, the curvedness of the glyphs and their end-to-end alignment in the image above makes it much easier to visually trace along the vector field.

To create images like this, follow this recipe:

  1. Load data with a vector field array. Let's assume the array is named Velocity.
  2. Add a Point Source from the Sources menu. Place the center of this source somewhere near the beginning of the vector field. Set the "Number of Points" to between 50-100. Adjust this number if the resulting image is overloaded with arrow glyphs.
  3. Create a Stream Tracer with Custom Source. Set the "Input" to the dataset you loaded in step 1 and the "Seed Source" to the Point Source created in step 2. Set the "Integration Step Unit" option to "Length".
  4. Attach a Contour filter to the Stream Tracer with Custom Source created in Step 3. Change the "Vectors" option to "Velocity" and the "Contour By" option to "IntegrationTime". Remove the existing value in the table under "Isosurfaces" and click on the insert range icon (below the minus sign). Change the number of "Steps" to somewhere between 50 and 100. Again, some tweaking might be needed to the exact number of steps to achieve the desired glyph density. This step gives you a set of points along the streamlines evenly spaced in integration time, which means points will be closer where the vector field magnitude is lower and less densely packed where the vector field magnitude is greater.
  5. Create another Stream Tracer with Custom Source with the "Input" set to the dataset loaded in Step 1 and the "Seed Source" set to the Contour filter. Change the "Vectors" option to "Velocity", the "Integration Direction" to "BACKWARD", and the "Integration Step Unit" to "Length".
  6. Attach a Tube filter to the Stream Tracer with Custom Source from Step 5.
  7. Attach a Clip filter to the Tube filter in Step 6. In this step, we'll clip the stream tubes by the "IntegrationTime" variable. Note that because the integration direction was backward, the "IntegrationTime" variable is non-positive. Change the "Clip Type" option to "Scalar", the "Scalars" array to "IntegrationTime" and the "Value" option to -0.2. If the resulting tube segments overlap and appear as a single tube, adjust the "Value" property to a smaller number. If the resulting tube segments are spaced too far away, increase the "Value" property.
  8. Finally, attach a Glyph filter to the Contour filter created in Step 4. To get a cone at the end of the tube segments, change the "Glyph Type" to "Arrow" and the "Tip Length" to 1. To get the glyphs to match the size of the tube, or to be slightly larger, turn "Scale Mode" to off and adjust the "Scale Factor" to 1. If the cone is too long in comparison to its base, you might need to increase the "Tip Radius" and decrease the "Scale Factor" to squash the cones.

The end result should be an image similar to the top image above.

Note that there are a couple of limitations to this technique. If the tube segments are very short, the cones at the tips may overlap because their lengths are not changed. Variations of this technique could deal with this by changing the Contour filter in Step 4 to an array that gives the length of the streamline generated in Step 3, but then density would no longer correspond to vector magnitude.

The ParaView state file for the example shown here is attached to this post. It requies the disk_out_ref.ex2 data file available here.

ParaView 4.2 available for download

$
0
0

ParaView 4.2.0 is now available to download. The complete list of over 200 issues resolved for this release can be found the ParaView Bug Tracker. Some of major highlights of this release are as follows:

 

Introducing ParaView Cinema

 

The idea behind Cinema is to process large data in either batch mode or in-situ using Catalyst to produce smaller data products which could then be viewed in a Web environment while allowing some interactivity and exploration freedom. This new framework is now part of ParaView as additional Python modules will allow dynamic and interactive data exploration within a web environment.

 

Expanded Properties panel

 

Continuing the process of avoiding users to have to switch between panels, which started with combining the Properties and Display panels into one, in 4.2 the View properties are now accessible from the Properties panel itself. Of course, some users may still prefer to have separate panels for each. For those, we have added a mode to customize this as well.

 

Application Settings

 

The infrastructure for managing user preferences and application settings was refactored from ground up. You can not only only change the configuration options previously exposed through the Settings dialog, but also change the default values for properties for any pipeline module including readers, filters, views and displays.

 

 

Not to be left behind, the Settings dialog was also redesigned to follow the now increasingly ubiquitous panel design with default/advanced view modes and searching capabilities.

 

 

Improved Python scripting and tracing

 

The Python tracing infrastructure received a much needed facelift in this release. Several changes to the underpinnings of the ParaView application logic now make it possible for sharing application logic between the graphical and Python-based applications. Thus, performing operations such as setting up color maps, rescaling color maps, creating views and displays, initializing filter defaults are now consistent between the two modes. Furthermore, tracing was made more robust are reliable to include working with color maps, multiple views, etc. Multiple tracing modes allow you to control the trace verbosity, making tracing a useful tool in learning ParaView’s Python API.

 

Improved NumPy integration

 

For users of Programmable Filter, Programmable Source, scripting become easier with improved NumPy integration. Writing NumPy expressions that work with distributed and/or composite datasets is now greatly simplified. Refer to the series of blog posts for more details starting with Improved VTK - numpy integration. Improved NumPy support also means improvements to Python Calculator and Find Data mechanism. For the first time, global operations like max(TEMP), min(Pres) are supported and work across ranks and data blocks.

 

Additional color legend options

 

The color legend has a slimmer default width when in the vertical orientation. The ranges are now displayed in scientific notation format, which can be customized, and have been moved to the same side as the intermediate numeric labels. Optionally, the numeric labels and tick marks can now be moved to the left side. Additionally, justification options for the title have been added (left, centered, and right). Tick marks, tick labels, and range labels may be independently turned off if so desired. All settings for color legends can be saved as custom defaults using the new settings capabilities described under Application Settings above.

 

User’s guide

 

The ParaView Book (or User’s guide) is being updated quite extensively. Updated version of the pdf as well as the printed book will be available soon.

 

ParaView Catalyst improvements

 

The ParaView Catalyst library can now be initialized without all processes by passing in the desired communicator to be used. The ParaView Catalyst script pipeline is now read only by process 0 and broadcast to all of the other processes.

 

ParaView Catalyst Live

 

ParaView Catalyst is a library that adds ParaView analysis and visualization capabilities to a simulation program. Furthermore, Catalyst can exchange data with a remote ParaView enabling easy inspection of simulation status and modification of analysis and visualization parameters. We call this connection ParaView Catalyst Live. For more information about Catalyst Live see the Introduction to ParaView Catalyst Liveblog post.

 

ParaView Web improvement

 

The main ParaViewWeb application had a facelift with new features and capabilities. It is becoming more flexible and getting closer to the actual ParaView Qt application UI philosophy.

 
Blog posts
 
As an experiment, we have been writing blog posts documenting new featrues as they are developed -- something we will continue to do in future to keep the community updated and get early feedback. Here are some of the posts that covers features that went into this release.
 
  1. Paraview's View Settings is moving to the Properties Panel

  2. Why is ParaView using all that memory?

  3. ParaView Catalyst Editions: What Are They?

  4. New in ParaView: Settings UI

  5. New in ParaView: Specular highlights

  6. New in ParaView: Color bar placement

  7. New in ParaView: Specifying custom default values

  8. New in ParaView: Customizing the Properties panel -- single panel or multiple tabs?

  9. New in ParaView: Rendering information in Render Views

  10. New in ParaView: Easy saving of custom defaults in ParaView

  11. ParaView: Python View is now more versatile

  12. New in ParaView: Python Trace On-the-fly

  13. New in ParaView: Histogram View

  14. ParaView: Improvements to Python script editors

  15. ParaView Trace Options: Controlling trace verbosity

  16. Slice Along a Polyline

  17. ParaViewWeb: Using ParaView's Visualization and Data Analysis Capabilities within Web Applications

  18. Updating the ParaView User's Guide

  19. ParaView Cinema: An Image-Based Approach to Extreme-Scale Data Analysis

  20. Introduction to ParaView Catalyst Live

New in ParaView: Coloring by string arrays

$
0
0

ParaView has always been able to map numerical values associated with points and cells to colors. ParaView 4.3 has the ability to map string arrays to colors. This feature works for string arrays in point data, cell data, and field data using the new feature that enables you to color by the first tuple in a field data array.

Coloring by string arrays is possible when the color map option "Interpret Values As Categories" is enabled and a set of annotations whose values are strings in the data array is defined. As with other cases where values are interpretted as categories, a set of active values can be obtained automatically from the data and defined as annotations using the tools in the Color Map Editor's Annotations section.

Let's take a look at an example data set that contains the countries of the world. The cells in the file that defined the countries have an associated string array named "REGION" that encodes the region in which the country is located. The image below shows the results of coloring by this region string array. Labels in the color legend show the region string values in the map data set.

The data file and ParaView state file that produced this image is attached to this post. You can try it out with ParaView 4.3 Release Candidate 1, available at the ParaView downloads page.

Mapping string arrays to colors in VTK

Coloring by string arrays is implemented in VTK, so any VTK-based application can do it. For example, imagine you have a data set where the colors to be used for cell data are defined by strings naming the colors. You can set up a vtkLookupTable to map these strings to the actual colors using the following code:

vtkLookupTable* lut = vtkLookupTable::New();  
lut->IndexedLookupOn();
lut->SetNumberOfIndexedColors(5);
lut->SetIndexedColor(0, 1.0, 0.0, 0.0); // red
lut->SetIndexedColor(1, 0.0, 0.0, 1.0); // blue
lut->SetIndexedColor(2, 0.0, 1.0, 0.0); // green
lut->SetIndexedColor(3, 1.0, 1.0, 0.0); // yellow
lut->SetIndexedColor(4, 0.0, 1.0, 1.0); // cyan

vtkStdString red("red");
lut->SetAnnotation(red, red);
vtkStdString blue("blue");
lut->SetAnnotation(blue, blue);
vtkStdString green("green");
lut->SetAnnotation(green, green);
vtkStdString yellow("yellow");
lut->SetAnnotation(yellow, yellow);
vtkStdString cyan("cyan");
lut->SetAnnotation(cyan, cyan);

Happy color mapping!


New in ParaView: Coloring by field data

$
0
0

In some situations, you may have a single data value associated with a data set that you would like to visualize "on" the data set. For example, you may want to visualize a boundary condition parameter defined for each surface in a computational fluid dynamics simulation. ParaView 4.3 now makes that possible.

You can now color data sets in ParaView by the value of a tuple in a field data array associated with the data set. Field data arrays in a data set now appear in the list of data arrays available to select for coloring. If a field data array is chosen, the first tuple in the array will be used to determine the color of the entire surface of the object being visualized. Tuples may have more than one component, in which case a specific element of the tuple can be selected (similar to how X, Y, or Z components can be selected for vectors) or the magnitude of the tuple can be selected instead.

Coloring by field data also works when you have a composite data set where each member data set has a field data array with the same name. As an example, consider the ParaView example data file tube.exii (available to download here). It is a multiblock data set containing four blocks. Each block has a field data array named "ElementBlockIds" that has one element with the block ID. If you select the "ElementBlockIds" array to use for coloring the data, each block will be colored by the element block ID associated with that block.

 

ParaView 4.3.1 available for download

$
0
0

ParaView 4.3.1 is now available for download. The complete list of over 70 issues resolved, including some of the critical ones detected in 4.2, can be found on the ParaView bug tracker.

 

Some of the major highlights of this release are as follows:

 

ParaView User’s Guide

A thoroughly revised version of the ParaView Guide is being prepared for publishing. The guide is being distributed as follows:

  • A CC-BY-4.0 versioned community edition (CE) PDF of the ParaView Guide is now freely available for download from the ParaView download page (under Data, Documentation, and Tutorials category).

  • Full color as well as B/W printed versions of the Guide are available for purchase. Besides the open-source parts of the Guide, this printed version includes three additional chapters that cover several domain specific use-cases and case-studies including CFD, Astrophysics, Climate, and VR. The printed versions will be available within the next few weeks.

Unlike in the past where the printed versions of the Guide would lag behind the ParaView releases, we are experimenting with a new approach which enables us to update all versions of the guide as frequently as the ParaView releases themselves.

 

Orthographic Slice View

A new version of the Quad View plugin is now available as a standard view in ParaView, named Orthographic Slice View. This view makes it easy to look at axis aligned slices in any dataset.

 

 

Map floating point arrays to colors

This version removes the requirement that only unsigned-char arrays can be mapped to colors directly without using a color transfer function. Three or four component floating point arrays in the range [0.0, 1.0] can now be directly interpreted as colors. Simply uncheck the Map Scalars checkbox on the Properties panel.

 

Color mapping by string arrays

Coloring by string arrays is possible when the color map option "Interpret Values As Categories" is enabled and a set of annotations whose values are strings in the data array is defined. As with other cases where values are interpreted as categories, a set of active values can be obtained automatically from the data and defined as annotations using the tools in the Color Map Editor's Annotations section. See the blog post about this feature for more details.

 

Color mapping by field data

You can now color data sets in ParaView by the value of a tuple in a field data array associated with the data set. Field data arrays in a data set now appear in the list of data arrays available to select for coloring. If a field data array is chosen, the first tuple in the array will be used to determine the color of the entire surface of the object being visualized. Tuples may have more than one component, in which case a specific element of the tuple can be selected (similar to how X, Y, or Z components can be selected for vectors) or the magnitude of the tuple can be selected instead. See the blog post for more details.

 

Adding active values from all visible objects

A new button in the Color Map Editor enables adding active values from all visible objects that are being colored by the array with the same name as the array coloring the active pipeline object.

 

Out-of-range colors

Prior to this release, values above the range of a color map were set to the color assigned to the maximum value. Likewise, values below the range of a color map were set to the color assigned to the minimum value. In this version of ParaView, you can now optionally set specific colors for values above and below the color map range.

 

Note to plugin/custom application developers

Please note that this will be the last release in which old style panels i.e. pqObjectPanel and subclasses will continue to work. Starting next release, all those classes will be removed.

Python Module to Create Weighted Functional Box Plots

$
0
0

With simple zero-dimensional data, basic statistics of a population can be displayed with a boxplot. A boxplot shows the median, interquartile range, and outliers in a population described using single scalar values. For example, you can plot the distribution of ages for a random sampling of 40 individuals. The boxplot shown below enables you to identify the median age, the interquartile range, and individuals who are outliers. The boxplot is an effective way to represent statistics about a population via the actual measurements from individuals within that population.

For our work on the project "Predictive Modeling for Treatment of Upper Airway Obstruction in Young Children" with collaborators at UNC, we are working with one-dimensional curves that represent airway cross-sectional area as a function of depth in the airway. A challenge with this data is to compute and display statistics over the population of curves. One might consider creating a point-wise average curve to represent a typical airway, but this might smooth out the data and produce a representation that is not reflective of any one individual. The same is true if we estimate airway typicality with a point-wise median/interquartile range calculation along all the curves.

An alternative solution uses individual curves from the population to represent the population median and interquartile range. This method relies on the calculation of a quantity for each curve called the "band depth". The band depth is essentially a measure of how often one curve is bounded above and below by other curves in a set. The curve with the highest band depth is considered the "most typical" and is equivalent to the median. The interquartile range for the functional boxplot is the region bounded by the top half of the curves, ranked by band depth.

This project has led to the development of the weighted functional boxplot [1]. A weighted functional boxplot assigns a weight to each curve in the population based on some attribute associated with the curve, e.g., age in months. This weight is used when determining band depth. The advantage of the weighted functional boxplot is that it can be used to adapt the statistics to a smaller segment of the total population. For the cross-sectional area curves, this can be used to visualize the airway statistics of 30-month-old children by putting a large weight on the curves from individuals who are close to 30 months old and smaller weights on curves from individuals much younger or older than 30 months.. In the weighted functional boxplot, the interquartile range is determined by the curves with the highest band depth that make up 50% of the population weight. Note that this is not necessarily half of the curves.

Though there was an existing module to generate unweighted functional boxplots, it was not possible to apply weights or use different methods to calculate band depth. We have developed a python module called AtlasBuilder that can do both of these things. Below you can see a set of functional boxplots produced from identical data using different generation algorithms.

The top row represents the results from two separate algorithms to calculate band depth with no weighting. The bottom row shows the plots for the population of 30-month-olds and 100-month-olds respectively. Note the overall increase in cross-sectional area for the 100-month plot. The black curves are the medians of each plot. The dotted lines are outliers. The magenta region is the area bounded by the curves that represent the interquartile range. The blue lines are not actually curves from the population but are the point-wise upper and lower bounds generated from the curves that envelope the magenta region. In the weighted functional boxplots there are two blue lines visible outside of the interquartile region. These lines indicate the region bounded by the curves with 99.7% of the population weight. 

The data that went into these graphs was generated from the cross-sectional area of the airways from control subjects derived from CT scans. The curves are registered using several anatomical landmarks so that each anatomical landmark is at the same parametric depth along the curve for each individual in the population.

The project described was supported by Grant Number R01HL105241 from the National Heart, Lung, And Blood Institute.  The content is solely the responsibility of the authors and does not necessarily represent the official views of the National Heart, Lung, And Blood Institute or the National Institutes of Health.

References

[1] Hong Y, Davis B, Marron JS, Kwitt R, Singh N, Kimbell JS, Pitkin E, Superfine R, Davis SD, Zdanski CJ, Niethammer M, Statistical Atlas Construction via Weighted Functional Boxplots, Medical Image Analysis. 2014 May;18(4):684-98.

Use viscm to design color maps for ParaView 4.4

$
0
0

This week at SciPy2015 I attended the talk by Stéfan van der Walt and Nathaniel Smith on designing a better default color map for Python (you can view a recording of the talk here). matplotlib's current default color map, shown below, is based on the rainbow color map, which has been shown  to actively mislead viewers in their interpretation of data.

Smith and van der Walt's talk laid out a few properties desired in a new default color map. It should be:

  • Colorful
  • Pretty
  • Sequential
  • Perceptually uniform in terms of uniform changes between successive colors in the map (even if printed in black and white)
  • Accessible to color blind viewers (5-10% of males of European descent)

The proposed default color map, named viridis, looks like this:

This is a vast improvement over the jet colormap in terms of perceptual uniformity, accessibility to color blind viewers, and conversion to black and white.

But why should matplotlib have all the fun? Attached is a JSON file that can be imported into ParaView 4.4 (coming later this summer; bleeding edge nightly builds are available now) and later. To import this color map, open up the Color Map Editor and click on the "Choose preset" button. In the dialog that appears, choose the "Import" button, and select the file paraview_cmap.json. Viola! Viridis is now available in ParaView!

Note that this color map is most appropriate for 2D data. Because the luminance of this color map changes from one end to the other, it is not recommended to color 3D surfaces because luminance changes in color maps interfere with surface shading from lighting.

To design this improved color map, van der Walt and Smith wrote a Python utility called viscm to design color maps with these properties. In addition to providing controls to define a color map in a way that has the desired properties, the utility shows the color map as printed in black and white and approximates how it appears to individuals with different types of color blindness. Screen shots of the utility are shown below.

A description of viscm and how to use it is available here. It provides the ability to export color maps in the form of a Python script. Exported color maps are saved in a file named /tmp/new_cm.py.

I have written a small Python script to convert this file to a JSON file that can be imported into the next release of ParaView. To use this script, first download the attached Python script named viscm2paraview.py. Then, run it with

python viscm2paraview.py /tmp/new_cm.py paraview_cmap.json "My Great Color Map"

Have fun trying viridis and designing new color maps for ParaView!

 

ParaView 4.4 available for download

$
0
0

ParaView 4.4 is now available for download. This is will be the last major release in the 4.* series. ParaView 5.0 will be released in the near term with a brand new rendering backend. A thorough list of over 160 issues and feature requests addressed by this release can be found here. Some of the major highlights of this release are as follows.

Axes Grid (aka Cube Axes 2.0)

This release introduces a new annotation type: Axes Grid. Axes Grid is designed as a Cube Axes replacement and can be used to render a grid for the coordinate axes. With improved labeling and formatting capabilities, Axes Grid is intended to completely replace Cube Axes in coming releases.

 

 

Artist-constructed colormaps

 

Several new color maps have been added that were designed through close collaboration between COSIM climate modelers at LANL, and artist Francesca Samsel.  The color maps move through changes in hue, saturation and value to create a longer line through color-space.

 

 

 

Quartile Chart View (Plotting multiple elements over time)

 

Quartile Chart View makes it easier to visualize summaries for values from multiple selected cells or points over time using the Plot Selection Over Time filter. This is now the default view used to show results from this filter.

 

 

Selection enhancements

 

A multitude of selection enhancements have gone into this release. Interactive selection allows users to interactively select and label elements in a dataset by simply moving their mouse pointer over the visualization. Modifier buttons make it easier to add/subtract selected elements even in the Render View.  Finally, Select Points On will find the closest point, retiring the need to rubber band select points.

Multiblock enhancements

Multiblock datasets are now automatically colored so that it’s easier to distinguish different blocks. Furthermore, the Multiblock Inspector reflects this coloring and allows users to override block colors and opacities as needed.

Display only available annotated values in the data set

An option has been added to the the Color Map Editor when interpreting values as categories to show only colors for annotated values actually in the data set. The data range concept has been extended to categorical data values to represent the list of categories in the data set. Updating the data range updates the colors displayed in the scalar bar.

 

Scalar bar and other scalar coloring improvements

Scalar bars used to automatically change orientation based on their placement in the view. The orientation can now be fixed to enable greater control of their placement. A bug that sometimes made setting a desired font size difficult or impossible has been fixed. The default number of digits of precision has also been changed from 20 to 6, given more readable scalar bar labels. As a side note, a brand new implementation for the scalar bar is currently underway, so stay tuned!

A new setting makes it possible to set a list of regular expressions defining array names that should not be displayed in the list of color arrays. This makes it easier to avoid cluttering the UI with internal arrays.

Furthermore, the Choose Presetdialog was completely revamped. It now allows searching for present using their name. Also the format for color preset files was changed from XML to a simpler JSON. Although importing older XML files is still supported, color presets can only be exported using the new JSON format.

Additionally, it is now possible to save a default color map for an array with a particular name so that any time an object is first colored by that array, the default for that array will be used. In the JSON settings file, a color map entry for a named looks like:

   {

     "array_lookup_tables" : {

       "<array name>" : {

        <state for the lookup table properties>

       }

     }

   }

 

Lightweight Periodic Dataset Generation

 

New in this release, Angular Periodic Filter allows users to generate an output dataset from a periodic block provided as the input with minimal memory overhead.

 

Snap points to surfaces

Points in Spline Source and Poly Line Source can be snapped to surfaces with the ‘p’ key. Select the point in the table in the Properties panel and type ‘p’ while hovering the mouse cursor over a point on the surface to snap the point to the surface.

Simplified Copy/Paste

Copy/Paste for copying filter properties has been supported in ParaView for several releases. In this releases, we made it easier to access (using buttons on the Properties panel) and extended the ability to including display and view properties.

Simply use the Copy/Paste to copy parameter values between filters, views, etc.

Reading image stacks as volume

To better handle tomography use-cases, we now support opening image stacks, e.g. a series of tiff files, as a 3D volume rather than a temporal dataset. On opening an image file series, users can choose to treat the dataset as a 3D volume using options on Properties panel.

 

 

 

The ParaView Guide is being updated to include documentation for several of these new features and the updated version will be made available with ParaView 5.0.

 

Blog posts

Here is a list of blog posts that describes some these features and more.

 
  1. Interacting with views in ParaView Python (pvpython)

  2. ParaView and Project Tango: Loading Data

  3. Zero copy arrays

  4. PHASTA + ParaView Catalyst: In Situ CFD Analysis at 256K MPI processes on BG/Q Mira

  5. NVIDIA IndeX Plug-in for ParaView: Analyze and Visualize Large Volume Datasets

  6. New in ParaView: Axes Grid Annotation

  7. Adding in Logic to a ParaView Catalyst Python Script

  8. Buildbot Primer for VTK and ParaView

  9. Colormaps Constructed with an Artist in the Loop

  10. New in ParaView: Quartile Chart View

  11. Project Tango at Kitware: Update at CVPR 2015

  12. Lightweight Periodic Dataset Generation

  13. Simple, Parallel Computing with vtkSMPTools

  14. New in ParaView: Rotating about a coordinate axis

  15. Selected ParaView 4.4 features

  16. Tomviz 0.6.1 Released: Tomography for Materials Science

  17. Color Multiblock Datasets

  18. New in ParaView: Changes to color/opacity presets

Defining Time-Varying Sources with ParaView's Programmable Source

$
0
0

One question about ParaView that comes up from time to time is how to define time-varying data sources with the Programmable Source. I'll show the basics of doing this here.

Let's start by looking at a simple example that produces a single static sphere. First, fire up ParaView and create a Programmable Source. The Script property for the Programmable Source in this example should be:

importvtk

sphere = vtk.vtkSphereSource()
sphere.SetRadius(1.0)
sphere.Update()
pd = self.GetPolyDataOutput()
pd.ShallowCopy(sphere.GetOutput())

This creates a simple sphere source at the origin. Pretty boring, right?

Let's make the sphere radius vary with time. To do this, we need to tell ParaView that our Programmable Source produces time-varying data. First, we tell the pipeline that the source has time information and define the time values in the Script (RequestInformation) property:

timeSteps =range(100)
outInfo = self.GetOutputInformation(0)
timeRange = [timeSteps[0], timeSteps[-1]]
outInfo.Set(vtk.vtkStreamingDemandDrivenPipeline.TIME_RANGE(), timeRange, 2)
outInfo.Set(vtk.vtkStreamingDemandDrivenPipeline.TIME_STEPS(), timeSteps, len(timeSteps))

Here, we define 100 timesteps [0, 1, 2, ... 99]. We need to inform the pipeline about the time range as well as the actual time values themselves. To do this, we set the vtkStreamingDemandDrivenPipeline.TIME_RANGE() and vtkStreamingDemandDrivenPipeline.TIME_STEPS() information keys in the output information.

Next, we adjust our original Script property to modify the radius according to the time value. We retrieve the time value with the vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP() key in the output information from the Programmable Filter and derive a radius value from it.

importvtk

outInfo =self.GetOutputInformation(0)if outInfo.Has(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP()):
  time = outInfo.Get(vtk.vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP())else:
  time =0

radius = math.sin(time*2*math.pi/100) +1.0

sphere = vtk.vtkSphereSource()
sphere.SetRadius(radius)
sphere.Update()

pd =self.GetPolyDataOutput()
pd.ShallowCopy(sphere.GetOutput())

When you click the Apply button on the Programmable Filter, you will notice that the number of time steps in the animation controls jumps to 100. If you click the play button, you will see a pulsing sphere.

Obviously, you can do a lot more with the timestep values. See, for example, section 13.2.2 in the ParaView User's Guide for how to read series of CSV files where each one defines a different timestep.

Viewing all 14 articles
Browse latest View live