\(\newcommand{\AA}{\unicode{x212B}}\)

11. Plotting and Displaying Data

Plotting and Visualizing data are vital to any scientific analysis package, and Larch provides several methods for data visualization. These are largely built on two types of data display. The first is the line plot (sometimes calld an xy plot), which shows traces of a set of functions y(x). The second type of data display supported is the 2-dimensional image display, in which a grey scale or false color map shows an image representing a 2-dimensional array of intensity.

Though not a dedicated plotting and graphics packages, Larch attempts to provide satisfying graphical displays of data, and the basic plots made with Larch are of high enough quality to include in publications. In addition, both line plots and image display provide interactive features such as zooming in and out, changing properties such as colors and labels. Finally, copying and saving images of the graphics is easy and can be done either with keyboard commands such as Ctrl-C or from dropdown menus on the graphic elements.

11.1. Line Plots

Larch provides a few functions for making line plots, with the principle function being called plot(). The plot() function takes two arrays: x, the abscissa array, and y, the ordinate array. It also accepts a very large number of optional arguments for setting properties like color, line style, labels, and so on. Most of these properties can also be set after the plot is displayed through the graphical display of the plot itself. The plots are fully interactive so that coordinates can be seen (and written to larch variables) by clicking on the plot, and zooming in on portions of the plot can be done with click-and-drag. Right-clicking will pop up a list of options for zooming out, configuring the plot, or saving a PNG image of the plot. Menus on the window frame give even more options, including Copy-to-clipboard and printing.

Multiple plot windows can be shown simultaneously, each in an independent window, and you can control which one is drawn to with a plot window index win.

11.1.1. plot(), newplot(), and oplot()

These functions all create a Line Plot from array of x and y data that are taken to be ordered, and so can be drawn as connected by lines from one point to the next. These functions share many options to set labels, colors, and so on to modify the resulting plot. All options are specified by the keyword/value arguments described in the Table of Plot Arguments below.

_plotter.plot(x, y, **kws)
Parameters:
  • x – array of x values

  • y – array of y values – same size as x

  • kws – optional commands as listed in Table of Plot Arguments.

Plot y(x) given 1-dimensional x and y arrays – these must be of the same size. Each x, y pair displayed is called a trace.

_plotter.newplot(x, y, **kws)
Parameters:
  • x – array of x values

  • y – array of y values – same size as x

  • kws – optional commands as listed in Table of Plot Arguments.

This is essentially the same a plot(), but with the option new=True. The rest of the arguments are as

_plotter.oplot(x, y, **kws)
Parameters:
  • x – array of x values

  • y – array of y values – same size as x

  • kws – optional commands as listed in Table of Plot Arguments.

This is essentially the same a plot(), but with the option new=False.

Table of Plot Arguments These arguments apply for the plot(), newplot(), and scatterplot() methods. Except where noted, the arguments are available for plot() and newplot(). In addition, the scatterplot() method uses many of the same arguments for the same meaning, as indicated by the right-most column.

argument

type

default

meaning

scatterplot?

title

string

None

Plot title

yes

ylabel

string

None

abscissa label

yes

y2label

string

None

right-hand abscissa label

yes

label

string

None

trace label (defaults to ‘trace N’)

yes

win

integer

1

index of plot window to use (1, 2, …, 16)

yes

side

left/right

left

side for y-axis and label

yes

grid

None/bool

None

to show grid lines

yes

fullbox

bool

True

to show full box (not just left + bottom axes)

no

color

string

blue

color to use for trace

yes

bgcolor

string

white

color to use for plot background

yes

framecolor

string

white

color to use for outer plot frame

yes

gridcolor

string

gray

color to use grid

yes

use_dates

bool

False

to show dates in xlabel (plot() only)

no

linewidth

int

2

linewidth for trace

no

style

string

solid

line-style for trace (solid, dashed, …)

no

drawstyle

string

line

style connecting points of trace

no

marker

string

None

symbol to show for each point (+, o, ….)

no

markersize

int

8

size of marker shown for each point

no

labelfontsize

int

9

font size of labels

no

legendfontsize

int

7

font size of legend

no

dy

array

None

uncertainties for y values; error bars

no

ylog_scale

bool

False

draw y axis with log(base 10) scale

no

xmin

float

None

minimum displayed x value

yes

xmax

float

None

maximum displayed x value

yes

ymin

float

None

minimum displayed y value

yes

ymax

float

None

maximum displayed y value

yes

autoscale

bool

True

whether to automatically set plot limits

no

zorder

None/int

None

Z-order of trace (which trace is on top)

no

show_legend

None/bool

None

whether to display legend (None: leave as is)

no

legend_loc

string

‘ur’

location of legend (‘ur’, ‘ll’, etc)

no

refresh

bool

True

whether to refresh display

no

arguments that apply only for scatterplot()

size

int

10

size of marker

yes

edgecolor

string

black

edge color of marker

yes

selectcolor

string

red

color for selected points

yes

For each plot window, the configuration for the plot (title, labels, grid displays, etc) and the properties of each trace (color, linewidth, …) are preserved for the duration of that window. A few specific notes:

1. The title, label, and grid arguments to plot() default to None, which means to use the previously used value.

2. The use_dates option is not very rich, and simply turns x-values that are Unix timestamps into x labels showing the dates.

3. While the default is to auto-scale the plot from the data ranges, specifying any of the limits will override the corresponding limit(s).

4. The color argument can be any color name (“blue”, “red”, “black”, etc), standard X11 color names (“cadetblue3”, “darkgreen”, etc), or an RGB hex color string of the form “#RRGGBB”.

5. Valid style arguments are ‘solid’, ‘dashed’, ‘dotted’, or ‘dash-dot’ , with ‘solid’ as the default.

6. Valid marker arguments are ‘+’, ‘o’, ‘x’, ‘^’, ‘v’, ‘>’, ‘<’, ‘|’, ‘_’, ‘square’, ‘diamond’, ‘thin diamond’, ‘hexagon’, ‘pentagon’, ‘tripod 1’, or ‘tripod 2’.

7. Valid drawstyles are None (which connects points with a straight line), ‘steps-pre’, ‘steps-mid’, or ‘steps-post’, which give a step between the points, either just after a point (‘steps-pre’), midway between them (‘steps-mid’) or just before each point (‘steps-post’). Note that if displaying discrete values as a function of time, left-to-right, and want to show a transition to a new value as a sudden step, you want ‘steps-post’.

Again, most of these values can be configured interactively from the Plot configuration window.

_plotter.scatterplot(x, y, **kws)

A scatterplot differs from a line plot in that the set of x, y values are not assumed to be in any particular order, and so are not connected with a line. Arguments are very similar to those for plot(), and are listed in Table of Plot Arguments.

_plotter.update_trace(x, y, trace=1, win=1, side='left')

updates an existing trace of a plot.

Parameters:
  • x – array of x values

  • y – array of y values

  • win – integer index of window for plot (1 is the first window)

  • trace – integer index for the trace (1 is the first trace)

  • side – which y axis to use (‘left’ or ‘right’).

This function is particularly useful for data to be plotted is changing and you wish to update traces from a previous plot() with new data without completely redrawing the entire plot. Using this method is substantially faster than replotting, and should be used for dynamic plots, such as plottting the progress of some function during a fit. Note that you cannot change properties such as color here – these will be inherited from the existing trace. In that sense, most of the properties of the trace and of the plot as a whole remain unchanged, it just happens that the data for the trace has been replaced.

_plotter.plot_text(text, x, y, win=1, side='left', rotation=None, ha='left', va='center')

add text at x, y coordinates of the plot window

Parameters:
  • text – text to draw

  • x – x position of text

  • y – y position of text

  • win – index of Plot Frame (0, 1, etc). May create a new Plot Frame.

  • side – which axis to use (‘left’ or ‘right’) for coordinates.

  • rotation – text rotation. angle in degrees or ‘vertical’ or ‘horizontal’

  • ha – horizontal alignment (‘left’, ‘center’, ‘right’)

  • va – vertical alignment (‘top’, ‘center’, ‘bottom’, ‘baseline’)

_plotter.plot_arrow(x1, y1, x2, y2, win=1, **kws)

draw arrow from x1, y1 to x2, y2.

Parameters:
  • x1 – starting x coordinate

  • y1 – starting y coordinate

  • x2 – endnig x coordinate

  • y2 – ending y coordinate

  • win – index of Plot Frame (0, 1, etc). May create a new Plot Frame.

  • side – which axis to use (‘left’ or ‘right’) for coordinates.

  • shape – arrow head shape (‘full’, ‘left’, ‘right’)

  • fg – arrow fill color (‘black’)

  • width – width of arrow line (in points. default=0.0)

  • head_width – width of arrow head (in points. default=0.05)

  • head_length – length of arrow head (in points. default=0.25)

  • overhang – amount the arrow is swept back (in points. default=0)

_plotter.plot_marker(x, y, marker='o', size=4, color='black', label='_nolegend_', win=1, **kws)

draw a single marker at x, y

Parameters:
  • x – x coordinate

  • y – y coordinate

  • marker – symbol to draw at each point (‘+’, ‘o’, ‘x’, ‘square’, etc) [‘o’]

  • size – symbol size [4]

  • color – color for marker [‘black’]

  • win – index of Plot Frame (0, 1, etc). May create a new Plot Frame. [1]

  • kws – other arguments are semt to func:oplot.

plot_axhline(y, xmin=0, xmax=1, win=1, size=None, **kws):

plot a horizontal line spanning the plot axes

Parameters:
  • y – y position of line

  • xmin – starting x fraction (window units – not user units!) [0]

  • xmax – ending x fraction (window units – not user units!) [1]

  • win – index of Plot Frame (0, 1, etc). May create a new Plot Frame. [1]

  • kws – other arguments are semt to func:axes.axhline

plot_axvline(x, ymin=0, ymax=1, win=1, size=None, **kws):

plot a horizontal line spanning the plot axes

Parameters:
  • x – x position of line

  • ymin – starting y fraction (window units – not user units!) [0]

  • ymax – ending y fraction (window units – not user units!) [1]

  • win – index of Plot Frame (0, 1, etc). May create a new Plot Frame. [1]

  • kws – other arguments are semt to func:axes.axvline

_plotter.save_plot(filename, dpi=600, format=None, win=1, facecolor='w', edgecolor='w', transparent=False)

save the current plot to a PNG or other output formats.

Parameters:
  • filename – name of output file

  • dpi – resolution (dots per inch)

  • format – output format (one of ‘png’, ‘pdf’, or ‘svg’)

  • win – index of Plot Frame (0, 1, etc). May create a new Plot Frame.

  • facecolor – color of plot background (not supported for all formats)

  • edgecolor – color of plot frame color (not supported for all formats)

  • transparent – whether to use a transparent background.

_plotter.save_image(filename, dpi=600, format=None, win=1, facecolor='w', edgecolor='w', transparent=False)

save the current 2D image from imshow() to a PNG or other output formats.

Parameters:
  • filename – name of output file

  • dpi – resolution (dots per inch)

  • format – output format (one of ‘png’, ‘pdf’, or ‘svg’)

  • win – index of Plot Frame (0, 1, etc). May create a new Plot Frame.

  • facecolor – color of plot background (not supported for all formats)

  • edgecolor – color of plot frame color (not supported for all formats)

  • transparent – whether to use a transparent background.

_plotter.get_display(win=1)

return the underlying Display object. For advanced usage, this allows access to the PlotDisplay object, which is the wxPython frame for the plot window. The plot itself is contained in the panel attribute, which contains the matplotlib components axes and canvas. For more details, see Advanced Plotting: using matplotlib.

11.1.2. Plot Examples

Here are a few example line plots, to whet your appetite:

x = linspace(0, 10, 101)
y1 = sin(x)
y2 = -2 +0.2*x + (0.2*x)**2
newplot(x, y1)

will make this plot:

_images/plot_basic1.png

Figure 11.1.2.1 A basic line plot.

Adding a second curve, and setting some labels:

plot(x, y2, xlabel='x (mm)', ylabel='f(x)', title='Example Plot')

will make this plot:

_images/plot_basic2.png

Figure 11.1.2.2 A line plot with two curves.

11.1.3. Interactive Use of the Plot Windows

From the main plot window, you can perform several tasks interactively:

Getting Cursor Position:

From the plot window you can click the left button of your mouse, and see the X, Y coordinates of where you clicked displayed in the status bar at the bottom of the plot window. You can also read the values from the variables _plotter.plot1_x and _plotter.plot1_y, for plot window 1, and _plotter.plot2_x and on for other plot windows.

Zooming in and out:

Left-clicking on the plot window and then dragging the mouse around with the button still pressed will draw a rectangular box around part of the plot window. Releasing the mouse will zoom in on the portion of the plot set by the rectangle. You can zoom in multiple times.

To unzoom, press Ctrl-Z (Apple-Z on Mac OS X), which will go back to the previous zoom rectangle. You can also right-click on the plot, which will bring up a window from which you can zoom out 1 level at a time, or all the way back to fully zoomed out.

Copy to Clipboard:

To copy the plot image (just the main plot image, not all the Window decorations such as menus and status bar) to the sysem clipboard, type Ctrl-C (Apple-C for Mac OS X users). You can then paste this image into other applications such as rich text documents and slide presentations.

Save image to PNG, PDF, or SVG:

To save the plot image to a standard image format, use Ctrl-S (Apple-S for Mac OS X users). This will bring up a ‘save file’ dialog box for writing an image file. The images will be generally high resolution, and should be of sufficiently high quality to be acceptable for publication or public display. Each of the supported image formats – PNG (default), PDF, and SVG – has its strengths and weaknesses. The PNG images use high resolution (600dpi) and anti-aliasing, and are generally higher quality than the SVG images. The PDF images include real font information but does not use anti-aliasing.

Print image:

On many systems, you should be able to print directly from the Plot Window, using Ctrl-P (Apple-P for Mac OS X users). This may not work on all systems, in which case saving an image and printing that should

Configuring the Plot:

From the Plot Window, either Ctrl-K (Apple-K for Mac OS X users) or Options->’Configure Plot’ (or right-click to bring up a popup menu, then select Configure) will bring up the plot configuration window, which looks like this:

_images/plot_config.png

Figure 11.1.3.1 Screenshot of the Configuration window for Plots.

From here you can set the titles, axis labels, and styles, colors, symbols, labels, and so on for each of the line traces drawn.

11.1.4. Using TeX-like commands for labels and titles

The titles and labels for plot elements can be simple strings or use a subset of TeX markup to give fine control over typesetting greek letters, mathematical symbols and formulae. A simple example would be:

plot(k, chi, xlabel = '$ k \rm(\AA^{-1}) $', ylabel = '$ \chi(k) $ ')

The portion of the strings between the dollar signs (‘$’) will be rendered as TeX-like markup, and so render the x and y labels as (for the pedantic, these renderings below may be only approximate):

\(k \rm(\AA^{-1})\)

\(\chi(k)\)

An important point here is the use of the backslash character, ‘\’, which you may recall from the tutorial is also used as an escape sequence. Thus some TeX sequences, such as ‘\theta’ may require an additional backslash, so that the ‘\t’ part isn’t rendered as a tab character. More generally, use of raw strings is recommended in this context, so that one uses:

plot(k, chi, xlabel = r'$ k \rm(\AA^{-1}) $', ylabel = r'$ \chi(k) $ ')

Note that this does not actually use TeX (so you don’t need TeX installed), and the rendering is done by the matplotlib library. For further details about using TeX for markup, including a list of symbols, commands to change fonts, and examples, can be found at https://matplotlib.org/users/mathtext.html

When using the Plot Configuration window to enter a TeX-like string, the text control box will be given a yellow background color (instead of the normal white color) if there is an error in rendering your TeX string.

11.2. Image Display and Contour

_plotter.imshow(dat, x=None, y=None, colormap=None, **kws)
Parameters:
  • dat – 2-d array of some intensity

  • x – 1-d array of x values

  • y – 1-d array of y values

  • colormap – name of color table to use.

display a grey-scale or false-color image from a 2-d array of intensities.

_plotter.contour(dat, x=None, y=None, colormap=None, nlevels=None, **kws)
Parameters:
  • dat – 2-d array of some intensity

  • x – 1-d array of x values

  • y – 1-d array of y values

  • colormap – name of color table to use.

  • nlevels – number of contour levels shown

display a grey-scale or false-color contour map from a 2-d array of intensities.

For both these functions, the x and y arguments are intended to show real world coordinates for the image, not just the array indices. If None, the array indices will be shown.

By default, the image will be shown with the origin (pixel [0, 0]) in the lower left corner. The image can be rotated and flipped by the user.

The colormap argument is the name of the color map to use to transform intensity to color. The default table is ‘gray’ for a grayscale mapping. Other valid names include ‘coolwarm’, ‘cool’, ‘hot’, ‘jet’, ‘Reds’, ‘Greens’, ‘Blues’, ‘copper’, and a host of others, available

From the Image Display Window, you zoom in on regions of the image, rotate the image, change the color table, change the intensity scaling, change the interpolattion algorithm used. You can also toggle between showing an image of continuously varying intensities and a contour map. An example image, generated with

## examples/plotting/doc_image2d.lar

def gauss2d(x, y, x0, y0, sx, sy):
    return outer(exp(-(((y-y0)/float(sy))**2)/2),
                 exp(-(((x-x0)/float(sx))**2)/2))
enddef

ny, nx = 350, 400
ix = arange(nx)
iy = arange(ny)
x  =  ix / 10.
y  = -2 + iy / 10.0

dat = 0.2 + (0.05*random.random(size=nx*ny).reshape(ny, nx) +
             2.0*gauss2d(ix, iy, 190,   176,  57,  69))

imshow(dat, x=x, y=y, colormap='coolwarm')

## end of examples/plotting/doc_image2d.lar

is shown below:

_images/plot_image1.png

Figure 11.2.1 A false-color display of 2 dimensional image data.

and as a contour plot, with a different color table:

_images/plot_contour1.png

Figure 11.2.2 A contour plot of 2 dimensional image data.

11.3. Advanced Plotting: using matplotlib

So far, this chapter has shown how to make simple plots and images. One of the main goals of Larch is to not only make the simple tasks very simple, but to keep the more difficult tasks possible and accessible. To this end, you can access both the wxPython and matplotlib components of the plots and images to do plotting tasks not covered above.

The matplotlib library offers a full range of line and image plotting functionality, as well as some support for 3-dimensioanl plotting. Larch gives you access to the maplotlib API by giving you access to the matplotlib Axes and Canvas for any displayed plot. To get this, you would use get_display() to get the current display window, then access the panel.axes member:

larch> x = linspace(0, 10, 101)
larch> y = sin(x)
larch> plot(x, y)
larch> display = get_display(win=1)
larch> axes = display.pane.axes

As an example of what you can do with this, here we make a histogram plot from a sampling of a more conitinuous distribution. This uses matplotlib’s hist() function,

## examples/plotting/doc_use_mpl.lar
#
from scipy.special import gamma

title = 'GNXAS-like distribution function'

sigma, beta, r0 = 0.12, 0.65, 3.0
q    = 4/beta**2
amp  = 2 / (sigma*abs(beta)*gamma(q))

# calculate g(r) on a fine r-grid:
r   = linspace(2.5, 3.5, 201)
arg = q + (2*(r-r0)) / (beta*sigma)
gr  = amp * exp(-arg)*arg**(q-1)
# note removal of nan's and impossible values
gr[isnan(gr)] = 0
if min(gr)< 0: gr[where(gr<0)] = 0

# standard plot of g(r)
newplot(r, gr, grid=False,
        xlabel=r'$R\,\rm(\AA)$', ylabel=r'$g(R)$',
        title=title, fullbox=False)

# calculate g(r) on a coarse r-grid:
hr   = linspace(2.5, 3.5, 21)
harg = q + (2*(hr-r0)) / (beta*sigma)
hgr  = amp * exp(-harg)*harg**(q-1)
hgr[isnan(hgr)] = 0
if min(hgr)< 0:  hgr[where(hgr<0)] = 0

# get panel, matplotlib axes
panel = get_display().panel
axes  = panel.axes

# plot histogram of coarse-grid data
histo = axes.hist(hr, weights=hgr, bins=len(hr), rwidth=0.25, color='k')
panel.draw()

## end of examples/plotting/doc_use_mpl.lar

which generates a plot that looks like

_images/plot_histogram.png

Figure 11.3.1 A histogram plot made using matplotlib’s hist() function.