Tutorial 4: Plotting multiple 1Ds

It is quite common to want to plot multiple 1D spectra on the same plot: in fact, so common that we will dedicate an entire introductory tutorial to it.

Because we will be doing quite a number of repetitive calls here, I suggest moving these commands into a Python script (or a Jupyter notebook), instead of typing them into the interactive REPL. All of the following code examples are scripts which can be run from inside the nmrdata folder. You can put the script anywhere you like, but will have to adjust the path to the nmrdata folder appropriately, so that penguins can find the data.

If you are using the sample nmrdata spectra, start by placing these lines at the top of your script (or notebook cell):

import penguins as pg
em = pg.read(".", 1, 1)  # this is the same as `data_1d` in previous tutorials
gm = pg.read(".", 1, 2)  # this is new

These two datasets have the same raw data, but are processed with different window functions: em uses an exponential window function, whereas gm uses a Gaussian window function. You are, of course, free to substitute this with any of your own data.


Staging multiple spectra

This is easy: just stage them with any of the options described in Tutorial 3: Customising 1D plots. For the purposes of this tutorial, let’s focus on the multiplet at 4.63 ppm. The coupling is barely resolved in the em spectrum, but can be seen more clearly in the gm spectrum. Add the following lines to your script, then run it:

em.stage(bounds="4.62..4.65", linestyle="--")   # stage the first one
gm.stage(bounds="4.62..4.65")                   # stage the second one
pg.mkplot()                                     # construct as usual
pg.show()                                       # display as usual
../../_images/multiple_1d-2.svg

Adding a legend

To add a plot legend, do one of the following:

  1. Pass the legend labels as the label keyword argument when staging. penguins will automatically create a legend if any of the plots are staged with the label keyword.

  2. Manually call matplotlib’s legend() function.

If you do the latter, we assume you are at least a little familiar with matplotlib, and won’t discuss it further. Here’s an example of the former. Modify the two calls to stage() to include a label argument:

em.stage(bounds="4.62..4.65", linestyle="--", label="Exponential")
gm.stage(bounds="4.62..4.65", label="Gaussian")
pg.mkplot()
pg.show()
../../_images/multiple_1d-3.svg

Because the label is just any old Python string, you can combine this with the attribute access discussed in Tutorial 1: Reading data. The f-string syntax in Python 3.7+ is especially useful for this: for example, label=f"lb={em['lb']}" would create a legend label which contains the value of the LB parameter for that dataset.


Horizontal and vertical offsets

TopSpin’s multiple display mode has a few settings which allow you to stack spectra or to shift them by a constant amount, which is really useful for plotting. However, these are not spectrum-specific options: they are options which affect the entire plot. That’s why these options will be passed to mkplot(), rather than stage().

Horizontal offsets, controlled by the hoffset parameter, are specified in units of ppm. The first spectrum will not be shifted, and subsequent spectra will be shifted rightwards (i.e. to lower chemical shift):

em.stage(bounds="4.62..4.65", label="Exponential")
gm.stage(bounds="4.62..4.65", label="Gaussian")
pg.mkplot(hoffset=0.03)
pg.show()
../../_images/multiple_1d-4.svg

Vertical offsets voffset are specified as a fraction of the height of the tallest spectrum. Successive spectra are moved upwards. Note that 1 is not the best value: often 1.1 or so is better as that adds a bit of empty space between plots.

em.stage(bounds="4.62..4.65", label="Exponential")
gm.stage(bounds="4.62..4.65", label="Gaussian")
pg.mkplot(voffset=1)
pg.show()
../../_images/multiple_1d-5.svg

Of course, you can specify both hoffset and voffset to get spectra that are diagonally offset from one another. This is commonly used, for example, when plotting a series of related spectra.


voffset and stacked

We’re going to do something weird for a while. Stage em one time and gm three times (this effectively creates a few copies of gm to be plotted), then call mkplot() with voffset=1.1:

em.stage(); gm.stage(); gm.stage(); gm.stage()
pg.mkplot(voffset=1.1)
pg.show()
../../_images/multiple_1d-6.svg

You will notice that the three gm spectra are separated by quite a bit of white space. This is the expected behaviour: the vertical separation between each plot is defined to be 1.1 times the height of the tallest spectrum (which in this case is em).

In many cases this is OK, but in some situations this may not be desirable. However, in some situations this may not be desirable. What we can do is to separate each spectrum by its own height, thus ensuring that there isn’t any excessive whitespace. penguins lets you do this quickly using the stacked argument:

em.stage(); gm.stage(); gm.stage(); gm.stage()
pg.mkplot(stacked=True)
pg.show()
../../_images/multiple_1d-7.svg

Which you use will depend on the scenario as well as your personal taste.