Reimplement plotting in C++

Registered by Benjamin Kehlet

Plotting via Viper is not an optimal solution (as has been said many times) since Viper is not maintained and since it required PyDolfin installed to be able to do plotting from C++.

Reimplementing (porting) Viper's functionality to C++ using VTK's C++ API should be pretty straight forward.
Fredrik has been working on this for some days now and the progress is good. The code is in https://code.launchpad.net/~simula-acdc/dolfin/dolfin-plot

Instead of rewriting Viper as a standalone application/module, we have placed the code within the Dolfin source tree to make testing and releasing easier.

As a next step, we could use this plotting code in Meshbuilder. That would reduce Meshbuilder to a small gui on top of Dolfin. It might then also replace Viper as a standalone application used for plotting meshes and meshfunctions from Dolfin XML files.

Blueprint information

Status:
Complete
Approver:
Anders Logg
Priority:
Undefined
Drafter:
None
Direction:
Approved
Assignee:
Fredrik Valdmanis
Definition:
Approved
Series goal:
Accepted for 1.1.x
Implementation:
Implemented
Milestone target:
milestone icon 1.1.0
Started by
Fredrik Valdmanis
Completed by
Anders Logg

Whiteboard

Targeted for 1.1 but not a blocker if we want to get 1.1 out before the summer.

F-V:
DOLFIN_NOPLOT is now supported, though slightly differently than in trunk. Trunk checks if it is set at all, while this branch checks if it is set to a nonzero value. This makes more sense in my opinion, as you can flip it between 0 and 1 (or some other value) to enable/disable plotting, rather than set/unset it. I can change it if the old behavior is preferred.

ART:
One request I have is to try to use this in a small parallel examples with each domain updating its portion of the field.

F-V:
The following functionality exists Viper but is not yet implemented in Dolfin. I don't know if this should be added or not:

- Specifying a mesh when plotting a function (right now it is just plotted on the mesh of its FunctionSpace).
- Include axes in plot
- A boolean keyword argument called "rescale" that I don't know the effect of
JH: If rescale is true vmin and vmax follows the min and max of the data that is plotted for each plot/update call

GNW: I suggest supporting plotting on mesh entities of dim d <= D. The DOLFIN VTK output supports this. It's really useful for plotting MeshFunctions.

F-V:
My contract with Simula is now over and the dolfin-plot branch is merged intro trunk. There are some todos/fixmes that I didn't have the time to look at:
- Boundary condition plotting does not work yet
- Plotting of MeshFunctions work in principle on vertices and cells. The appearance/coloring should be tweaked. In the case of vertices it would probably work to plot the vertices as a point cloud and color them based on the meshfunction value. Facet-based meshfunctions does not work yet, since VTK only supports setting values on points and cells. Facets could probably be colored by extracting a boundary-mesh and color the cells of that mesh instead.
- Offscreen rendering (rendering without X) and PDF/PS hardcopying is not implemented as VTK must be configured with special flags in order for that to work.
- 1D-plotting is not plotted in a traditional XY-plot. The scalar 1D case should be handled separately in VTKPlottableGenericFunction. The VTK-backend of Easyviz (SciTools) could provide a starting point for this.
- For compatibility with the plotting-examples of the book tutorial, site-packages/dolfin/common/plottin.py should be updated to return a dummy object that one can call methods on. These methods should simply warn the user that the interface has changed.
- Support for gathering of values to only have one plot window when running in parallel
- Documentation should be cleaned up and consolidated. The interface should be properly documented in one place. The parameters are documented in VTKPlotter.h and plotting.py, while the plot(obj) C++ interface is "documented" in plot.h.
- Plotting of mesh entity indices on facets and cells.

J-H:
Plotting vertex labels is only available when a mesh is plotted. This is might make perfect sense, but is not immediately intuitive and is not reflected in the help text.

MSA: It would be nice to have a shortcut key for closing all windows. It is a pain to click through many plot windows and press q in all of them.

BK:
Agree, it is very annoying. Should we change the 'q' keypress handler to close all windows, or introduce a new key (or possibly something like shift+q)?

AL:
I suggest CTRL-w for closing a single window and {CTRL-q or q} for closing all plots. Should be relatively easy to implement. There is a global (static) list of all VTKPlotter instances that can be accessed so we could iterate through them all.

BK:
This turned out to be slightly more tricky than just defining some keyboard shortcuts because of the way the event system in VTK is designed. I have at least improved it a bit, so only one event loop will be entered. This means that pressing 'e' or 'q' will close all VTK windows.

JBH:
Just a quick summary of the changes that have been merged last week. If noone objects, I suggest this blueprint is marked as done (I do not have permission to do so). The remaining work items are either minor, impossible in VTK (plotting without window system), or have separate blueprint (https://blueprints.launchpad.net/dolfin/+spec/multiple-plottables-vtkplotter).

Library related changes:

- VTK back to 5.2 is supported, in some cases missing (non-essential) functionality.

- If Qt and QVTK are available, the plot windows become Qt widgets. Some functionality which is impossible to implement (robustly) in pure VTK is only available in this case. This includes some window operations like closing a single plot window, (occasional) interaction while a simulation is running, GUI integration, etc.

API/parameter related changes:

- Value ranges (range_min, range_max) are properly supported, and behave correctly if only one of them is set. If not set, the automatic ranges are rounded to two significant digits, and additionally rounded to zero if that can be achieved without changing the range more than 5%.

- Programmatic setting of zoom level.

- A new parameter "key", which can be set equal in two plot calls to reuse the same window even if the functions are different (e.g. with project(u) in a time loop when u is the same function).

- Reintroduce the parameter "axes", which was in viper. Shows X-Y-Z axes in plot.

Support more data types:

- DirichletBCs are supported; internally, a function is created with all-NaN values, and the BCs are applied on this function. The NaNs are plottes as (semi-)transparent, so this should make it easy to see the difference between a zero boundary and an unset boundary.

- MeshFunction<x> are supported.

- 1D functions are supported with X-Y plots. These plots are very inflexible in VTK, so not much can be done with the appearance. VTK X-Y charts are not used, because they are not available in older VTK.

- (Surface of) CSG geometries. This is fairly fast. To plot the full geometries, plot the resulting mesh instead (this can be quite slow in 3D).

- Plot DG0 functions in 2+ dimensions as discontinuous. Basically, they are treated the same way as MeshFunction<double>. A more general treatment of discontinuous functions is possible, but requires more work (in particular the vertices must be duplicated per cell).

New key bindings:

- Change "h" (write to png) to "p" (png) / "P" (pdf). Pdf output is only available if VTK is built with GL2PS. It works in ubuntu, at least. The pdf output is hit-and-miss -- it should be ok for 2D plots, but 3D may not be so nice. It should be possible to handle 3D better by rasterisation, but that is currently commented out because it crashed for me.

- Change "p" (bounding box) to "b".

- New binding "m", which toggles a wireframe view of the original mesh. Especially nice with vector plots. I think it may be nice to show this by default, in fact.

- New bindings "c" and "v", to show cell or vertex indices. There is a known problem with visibility of the labels, it is unstable whether they are calculated to be behind a given surface or not. This is a problem with VTK's vtkSelectVisiblePoints filter -- see tolerance setting and comment in VTKPlottableMesh::get_vertex_actor().

- Old bindings "w" and "s" are replaced by a single key "w", which cycles between surface / wireframe / point representations.

- Points and lines can be resized by "+"/"-". Especially useful with point representation.

- Glyphs and warping can be rescaled by Ctr-"+"/"-". Useful with vector plots, but also warped 2D plots.

- Keys "h" and "H" are used to show keybinding help, either in-plot or printed to console

- Ctrl-"w"/"q"/"c" - close single window, close all windows, abort execution. The first two are only available with Qt.

- "q" is as before, but additionally "Q" can be used to run the simulation to the end. Like pressing "q" repeatedly. With Qt, the key "I" is also available, which enters interactive mode immediately (well, in the next plot command). In general, the Qt event loop processes events whenever plot() is called, so limited interactivity is supported also before calling interactive().

- "s" synchronises the camera between different plot windows. A nice workflow is to plot different data on the same mesh, and hold down the "s" key while manipulating (spinning, zooming) the plot. This will hopefully alleviate somewhat the fact that only a single function can be shown in a plot window (see separate blueprint).

Miscellaneous:

- General bug fixes and minor improvements all around.

- A new demo which shows integration into a Qt application, mesh picking, etc.

AL: Excellent work Joachim! Thanks! :-) Closing this blueprint now.

(?)

Work Items

Work items:
Basic plotting of mesh and functions: DONE
Display help text: DONE
Support DOLFIN_NOPLOT, abort when set to nonzero value: DONE
Use name, label (from Varible) in title: DONE
Document VTKPlotter in VTKPlotter.h header, parameters etc: DONE
Updated plot, cache of VTKPlotter objects in plot.cpp, decide whether to call plot or update: DONE
Parameter handling in C++, plot(object, parameters): DONE
Parameter argument title should override default title: DONE
Parameter handling in Python, plot(object, parameters), plot(object, key=value, key=value): DONE
Handling of plotting elements, expression in Python (plotting.py) : DONE
When several plots windows are created, make sure they don't overlap completely: DONE
Implement impressive plotting demo in C++: DONE
Save to PNG: DONE
Implement support for MeshFunctions: DONE
Plotting of DirichletBC in C++: DONE
Improve handling of scaling (value ranges): DONE
Improve window management (^w, ^q, etc): DONE
Add id parameter (or similar) to enable update-functionality for projections: DONE
Make plot windows available as a Qt widget (using QVTK): DONE
Toggle mesh view when plotting glyphs: DONE
Synchronize camera between views: DONE
Plotting of CSG geometries: DONE
Plot mesh indices (labels): DONE
Plot DG0 functions: DONE
Save to PDF (PS): DONE
Prettier 1D plots: DONE
Support VTK 5.2: DONE
Prettify help text (alignment etc): DONE
Implement the "rescale" parameter: DONE
Implement the "axes" parameter: DONE
Warped 2D plots should be elevated by default (see code examples from the book): DONE
Find out what to do with the "mesh" keyword argument in Python: DONE
Support controling range by setting range_min and range_max: DONE
Mouse picking of meshentities (needed in Meshbuilder): DONE
Plot DGx functions and DG0 in 1D: TODO
Parameterised 1D plots for 2+D geometries: TODO
Consider adding several objects to the same window: TODO
Deprecate old C++ keyword argument interface: POSTPONED
One parameter mode=warp etc with warnings when not make sense: POSTPONED
Support plotting without window system: Don't show plot on screen, save to file instead: POSTPONED

This blueprint contains Public information 
Everyone can see this information.