Plotting hints and FAQ

More to come!

What’s the difference between make .plots and make plots ?

The default Makefile configuration in Version 4.5.1 was changed to allow two different targets .plots and plots. The former creates a hidden file .plots whose modification time is used to check dependencies. The plotting commands will be performed again only if the output of setplot file has been changed, and will also re-run the code if it appears that the output is out of date relative to the setrun file, for example. If you want to create the plots without checking dependencies (and perhaps accidentally re-running the code), use the make plots option. plots is a phony target in the default Makefile.

How to plot a something other than a component of q?

Objects of class ClawPlotItem have an attribute plot_var. If this is set to an integer than the corresponding component of q is plotted (remembering that Python indexing starts at 0, so plot_var = 0 will specify plotting the first component of q, for example).

If plot_var is a function then this function is applied to applied to current_data and should return the array of values to be plotted. For an example, see plotexample-acou-1d-6.

Sometimes you want to plot something other than the solution on the patch, for example to add another feature to a plot of the solution. This can be done via an afteraxes command, for example, which is called after all items have been plotted on the current axes. See ClawPlotAxes for details and an example.

How to add another curve to a plot, e.g. the true solution?

The afteraxes attribute of a ClawPlotAxes` object can be specified as either a string or a function. The string is executed (using exec(...)) or the function is called after performing all plots on these axes (as specified by ClawPlotItem` objects). This can be used to add a curve to a plot.

For example, if the true solution to an advection equation is known to be \(q(x,t) = \sin(x+t)\), this could be added to a plot as a red curve via:

def add_true_solution(current_data):
    from pylab import sin, plot
    x = current_data.x
    t = current_data.t
    qtrue = sin(x+t)
    plot(x, qtrue, 'r')

plotaxes.afteraxes = add_true_solution

How to change the title in a plot?

The title attribute of a ClawPlotAxes` object determines the title that appears a the top of the plot.

The title_with_t attributed determines if the time is included in this title. If True (the default value), then “at time t = ...” is appended to the title. The time is printed using format 14.8f if (t>=0.001) & (t<1000.), or format 14.8e more generally.

It is also possible to change the title using and afteraxes function. For example, to create a larger title with fontsize 20 and only 4 digits in t:

def add_title(current_data):
    from pylab import title
    t = current_data.t
    title("Solution at time t = %10.4e" % t, fontsize=20)

plotaxes.afteraxes = add_title

How to specify outdir, the directory to find fort.* files for plotting?

This is normally determined by the outdir attribute of the ClawPlotData object directing the plotting. But see the next FAQ for the option of using different directories for some plot items (e.g. to compare results of two computations).

If you are making a set of hardcopy plots using:

$ make .plots

or

$ make plots

then outdir is specified in the Makefile by setting the CLAW_OUTDIR variable.

If you are making plots interactively using Iplotclaw_, then you can directly specify the outdir as a parameter, e.g.:

In[1]: ip=Iplotclaw(outdir="_output");   ip.plotloop()

If you don’t specify this parameter, `Iplotclaw`_ will look for a file .output in the current directory. If you created the fort.* files by the command:

$ make .output

then the output directory is set in the Makefile and the file .output contains the path to the output directory.

Note: If you use

$ make output

which does not check dependencies, this also does not create a target file .output.

If the file .output does not exist, outdir = '.' is used by default, the current directory.

Note that if you stop a calculation mid-stream using <ctrl>-C, the file .output may not exist or be correct, since this file is written after the execution finishes.

How to specify a different outdir for some plot item?

If you want one plot item on an axis to use the default plotdata.outdir while another to take data from a different directory (in order to compare two computations, for example), you can set the outdir attribute of a ClawPlotItem directly. If you do not set it, by default it inherits from the ClawPlotFigure object this item belongs to.

For example, you might have the following in your setplot function:

plotfigure = plotdata.new_plotfigure(name='compare', figno=1)
plotaxes = plotfigure.new_plotaxes()

plotitem = plotaxes.new_plotitem(plot_type='1d_plot')
plotitem.plot_var = 0
plotitem.plotstyle = '-o'
plotitem.color = 'b'

plotitem = plotaxes.new_plotitem(plot_type='1d_plot')
import os
plotitem.outdir = os.path.join(os.getcwd(), '_output2')
plotitem.plot_var = 0
plotitem.plotstyle = '-+'
plotitem.color = 'r'

This would plot results from plotdata.outdir as blue circles and results from ./_output2 as red plus signs. It’s best to give the full path name, e.g. as done here using os.path.join(os.getcwd(), '_output2').

How to set plot parameters that are not provided as attributes of ClawPlotItem?

Some commonly used plotting parameters can be specified as an attribute of a ClawPlotItem`, for example:

plotitem = plotaxes.new_plotitem(plot_type='1d_plot')
plotitem.plot_var = 0
plotitem.plotstyle = '-'
plotitem.color = 'b'

specifies plotting a blue line. These attributes are used in the call to the matplotlib plot function. The plot function has many other keyword parameters that are not all duplicated as attributes of ClawPlotItem`. To change these, the kwargs attribute can be used.

For example, to plot as above, but with a wider blue line, append the following:

plotitem.kwargs = {'linewidth': 2}

If you try to specify the same keyword argument two different ways, e.g.:

plotitem.color = 'b'
plotitem.kwargs = {'linewidth': 2, 'color': 'r'}

the value in kwargs takes precedence. It is the kwargs dictionary that is actually used in the call, and the color attribute is checked only if it has not been defined by the user in the kwargs attribute.

How to change the size or background color of a figure?

By default, a figure is created of the default matplotlib size, with a tan background. Any desired keyword arguments to the matplotlib figure command can be passed using the kwargs attributed of ClawPlotFigure`. For example, to create a figure that is 10 inches by 5 inches with a pink background:

plotfigure = plotdata.new_plotfigure(name='pinkfig', figno=1)
plotfigure.kwargs = {'figsize': [10,5],  'facecolor': [1, .7, .7]}

Specifying colormaps for pcolor or contourf plots

The matplotlib module matplotlib.cm provides many colormaps that can be acquired as follows, for example:

from matplotlib import cm
cmap = cm.get_cmap('Greens')

matplotlib.colors provides some tools for working with colormaps, and some additional colormaps and tools can be found in clawpack.visclaw.colormaps.

In particular, the make_colormaps function simplifies the creation of new colormaps interpolating between specified colors. For example, a colormap fading from blue to yellow to red can be created with the command:

from clawpack.visclaw import colormaps
yellow_red_blue = colormaps.make_colormap({0.:'#ffff00', 0.5:[1,0,0], 1.:'b'})

The argument of make_colormaps is a dictionary that maps values to colors, with linear interpolation between the specified values. Each color can be specified in various ways, e.g. in the example above blue is specified as the matlab style ‘b’, yellow with an html hex string, and red with an RGB tuple [1,0,0].

The colormap above is also predefined as clawpack.visclaw.colormaps.yellow_red_blue and is used in many Clawpack examples.

The function clawpack.visclaw.colormaps.showcolors(cmap) can be used to display a colormap. `

How to debug setplot.py?

Suppose you are working in an interactive Python shell such as ipython and encounter the following when trying to plot with `Iplotclaw`_:

In [3]: ip=Iplotclaw(); ip.plotloop()
*** Error in call_setplot: Problem executing function setplot
*** Problem executing setplot in Iplotclaw
    setplot =  setplot.py
*** Either this file does not exist or
    there is a problem executing the function setplot in this file.
*** PLOT PARAMETERS MAY NOT BE SET! ***

Interactive plotting for Clawpack output...

Plotting data from outdir =  _output
Type ? at PLOTCLAW prompt for list of commands

    Start at which frame [default=0] ?

This tells you that there was some problem importing setplot.py, but is not very informative and it is hard to debug from within the Iplotclaw.plotloop method. You may also run into this if you modify setplot.py (inadvertantly introducing a bug) and then use the resetplot option:

PLOTCLAW > resetplot
Executing setplot from  setplot.py
*** Error in call_setplot: Problem executing function setplot
*** Problem re-executing setplot
PLOTCLAW >

If you can’t spot the bug by examing setplot.py, it is easiest to debug by exiting the plotloop and doing:

PLOTCLAW > q
quitting...

In [4]: import setplot
In [5]: pd = ip.plotdata
In [6]: pd = setplot.setplot(pd)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

      8
      9     # Figure for q[0]
---> 10     plotfigure = plotdata.new_plotfgure(name='q[0]', figno=1)
     11
     12     # Set up for axes in this figure:

AttributeError: 'ClawPlotData' object has no attribute 'new_plotfgure'

In this case, the error is that new_plotfigure is mis-spelled.

In ipython you can also easily turn on the Python debugger pdb:

In [9]: pdb
Automatic pdb calling has been turned ON

In [10]: pd = setplot.setplot(pd)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
      8
      9     # Figure for q[0]
---> 10     plotfigure = plotdata.new_plotfgure(name='q[0]', figno=1)
     11
     12     # Set up for axes in this figure:

AttributeError: 'ClawPlotData' object has no attribute 'new_plotfgure'

ipdb>

For more complicated debugging you could now explore the current state using any pdb commands, described in the documentation. See also the ipython documentation.