flint_data_plotting.md 7.34 KB
Newer Older
1
2
3

# Flint Data Plotting

4
5
6
7
During a BLISS session, users may create data (other than scan data) that needs
to be displayed graphically. Flint offers a collection of different type of
plots (curve, scatter, image...) so user can select the one that best fits
with the data to be displayed.
8

9
## Basic plot display
10

11
A generic display is provided through the BLISS `plot` command.
12

13
This the data dimensionality to select and display a plot.
14

15
This can be convenient for basic display.
16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
![Screenshot](img/plot_1d_cosinus.png)

```python
# Display a list (as a single curve using index as x-axis)
plot([1, 2, 3, 1, 2, 3])

import numpy

# Display a 1D data (as a single curve using index as x-axis)
array = numpy.array([1, 2, 3, 1, 2, 3])
plot(array)

# Display a 2D data (as an image)
image = numpy.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
plot(image)

# Display a 3D data (as a stack of images)
cube = numpy.arange(1000)
cube.shape = 10, 10, 10
plot(cube)
```

## Create a plot

To use more features another way is provided.

First a plot have to be created from the Flint.

The first argument (here `curve`) is used to select the kind of expected plot.
See the following documentation for example for each kind.

```python
f = flint()
p = f.get_plot("curve")
```

Other arguments are available to edit some behavior of this plot.

A title can be specified, a unique name can be set to reuse plots instead of
creating a new one. The plot can be closeable (default is true) or selected
by default at the creation (default is false).

```python
p = f.get_plot("curve",
               name="My plot title",
               unique_name="myplot42",
               closeable=True,
               selected=True)
```

## 1D plot / curve plot

The main plot is a curve plot.

It can be used to display several 1D data as curves.
72

Valentin Valls's avatar
Valentin Valls committed
73
74
75
```python
import numpy

76
77
78
79
80
# Create the plot
f = flint()
p = f.get_plot("curve", name="My plot")

# Create data
Valentin Valls's avatar
Valentin Valls committed
81
t = numpy.linspace(0, 10 * numpy.pi, 100)
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
s = numpy.sin(t)
c = numpy.cos(t)

# Update the plot
p.add_curve(t, c, legend="aaa")  # the legend have to be unique
p.add_curve(t, s, legend="bbb")

# Clean up the plot
p.clean_data()
```

This also can be used to display parametric functions

```python
import numpy
Valentin Valls's avatar
Valentin Valls committed
97
98
99
100

t = numpy.linspace(-3, 3, 50)
x = 16 * numpy.sin(t)**3
y = 13 * numpy.cos(t) - 5 * numpy.cos(2*t) - 2 * numpy.cos(3*t) - numpy.cos(4*t)
101
102
103
104

f = flint()
p = f.get_plot("curve", name="My heart")
p.add_curve(x, y, legend="heart")
Valentin Valls's avatar
Valentin Valls committed
105
106
```

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
## Scatter plot

A 2D scatter plot is provided.

A scatter is a group of of three 1D data of the same length. Each of them
respectively contains x-locations, y-locations and values.

The widget provides different visualization mode to display the data as points,
or with a solid rendering, including 2D histogram rendering.

```python
import numpy

# Create the plot
f = flint()
p = f.get_plot("scatter", name="My plot")

# Create the data and setup the plot
y, x = numpy.ogrid[:10, :10]
x, y = numpy.zeros_like(y) + x, numpy.zeros_like(x) + y
x, y = x.flatten(), y.flatten()
v = numpy.sin(numpy.sqrt((x-5)**2 + (y-5)**2))
p.set_data(x, y, v)

# The colormap can be updated
p.set_colormap(lut="red")
```
134

135
![Screenshot](img/custom-plot-scatter-view.png)
136

137
## Image plot
138

139
A plot is provided to display a specific image.
140

141
142
It provides a dedicated view to display a single image, with tools
to provides vertical and horizontal histograms.
143

144
145
```python
import numpy
146

147
148
149
# Create the plot
f = flint()
p = f.get_plot("image", name="My plot")
150

151
152
153
154
# Create the data and setup the plot
y, x = numpy.ogrid[:10, :10]
image = numpy.sin(numpy.sqrt((x-5)**2 + (y-5)**2))
p.set_data(image)
155

156
157
158
# The colormap can be updated
p.set_colormap(lut="red")
```
159

160
![Screenshot](img/custom-plot-image-view.png)
Valentin Valls's avatar
Valentin Valls committed
161

162
## 2D plot
Valentin Valls's avatar
Valentin Valls committed
163

164
165
Another 2D plot is provided to allow to compose a view with many images.
It provides less tools than the dedicated image plot.
Valentin Valls's avatar
Valentin Valls committed
166
167

```python
168
169
170
import numpy

# Create the plot
Valentin Valls's avatar
Valentin Valls committed
171
f = flint()
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
p = f.get_plot("plot2d", name="My plot")

# Create the data and setup the plot
y, x = numpy.ogrid[:10, :10]
image1 = numpy.sin(numpy.sqrt((x-5)**2 + (y-5)**2))
image2 = numpy.cos(numpy.sqrt((x-5)**2 + (y-5)**2))
p.add_image(image1, origin=(0, 0), scale=(0.5, 0.5), legend="img1")  # legend have to be unique
p.add_image(image2, origin=(5, 0), scale=(0.5, 0.5), legend="img2")

# Clean up the plot
p.clean_data()
```

![Screenshot](img/custom-plot-plot2d.png)

## Curve stack

This plot displays a single curve from a selectable list of curves.

The data have to be provided as a 2D array. The slow axis is used as the axis
of the curve.

The selection is done with a slider.

```python
import numpy
Valentin Valls's avatar
Valentin Valls committed
198

199
200
201
# Create the plot
f = flint()
p = f.get_plot(plot_class="curvestack", name="My curve stack")
Valentin Valls's avatar
Valentin Valls committed
202

203
# Create the data and setup the plot
Valentin Valls's avatar
Valentin Valls committed
204
205
206
207
208
209
210
211
212
curves = numpy.empty((10, 100))
for i in range(10):
    curves[i] = numpy.sin(numpy.arange(100) / 30 + i * 6)
x = numpy.arange(100) * 10
p.set_data(curves=curves, x=x)
```

![Screenshot](img/custom-plot-curve-stack.png)

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
## Image stack

This plot displays a single image from a stack of image.

The data have to be provided as a 3D array. The 2 first slow axis are used as
the image axes.

A slider is provided to browse the images.

```python
import numpy

# Create the plot
f = flint()
p = f.get_plot(plot_class="stackview", name="My image stack")
228

229
230
231
232
233
# Create the data and setup the plot
cube = numpy.arange(10 * 10 * 10)
cube.shape = 10, 10, 10
cube = numpy.sin(cube)
p.set_data(cube)
234

235
236
237
# The colormap can be updated
p.set_colormap(lut="red")
```
238

239
![Screenshot](img/custom-plot-stack-view.png)
240

Valentin Valls's avatar
Valentin Valls committed
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
## Time curve plot

![Screenshot](img/custom-plot-time-curve-plot.png)

A dedicated plot is provided to display curve data with time as x-axis.

It's the plot used by the regulation framework.

This is useful to simplify the display of a fixed period of time
(the last x seconds), and to update the data using the new known
data only.

The GUI allow the user to change the last displayed period of time displayed.

```python
# Create the plot
257
258
f = flint()
p = f.get_plot(plot_class="timecurveplot", name="My plot")
Valentin Valls's avatar
Valentin Valls committed
259
260
261
262

# Setup the plot to display a dedicated data name
# The data will be provided later
# the `time` data name is used as x-axis
263
p.add_time_curve_item("diode1")
Valentin Valls's avatar
Valentin Valls committed
264
# The curve style can be specified
265
p.add_time_curve_item("diode2", color="red")
Valentin Valls's avatar
Valentin Valls committed
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

# The data can be set
# The time have to be provided in epoch second UTC (see python API `time.time()`)
p.set_data(time=[0, 1, 2], diode1=[0, 1, 1], diode2=[1, 5, 1])

# The data also can be appended
p.append_data(time=[3], diode1=[2], diode2=[6])

# Old data is dropped automatically
# This can be setup programatically
p.select_x_duration(second=5)

# And data can be cleared
p.clear_data()
```

282
## Extra commands
283

284
Plots provide few extra commands.
285
286

```python
287
# Create a plot
288
f = flint()
289
p = f.get_plot(plot_class="plot1d", name="My plot")
290
```
291

292
The plot life cycle can be checked and changed with this commands:
293
```python
294
295
if p.is_open():
    p.close()
296
297
```

298
Set the focus on a specific plot can be set the following way:
299
```python
300
p.focus()
301
302
```

303
A plot can be exported to the logbook this way:
304
```python
305
p.export_to_logbook()
306
307
```

308
## From scripts
309

310
From a scripts Flint also can be used to display plot.
311

312
The `plot` command can be imported the following way:
313
314

```python
315
from bliss.common.plot import plot
316

317
plot([1, 2, 3, 4, 5, 6])
318
319
```

320
Flint and it's plot API can be imported the followng way:
321
322

```python
323
from bliss.common.plot import get_flint
324

325
326
f = get_flint()
p = f.get_plot("plot1d", name="My plot")
327
```