File size: 4,395 Bytes
21848e9
88a0677
21848e9
 
 
 
 
 
 
 
88a0677
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169b2fd
74f19b4
 
4f6789c
 
 
 
 
 
 
 
 
88a0677
4f6789c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74f19b4
 
c72cfef
21848e9
c72cfef
88a0677
 
 
 
 
 
 
c72cfef
 
80f08b9
c72cfef
21848e9
74f19b4
21848e9
 
 
80f08b9
 
 
 
 
 
 
 
 
74f19b4
21848e9
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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

# ⏯ [interactive pipe website](https://balthazarneveu.github.io/interactive_pipe/)

![](https://balthazarneveu.github.io/interactive_pipe/static/interact-pipe-logo-horizontal-rgb.svg)


# Full tutorial

**Note** : The same tutorial is also available on [Google Colab](https://colab.research.google.com/github/livalgo/interactive-pipe-examples/blob/main/interactive_pipe_tutorial.ipynb) to learn about the Jupyter notebook backend.

# Analyzing the headless pipeline

```python
headless_tutorial_pipeline = interactive_pipeline(gui=None)(tutorial_pipeline)
# gui=None allows retuning a HeadlessPipeline instance.
headless_tutorial_pipeline.graph_representation("__tuto_pipeline")
```
Let's now call the pipeline several times with varying parameters.

🎁 We provide a basic code sample to generate the gif animation.

```python
from PIL import Image as PILImage
img_list = []
for freq in np.linspace(1, 100, 10):
    # Let's first override some of the default parameters.
    headless_tutorial_pipeline.parameters = {
        "gen_color": {"frequency": freq, 'isotropy': freq/100.},
        "compare_by_splitting": {"ratio": freq/100.}}
    # Let's execute
    headless_tutorial_pipeline()
    img = (255.*headless_tutorial_pipeline.results[1][1]).astype(np.uint8)
    img_list.append(PILImage.fromarray(img))

img_list[0].save("animation.gif", save_all=True, append_images=img_list[1:], duration=1, loop=1000)
```

![animation](https://huggingface.co/spaces/balthou/interactive-pipe-tutorial/resolve/main/animation.gif)

# Advice


## Keep separation between "production code" (library / not interactive) & interactivity
- πŸ’‘ One of the strength of interactive pipe is to avoid adding hundreds of lines of code dedicated to GUI (graphical user interfaces). 
- With interactive pipe, you have the choice to keep this design choice. Each processing block can be defined as a regular function, without even importing the `interactive` decorator. In a separate file, you'll add sliders.

### Several ways to decorate building blocks


#### 1.Decorate afterward   πŸ† *= Recommended approach*
- βž– Less elegant to read (`add_interactivity` may be in a different file)
- βž• The decorated function can be re-used somewhere else (before being decorated).
- βž• Possibility to add conditions (`debug` flag)
 
```python
def gen_color(frequency=0, isotropy=0.):
    ...


def add_interactivity(debug=True):
    interactive(
        frequency=(80, [1, 100]),
        isotropy=(0.8, [0.1, 1.]) if debug else 0.8
    )(gen_color)
```


#### 2.Decorate using `@`


```python
@interactive(
    frequency=(80, [1, 100]),
    isotropy=(0.8, [0.1, 1.])
)
def gen_color(frequency=0, isotropy=0.):
    ...
```
- βž• Easy to read
- βž– The decorated function can't be re-used somewhere else.
- βž– No possibility to add condition to hide/show slider. To hide the slider, you need to comment!


#### 3. Shorter code using `@`

```python
@interactive()
def gen_color(
    frequency=(80, [1, 100]),
    isotropy=(0.8, [0.1, 1.])
):
```

- βž• Shortest code
- βž– The decorated function can't be re-used somewhere else

## Pipeline visualization

Internally, `interactive_pipe` builds an execution graph of the pipeline. 
- If you're using  the `qt` backend, press `G` to build the graph. 
- If you're in a notebook, it's possible to easily plot the graph.
```python
headless_tutorial_pipeline = interactive_pipeline(gui=None)(tutorial_pipeline)
headless_tutorial_pipeline.graph_representation()
```

| pipeline's execution graph |
| :--:| 
| ![Pipeline](https://huggingface.co/spaces/balthou/interactive-pipe-tutorial/resolve/main/pipeline.png) |


## Backend choice



|Backend | πŸš€  `Qt` | 🐒 `Gradio` |
|:---|:---|:---|
| Responsiveness | βž• Very fast | βž– Slower  |
| Shareable | βž– No, only 1 local Qt Window | βž• Share a link with others,  (βž• Optional: standalone hosting on  HF spaces πŸ€— ) |
| Keyboard controls |  βž• Yes | βž– No |
| Full screen |  βž• Yes | βž– No |


| πŸš€  `Qt` | 🐒 `Gradio` |
|:---:|:---:|
| ![QT](https://huggingface.co/spaces/balthou/interactive-pipe-tutorial/resolve/main/pyqt.gif) | ![Gradio](https://huggingface.co/spaces/balthou/interactive-pipe-tutorial/resolve/main/gradio.gif) |


### Matplotlib backend

Please note that there's also a matplotlib `gui="mpl"` backend in case of environments where you really don't have access to Qt or Jupyter notebooks.