diff --git a/gradio-example.py b/gradio-example.py
new file mode 100644
index 0000000000000000000000000000000000000000..79bf747c9361966e08b5242c8538127d63290b40
--- /dev/null
+++ b/gradio-example.py
@@ -0,0 +1,55 @@
+# %% Imports
+import gradio as gr
+import numpy as np
+import pandas as pd
+import socket
+
+# %% Plotting Function
+def make_sine_wave(a=1, offset=0, f=3, phi=0):
+    t = np.linspace(0, 2, 200)
+    y = a * np.sin(2 * np.pi * f * t + phi) + offset
+
+    return pd.DataFrame({'t': t, 'y': y})
+
+# %% Interface Layout
+with gr.Blocks() as demo:
+    with gr.Row(equal_height=True):
+        with gr.Column(scale=1, min_width=200):
+            amp = gr.Slider(minimum=-5, maximum=5, step=0.1, value=1, label="Amplitude")
+            offset = gr.Slider(minimum=-5, maximum=5, step=0.1, value=0, label="Offset")
+            freq = gr.Slider(minimum=-5, maximum=5, step=0.01, value=1, label="Frequency")
+            phase = gr.Slider(minimum=-3.1416, maximum=3.1416, step=0.1, value=0, label="Phase")
+
+        # should work, but does not:
+        # plot = gr.LinePlot(make_sine_wave, inputs=[amp, offset, freq, phase], x='t', y='y', title='Sine Wave')
+        # as alternative initialize plot and trigger updates using gr.on:
+        plot = gr.LinePlot(make_sine_wave(), x='t', y='y', title='Sine Wave')
+
+    gr.on(
+        triggers=[amp.change, offset.change, freq.change, phase.change, demo.load],
+        fn=make_sine_wave,
+        inputs=[amp, offset, freq, phase],
+        outputs=plot,
+    )
+
+# %% Start Gradio App
+## JupyterHub or anywhere else, public link, max. 72 h
+# demo.launch(share=True)
+
+## JupyterHub, proxy link
+user = socket.gethostname().removeprefix('jupyter-')
+port = 7860
+print(f'Run this in (non-interactive) terminal. Stop server with Ctrl+C. Then you can reuse the same port.\nAccess WebGUI server on https://jupyter.hs-bochum.de/user/{user}/proxy/{port}/')
+demo.launch(server_port=port, root_path=f'/user/{user}/proxy/{port}/', quiet=True)
+
+## local network, allow access via network IP
+# s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+# s.connect(("8.8.8.8", 80))
+# my_ip = s.getsockname()[0]
+# s.close()
+# port = 7860
+# print(f'Run this in (non-interactive) terminal. Stop server with Ctrl+C. Then you can reuse the same port.\nAccess WebGUI server on https://{my_ip}:7860')
+# demo.launch(server_name='0.0.0.0', server_port=port, quiet=True)
+
+## local computer, access only allowed from the computer itself, works also in VS Code's interactive window
+# demo.launch()
diff --git a/gradio.md b/gradio.md
new file mode 100644
index 0000000000000000000000000000000000000000..e928f2e397d147ebecb38b4f0b4049312e13596b
--- /dev/null
+++ b/gradio.md
@@ -0,0 +1,97 @@
+# How to launch gradio apps?
+
+As an example gradio app, we use as base:
+``` python
+# %% Imports
+import gradio as gr
+import numpy as np
+import pandas as pd
+import socket
+
+# %% Plotting Function
+def make_sine_wave(a=1, offset=0, f=3, phi=0):
+    t = np.linspace(0, 2, 200)
+    y = a * np.sin(2 * np.pi * f * t + phi) + offset
+
+    return pd.DataFrame({'t': t, 'y': y})
+
+# %% Interface Layout
+with gr.Blocks() as demo:
+    with gr.Row(equal_height=True):
+        with gr.Column(scale=1, min_width=200):
+            amp = gr.Slider(minimum=-5, maximum=5, step=0.1, value=1, label="Amplitude")
+            offset = gr.Slider(minimum=-5, maximum=5, step=0.1, value=0, label="Offset")
+            freq = gr.Slider(minimum=-5, maximum=5, step=0.01, value=1, label="Frequency")
+            phase = gr.Slider(minimum=-3.1416, maximum=3.1416, step=0.1, value=0, label="Phase")
+
+        # should work, but does not:
+        # plot = gr.LinePlot(make_sine_wave, inputs=[amp, offset, freq, phase], x='t', y='y', title='Sine Wave')
+        # as alternative initialize plot and trigger updates using gr.on:
+        plot = gr.LinePlot(make_sine_wave(), x='t', y='y', title='Sine Wave')
+
+    gr.on(
+        triggers=[amp.change, offset.change, freq.change, phase.change, demo.load],
+        fn=make_sine_wave,
+        inputs=[amp, offset, freq, phase],
+        outputs=plot,
+    )
+```
+
+Now, what is missing is the `demo.launch()` part. And this is, what this small tutorial is about. For different situations you need different arguments. The order of the situations is from low access to shared access. So prefer the first method that fits for you.
+
+Find the full code for download [here](gradio-example.py).
+
+## Localhost
+
+If you are working on a local python installation (not JupyterHub) and want to restrict access to this very machine, just call
+
+``` python
+demo.launch()
+```
+
+Gradio can also show in VS Code's interactive window. So you can call this in interactive mode or maybe even from Jupyter Notebooks. Or just open http://localhost:7860.
+
+## Network link
+
+If you are working on a local python installation (not JupyterHub) and want to allow access to the gradio server from other computers in the local network, use `server_name='0.0.0.0'. For a friendly output, we also look for the IP address of the default route.
+
+``` python
+import socket
+
+s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+s.connect(("8.8.8.8", 80))
+my_ip = s.getsockname()[0]
+s.close()
+port = 7860
+print('Run this in (non-interactive) terminal. Stop server with Ctrl+C. Then you can reuse the same port.')
+print(f'Access WebGUI server on http://{my_ip}:7860')
+demo.launch(server_name='0.0.0.0', server_port=port, quiet=True)
+```
+
+Then just open the displayed link in a browser.
+
+## Proxy Link
+
+If you run the app on a JupyterHub with the Jupyter Server Proxy is enabled, like on [our JupyterHub](https://jupyter.hs-bochum.de), you can use the following code and execute your script in a terminal.
+
+``` python
+import socket
+
+user = socket.gethostname().removeprefix('jupyter-')
+port = 7860
+print('Run this in (non-interactive) terminal. Stop server with Ctrl+C. Then you can reuse the same port.')
+print(f'Access WebGUI server on https://jupyter.hs-bochum.de/user/{user}/proxy/{port}/')
+demo.launch(server_port=port, root_path=f'/user/{user}/proxy/{port}/', quiet=True)
+```
+
+Then just open the displayed link in a browser.
+
+## Public Shared Link
+
+If you run the app anywhere, like on Kaggle, Google Colab or any other JupyterHub, you can always make a public shared link. It will last for max. 72 h.
+
+``` python
+demo.launch(share=True, height=800)
+```
+
+This will use gradio's service to make a public link tunneling to the gradio server.