# Plotting 1-D data#

scipp offers a number of different ways to plot data from a DataArray or a Dataset. It uses the matplotlib graphing library to do so.

[1]:

import numpy as np
import scipp as sc


## Basic plot#

Plotting is done using the plot function. Generally the information in a dataset is sufficient to produce a useful plot out of the box.

For example, a simple plot from a 1D dataset is produced as follows:

[2]:

d = sc.Dataset()
N = 50
d['Signal'] = sc.Variable(dims=['tof'], values=5.0 + 5.0*np.sin(np.arange(N, dtype=float)/5.0),
unit=sc.units.counts)
d.coords['tof'] = sc.Variable(dims=['tof'], values=np.arange(N).astype(float),
unit=sc.units.us)
sc.plot(d)


## With error bars#

Error bars are shown automatically if variances are present in the data:

[3]:

d['Signal'].variances = np.square(np.random.random(N))
sc.plot(d)


Note that the length of the errors bars is the standard-deviation, i.e., the square root of the variances stored in the data.

## Multiple variables on the same axes#

### Plotting a Dataset with multiple entries#

If a dataset contains more than one 1D variable with the same coordinates, they are plotted on the same axes:

[4]:

d['Background'] = sc.Variable(dims=['tof'], values=3.0*np.random.random(N),
unit=sc.units.counts)
sc.plot(d)


It is possible to hide the error bars with

[5]:

sc.plot(d, errorbars=False)


We can always plot just a single item of the dataset.

[6]:

sc.plot(d['Background'])


### Overplotting using a dict of DataArrays#

One can also supply the plot function with a dict of data arrays. Compatible data arrays will be overplotted on the same axes:

[7]:

sc.plot({"My sample": d['Signal'], "My background": d["Background"]})


Note that the newly supplied names (keys) have also been adopted as the graph names.

We can also overplot sections of interest with the help of slicing.

[8]:

sc.plot({"My sample": d['Signal']['tof', 10:40], "My background": d["Background"]})


This overplotting is useful for plotting slices of a 2D data array:

[9]:

M = 100
L = 5
xx = np.arange(M, dtype=float)
yy = np.arange(L, dtype=float)
x, y = np.meshgrid(xx, yy)
b = M/20.0
c = M/5.0
e = L/10.0
r = np.sqrt(((x-c)/b)**2 + (y/e)**2)
a = np.sin(r)
d2d = sc.DataArray(data=sc.Variable(dims=['y', 'x'], values=a, unit=sc.units.counts))
d2d.coords['x'] = sc.Variable(dims=['x'], values=xx, unit=sc.units.m)
d2d.coords['y'] = sc.Variable(dims=['y'], values=yy, unit=sc.units.m)
sc.plot({f'slice-{i}': d2d['y', i] for i in range(L)})


Or using the collapse helper function, which returns a dict of data arrays:

[10]:

sc.plot(sc.collapse(d2d, keep='x'))


## Customizing linestyles, markers and colors#

Linestyles can be customized following the Matplotlib syntax. For instance, it is possible to connect the dots by setting linestyle='solid':

[11]:

sc.plot(d, linestyle='solid')


Marker colors and symbols can be changed via the color and marker keyword arguments:

[12]:

sc.plot(d, color=['red', '#30D5F9'], marker=['s', 'x'])


The supplied color and marker arguments can also be a list of integers, which correspond to one of the pre-defined colors or markers (which were taken from matplotlib). In addition, the grid can also be displayed:

[13]:

sc.plot(d, color=[6, 8], grid=True)


## Logarithmic scales#

Use the keyword arguments scale and norm to apply logarithmic scales to the horizontal and vertical axes, respectively.

[14]:

sc.plot(d, norm='log', scale={'tof': 'log'})


## Histograms#

Histograms are automatically generated if the coordinate is bin edges:

[15]:

histogram = sc.DataArray(data=sc.Variable(dims=['tof'],
values=20.0 + 20.0*np.cos(np.arange(N-1, dtype=float) / 3.0),
unit=sc.units.counts),
coords={'tof':d.coords['tof']})
sc.plot(histogram)


and with error bars

[16]:

histogram.variances = 5.0*np.random.random(N-1)
sc.plot(histogram)


The histogram color can be customized:

[17]:

sc.plot(histogram, color='#000000')


## Multiple 1D variables with different dimensions#

scipp.plot also supports multiple 1-D variables with different dimensions (note that the data entries are grouped onto the same graph if they have the same dimension and unit):

[18]:

M = 60
d['OtherSample'] = sc.Variable(dims=['x'], values=10.0*np.random.rand(M),
unit=sc.units.s)
d['OtherNoise'] = sc.Variable(dims=['x'], values=7.0*np.random.rand(M),
variances=3.0*np.random.rand(M),
unit=sc.units.s)
d['SomeKgs'] = sc.Variable(dims=['x'], values=20.0*np.random.rand(M),
unit=sc.units.kg)
d.coords['x'] = sc.Variable(dims=['x'],
values=np.arange(M).astype(float),
unit=sc.units.m)
sc.plot(d)


## Custom labels along x axis#

Sometimes one wishes to have labels along the x axis instead of the dimension-coordinate. This can be achieved via the labels keyword argument by specifying which dimension should run along the x axis:

[19]:

d1 = sc.Dataset()
N = 100
x = np.arange(N, dtype=float)
d1['Sample'] = sc.Variable(dims=['tof'],
values=np.sqrt(x),
unit=sc.units.counts)
d1.coords['tof'] = sc.Variable(dims=['tof'],
values=x,
unit=sc.units.us)
d1.coords['somelabels'] = sc.Variable(dims=['tof'],
values=np.linspace(101., 105., N),
unit=sc.units.s)
sc.plot(d1, labels={'tof': 'somelabels'})


If a dataset item contains masks, the symbols of masks data points will have a thick black contour in a 1D plot:

[20]:

d4 = sc.Dataset()
N = 50
x = np.arange(N).astype(float)
d4['Sample'] = sc.Variable(dims=['tof'], values=3*np.sin(x/5)+3,
unit=sc.units.counts)
d4['Background'] = sc.Variable(dims=['tof'], values=1.0*np.random.rand(N),
unit=sc.units.counts)
d4.coords['tof'] = sc.Variable(dims=['tof'], values=x,
unit=sc.units.us)
values=np.where(np.abs(x-40) < 10, True, False))
sc.plot(d4)


Checkboxes below the plot can be used to hide/show the individual masks. A global toggle button is also available to hide/show all masks in one go.

The color of the masks can be changed as follows:

[21]:

sc.plot(d4, masks={'color': 'red'})


Masks on a histogram show up as a thick black line:

[22]:

N = 50
x = np.arange(N+1).astype(float)
d4 = sc.DataArray(data=sc.Variable(dims=['tof'], values=3*np.sin(x[:-1]/5)+3, unit=sc.units.counts))
d4.coords['tof'] = sc.Variable(dims=['tof'], values=x, unit=sc.units.us)
sc.plot(d4)


## Plotting time series#

When plotting data with time-series (dtype=datetime64) coordinates, a special axis tick label formatting, which dynamically adapts to the zoom level, is used.

[23]:

time = sc.array(dims=['time'], values=np.arange(np.datetime64('2017-01-01T12:00:00'),
np.datetime64('2017-01-01T13:00:00'), 20))
N = time.sizes['time']
data = sc.DataArray(data=sc.array(dims=['time'],
values=np.arange(N) + 50.*np.random.random(N),
unit="K"),
coords={'time':time})
data.plot(title="Temperature as a function of time")


## Saving figures#

Static pdf or png copies of the figures can be saved to file (note that any buttons displayed under a figure are not saved to file). This is achieved as follows:

[24]:

sc.plot(d4, filename='my_1d_figure.pdf')