Quick Start: Plotting NMR spectra¶
SpinPlots lets you load and plot processed NMR data in just a few lines of code. It currently supports Bruker processed data and DMFit exports (1D and 2D). For raw/unprocessed data or other instrument vendors, see NMRglue.
This tutorial covers Bruker data. For DMFit plotting, see the DMFit Plots tutorial. To learn how to access raw data arrays and build fully custom matplotlib figures, see Working with Spin Objects.
The examples below use 13C,15N-labelled Tyrosine and Glycine spectra.
Plot 1D spectra¶
Here is how to load and plot a simple 1D spectrum of Tyrosine acquired at 9.4T using a MAS rate of 10kHz
SpinPlots uses Matplotlib's default style. To further customize a plot, pass return_fig=True to get the figure and axes objects back, then modify them with standard matplotlib calls. See the Read and Export tutorial for an example.
Customization of 1D spectra¶
The .plot() method accepts many keyword arguments to customize the output. Key options for 1D spectra include:
- Overlay multiple spectra on the same axes
- Labels and colors for each spectrum (supports matplotlib named colors and hex codes)
- Normalization by maximum intensity (
normalize="max") or number of scans (normalize="scans") - Stacking spectra vertically (
stacked=True) - Grid layouts for side-by-side subplots (
grid="1x2") - Frame control (
frame=Trueto show y-axis and spines) - Font and tick customization (
axisfont,axisfontsize,tickfont,tickfontsize,tickspacing) - Save directly to file (
save=True,filename=...,format=...) - Return the matplotlib figure for further editing (
return_fig=True)
The following example demonstrates the most common options:
tyr.plot(
labels=["Tyrosine"], # Set the labels for the spectra
color=["black"], # Set the colors for the spectra
xlim=(200, 0), # Set the x-axis limits
alpha=1, # Set the transparency of the lines (1 for no transparency, 0 for transparent)
linewidth=2, # Set the line width
linestyle="-", # Set the line style (styles, e.g. '--', ':', '-.', etc.)
axisfont="Arial", # Set the font style of the axis labels
axisfontsize=12, # Set the font size of the axis labels
tickfont="Arial", # Set the font style of the tick labels
tickfontsize=10, # Set the font size of the tick labels
tickspacing=20, # Set the spacing between the ticks on X-axis
frame=True, # Set True or False to add or remove frame
save=False, # Set True or False to save the figure
filename="../../data/1D/tyrosine_13C", # Set the path and filename for saving the figure
format="svg",
) # Set the format of the saved figure (e.g. 'png', 'pdf', 'svg', etc.)
plot sets the Y-axis and X-axis labels automatically based on the data loaded.
The Y-axis and X-axis labels can be edited with the yaxislabel and xaxislabel options, as follows :
Normalization¶
For multiple spectra, the plot function supports normalization of data and plot stacking. For this example two 13C NMR datasets of Tyrosine and Glycine are used with different number of scans.
# Use a list of path to read multiple spectra
base_path = "../../data/1D/"
gly_tyr = read_nmr([base_path + "glycine/pdata/1", base_path + "tyrosine/pdata/1"])
gly_tyr.plot(
labels=["Glycine", "Tyrosine"],
color=["orange", "blue"],
xlim=(200, 0),
alpha=1,
linewidth=1,
linestyle="-",
axisfont="Arial",
axisfontsize=12,
tickfont="Arial",
tickfontsize=10,
tickspacing=20,
frame=True,
save=True,
filename="../../data/1D/overlapped",
format="svg",
)
The spectrum can be normalized using the normalize using either max or scans to normalize by the maximum number of the number of scans.
gly_tyr.plot(
labels=["Glycine", "Tyrosine"],
color=["orange", "blue"],
xlim=(200, 0),
alpha=1,
linewidth=1,
linestyle="-",
axisfont="Arial",
axisfontsize=12,
tickfont="Arial",
tickfontsize=10,
tickspacing=20,
normalize="max", # Normalized by maximum point
frame=True,
save=False,
filename="../../data/1D/overlapped",
format="svg",
)
Stacking¶
Multiple spectra can be plotted using the stacked option, as follows :
gly_tyr.plot(
labels=["Glycine", "Tyrosine"],
color=["orange", "blue"],
xlim=(200, 0),
alpha=1,
linewidth=1,
linestyle="-",
axisfont="Arial",
axisfontsize=12,
tickfont="Arial",
tickfontsize=10,
tickspacing=20,
normalize="max",
stacked=True, # Set to True to stack the spectra
frame=True,
save=False,
filename="../../data/1D/stacked",
format="svg",
)
or with more plots
base_path = "../../data/1D/"
gly_tyr_ala_arg = read_nmr(
[
base_path + "glycine/pdata/1",
base_path + "tyrosine/pdata/1",
base_path + "alanine/pdata/1",
base_path + "arginine/pdata/1",
]
)
gly_tyr_ala_arg.plot(
labels=["Glycine", "Tyrosine", "Alanine", "Arginine"],
color=[
"#03045e",
"#023e8a",
"#0077b6",
"#0096c7",
], # Hex color codes is also supported
xlim=(200, 0),
alpha=1,
linewidth=1,
linestyle="-",
axisfont="Arial",
axisfontsize=12,
tickfont="Arial",
tickfontsize=10,
tickspacing=20,
normalize="max",
stacked=True, # Set to True to stack the spectra
frame=True,
save=False,
filename="../../data/1D/stacked",
format="svg",
)
Grid¶
The plot allows the presentation of multiple spectra in a grid style (subplots), by using the option grid='rows x columns.
More complex grid spaces can be created, as follows :
gly_tyr_ala_arg.plot(
grid="2x2", # Set the grid layout '2x2' for 2 rows and 2 columns
labels=["Glycine", "Tyrosine", "Alanine", "Arginine"],
color=[
"#03045e",
"#023e8a",
"#0077b6",
"#0096c7",
], # Hex color codes is also supported
xlim=(200, 0),
normalize=True,
frame=True,
save=False,
filename="../../data/1D/grid",
format="svg",
)
Plot 2D spectra¶
The .plot() method also handles 2D spectra with contour lines and projections. Key options for 2D plots include:
contour_start: the minimum contour level (controls which peaks are visible)contour_num: the number of contour levelscontour_factor: the multiplicative factor between successive contour levelscmap: a matplotlib colormap for the contours (default is black lines)color: solid color(s) for contour lines — use instead ofcmapwhen overlaying spectraproj_color: color(s) for the projection tracesxlim/ylim: axis limits for the direct (F2) and indirect (F1) dimensionsdiagonal: slope of a diagonal reference line (e.g.diagonal=2for DQ-SQ)homonuclear: set toTruewhen both axes correspond to the same nucleuslinewidth_contour/linewidth_proj: line widths for contours and projectionssave,filename,format: save the plot directly to a file
Heteronuclear correlation¶
The following example includes all options currently available in the bruker2d function.
A simple heteronuclear 1H-13C 2D acquired at 9.4T using a MAS rate of 10kHz can be plotted, as follows :
data_het = read_nmr("../../data/2D/43/pdata/1")
data_het.plot(
contour_start=4e10, # Set the starting value for the contour lines
contour_num=12, # Set the number of contour lines
contour_factor=1.5, # Set the factor for the contour lines
cmap="viridis", # Set the colormap for the contour plot. Available colormaps: https://matplotlib.org/stable/users/explain/colors/colormaps.html
xlim=(180, 30), # Set the x-axis limits
ylim=(14, -2), # Set the y-axis limits
linewidth_contour=1, # Set the line width for the contour lines
linewidth_proj=1.5, # Set the line width for the projection lines
axisfont="Arial", # Set the font style of the axis labels
axisfontsize=12, # Set the font size of the axis labels
tickfont="Arial", # Set the font style of the tick labels
tickfontsize=10, # Set the font size of the tick labels
tickspacing=20, # Set the spacing between the ticks on X-axis
save=False, # Set True or False to save the figure
filename="../../data/2D/2d_hetero", # Set the path and filename for saving the figure
format="png", # Set the format of the saved figure (e.g. 'png', 'pdf', 'svg', etc.)
)
Homonuclear correlation¶
Some NMR spectra, like double-quantum (DQ) experiments, are often visualized with a diagonal line representing y=2x. You can add this diagonal line for any line of the form y=nx using the keyword diagonal=n, where n sets the desired quantum order. The following example shows a 13C-13C DQ-SQ experiment. The option homonuclear=True is only needed if the y-axis label isn't displaying correctly, such as when the DQ-SQ is acquired through CPMAS.
Similarly, a simple homonuclear 13C-13C 2D can be plotted, as follows :
data_homo = read_nmr("../../data/2D/16/pdata/1")
data_homo.plot(
contour_start=1e7,
contour_num=25,
contour_factor=1.5,
cmap="viridis",
xlim=(200, 30),
ylim=(400, 60),
linewidth_contour=1,
linewidth_proj=1.5,
axisfont="Arial",
axisfontsize=12,
tickfont="Arial",
tickfontsize=10,
tickspacing=20,
homonuclear=True, # Set to true if spectra is a homonuclear correlation
diagonal=2, # Set the diagonal slope: 2 for DQ (y=2x)
save=False,
filename="../../data/2D/2d_homo",
format="png",
)
bruker2d function sets the Y-axis and X-axis labels automatically based on the data loaded, but you can edit them with the yaxislabel and xaxislabel options, as follows :
data_homo.plot(
contour_start=1e7,
contour_num=25,
contour_factor=1.5,
cmap="viridis",
xlim=(200, 30),
ylim=(400, 60),
linewidth_contour=1,
linewidth_proj=1.5,
axisfont="Arial",
axisfontsize=12,
tickfont="Arial",
tickfontsize=10,
xtickspacing=20, # Set space between ticks in x-axis
ytickspacing=50, # Set space between ticks in y-axis
homonuclear=True,
diagonal=2,
xaxislabel="SQ $^{13}$C (ppm)", # Set the label for the x-axis
yaxislabel="DQ $^{13}$C (ppm)", # Set the label for the y-axis
save=False,
filename="../../data/2D/2d_homo",
format="png",
)