diff --git a/pages/images/jupyterlab_dashboard.png b/pages/images/jupyterlab_dashboard.png
index 190a3dc2..4c19aa6f 100644
Binary files a/pages/images/jupyterlab_dashboard.png and b/pages/images/jupyterlab_dashboard.png differ
diff --git a/pages/jupyter.qmd b/pages/jupyter.qmd
index b56a8424..3c7068d3 100644
--- a/pages/jupyter.qmd
+++ b/pages/jupyter.qmd
@@ -55,23 +55,15 @@ haven't done so already. Then open up a terminal and go to
## The basics
-One thing that sets Jupyter Notebook apart from what you might be used to is
-that it's a web application, _i.e._ you edit and run your code from your
-browser. But first you have to start the Jupyter Notebook server. At this
-point you may either try the classic notebook interface by running:
-
-```bash
-jupyter notebook --allow-root
-```
-
-Or give the more feature-rich Jupyter lab interface a try by running:
+One thing that sets Jupyter apart from what you might be used to is that it's a
+web application, _i.e._ you edit and run your code from your browser. But first
+you have to start the Jupyter server. Do this by running:
```bash
jupyter lab --allow-root
```
-Whichever interface you choose you should see something similar to this
-printed to your terminal:
+You should see something similar to this printed to your terminal:
```no-highlight
[I 18:02:26.722 NotebookApp] Serving notebooks from local directory: /Users/john/workshop-reproducible-research/tutorials/jupyter
@@ -90,68 +82,45 @@ printed to your terminal:
::: {.callout-tip title="A note for Windows users"}
If you see the error message `Start : This command cannot be run due to the
error: The system cannot find the file specified. ...` then try starting
-Jupyter with `jupyter notebook --no-browser` then copy the URL given into the
+Jupyter with `jupyter lab --no-browser` then copy the URL given into the
browser directly.
:::
-::: {.callout-note title="Jupyter notebook versions"}
-Depending on what version of the `notebook` conda package you have installed,
-the interface may look slightly different. The screenshots in this tutorial
-are from version 7, an update which has brought the 'classic' Jupyter notebook
-closer to the Jupyter lab interface. Read more about this update at the
-[Jupyter homepage](https://jupyter-notebook.readthedocs.io/en/latest/migrate_to_notebook7.html).
-:::
-
-The Jupyter Notebook/Lab interface probably opened up a web browser for you
+The Jupyter Lab interface probably opened up a web browser for you
automatically, otherwise go to the address specified in the message in the
-terminal. Note that the server is running locally (as
-`http://localhost:8888`) so this does not require that you have an active
-internet connection. Also note that it says:
-
-```no-highlight
-Serving notebooks from local directory:
-```
-
-Everything you do in your Notebook session will be stored in this directory, so
-you won't lose any work if you shut down the server.
+terminal under `Or copy and paste one of these URLs:`.
-> ![](images/jupyter_dashboard.png){ width=700px }
-
-What you're looking at is the Notebook dashboard. This is where you manage your
-files, notebooks, and kernels. The Files tab shows the files in your directory.
-The Running tab keeps track of all your processes.
-
-The Jupyter lab dashboard should look something like this:
+What you're looking at is the dashboard which should look something like this:
> ![](images/jupyterlab_dashboard.png){ width=700px }
-Let's start by creating an empty notebook. You can do this by selecting the
-Files tab and clicking New > Notebook. When the notebook opens, select the
-suggested Python 3 kernel from the drop-down menu.
-
-This will open up a new tab or window looking like this:
-
-> ![](images/jupyter_empty_nb.png){ width=700px }
+In the left margin you have a few icons, the first being a folder icon. This is
+the **File browser**, which shows the files in your directory. The next icon is
+the **Running terminals and Kernels** tab, which shows you the running kernels.
+The third icon is the **Table of contents**, which shows the outline of your
+active notebook (if you have one open). This table will be populated with
+headers from your markdown cells. The fourth icon is the **Extensions Manager**
+tab, where you can install and manage extensions.
-Start by giving your notebook a name by clicking on the text "Untitled" at the
-top of the page. Enter "jupyter-tutorial.ipynb".
+The main part of the dashboard is occupied by what's called the **Main work
+area**. This is where you can open and work on notebooks, text files, terminals
+and so on. These are opened in tabs, and you can have several tabs open at the
+same time. These tabs can be moved, resized, and split by dragging them around.
-Note that for most of this tutorial we will describe how you work in the actual
-notebook and not devote a lot of time to the extra features available in the
-Jupyter lab interface.
+Let's start by creating an empty notebook. You can do this by selecting the
+Files tab and clicking New > Notebook. From the drop-down menu that appears,
+select the `jupyter-env` kernel.
-::: {.callout-tip}
-If you want to start Jupyter Notebooks on a cluster that you SSH to (_e.g._
-Uppmax) see the section in the [Extra material](#extra-material).
-:::
+Start by giving your notebook a name by right-clicking on the text "Untitled.ipynb" at the
+top of the tab then clicking "Rename Notebook". Enter `jupyter-tutorial.ipynb`.
-Jupyter notebooks are made up of cells, and you are currently standing in
-the first cell in your notebook. Your cursor should be blinking in this cell,
-indicating that you are in "Edit mode" meaning that you can type text in the
-cell. Pressing the `Esc` key puts you in "Command mode" which allows you to
-manipulate the notebook as a whole, more on this later.
+Jupyter notebooks are made up of cells, and you should have one cell in your
+newly created notebook. Clicking inside the cell puts you in "Edit mode" meaning
+that you can type text in the cell. Pressing the `Esc` key puts you in "Command
+mode" which allows you to manipulate the notebook as a whole, more on this
+later.
-Cells in Jupyter notebooks can be of two types:*markdown* or *code*.
+Cells in Jupyter notebooks can be of two types: *markdown* or *code*.
- **Markdown:**
@@ -185,23 +154,18 @@ the menus. You can also view this list of shortcuts from the **Help** menu under
| `ctrl-enter` | Run the cell |
| `shift-enter` | Run the cell and select the cell below |
| `alt-enter` | Run the cell and insert a new cell below |
-| `s` | Save the notebook |
-| `tab` | For code completion or indentation |
| `m,y` | Toggle between Markdown and Code cells |
| `d-d` | Delete a cell |
| `a` | Insert cells above current cell |
| `b` | Insert cells below current cell |
| `x` | Cut currently selected cells |
| `v` | Paste cell below |
-| `o` | Toggle output of current cell |
## Writing markdown
Let's use our first cell to create a header. Change the format from Code to
-Markdown using the drop-down list in the Notebook Toolbar, or by pressing the
-`m` key when in command mode. Double click on the cell, or hit `enter` to enter
-editing mode and input "# My notebook" ("#" is used in Markdown for header 1).
-Run the cell with `ctrl`-`enter` (`cmd`-`enter` on Mac).
+Markdown by pressing the `m` key when in command mode. Click inside the cell and
+input `# My notebook`. Run the cell with `ctrl`-`enter` (`cmd`-`enter` on Mac).
Markdown is a simple way to structure your notebook into sections with
descriptive notes, lists, links, images etc.
@@ -238,9 +202,10 @@ See [here](https://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/W
## Writing code
-Now let's write some code! Since we chose a Python kernel, Python would be the
-native language to run in a cell. Enter this code in the second cell and run
-it:
+Now let's write some code! Create a new cell either by clicking the `+` in the
+tab menu or by pressing `b` when in command mode. Since we chose a Python
+kernel, Python would be the native language to run in a cell. Enter this code in
+the second cell and run it:
```python
print("Hello world!")
@@ -253,12 +218,13 @@ one run, while you work *in* a Jupyter notebook in a different way. This
requires some special attention when it comes to reproducibility, which we will
get back to in the [reproducibility](#reproducibility) section.
-What **is** a Jupyter notebook? Let's look a closer at the notebook we're
+What **is** a Jupyter notebook? Let's look closer at the notebook we're
currently working in. Jupyter Notebooks are autosaved every minute or so, so you
will already have it available. We can be a little meta and do this from within
the notebook itself, by running some shell commands in a code cell. This very
handy functionality is possible by prepending the command with `!`. Try adding
-`!ls` to a code cell and run it. This will list the files in the current directory.
+`!ls` to a code cell and run it. This will list the files in the current
+directory.
Aha, we have a new file called `jupyter-tutorial.ipynb`! This is our notebook.
Look at the first ten lines of the file by using `!head jupyter-tutorial.ipynb`.
@@ -283,10 +249,6 @@ Now create a new cell and add:
print_me("Hi!")
```
-Your notebook should now look something like this.
-
-> ![](images/jupyter_basic_update.png){ width=700px }
-
The focus of this tutorial is not on how to write Markdown or Python; you can
make really pretty notebooks with Markdown and you can code whatever you want
with Python. Rather, we will focus on the Jupyter Notebook features that allow
@@ -295,6 +257,7 @@ you to do a little more than that.
::: {.callout-note title="Quick recap"}
In this section we've learned:
+- How to open and work with Jupyter lab
- That a Jupyter notebook consists of a series of cells, and that they can
be either markdown or code cells.
- That we execute the code in a code cell with the kernel that we chose
@@ -313,12 +276,13 @@ power of Jupyter notebooks. There are two types of magics:
- **Cell magics**: Commands that start with `%%` and then apply to the whole
cell. Must be written on the first line of a cell.
-Now list all available magics with `%lsmagic` (which itself is a magic). You
-add a question mark to a magic to show the help (_e.g._ `%lsmagic?`). Some of
-them act as shortcuts for commonly used shell commands (`%ls`, `%cp`, `%cat`,
-..). Others are useful for debugging and optimizing your code (`%timeit`,
-`%debug`, `%prun`, ..). For more information see the
-[magics documentation](https://ipython.readthedocs.io/en/stable/interactive/magics.html).
+Now list all available magics with by adding `%lsmagic` (which itself is a
+magic) to a cell and running it. You can add a question mark to a magic to show
+the help (_e.g._ `%lsmagic?`). Some of them act as shortcuts for commonly used
+shell commands (`%ls`, `%cp`, `%cat`, ..). Others are useful for debugging and
+optimizing your code (`%timeit`, `%debug`, `%prun`, ..). For more information
+see the [magics
+documentation](https://ipython.readthedocs.io/en/stable/interactive/magics.html).
A very useful magic, in particular when using shell commands a lot in your
work, is `%%capture`. This will capture the stdout/stderr of any code cell and
@@ -340,8 +304,11 @@ print("stdout:" + output.stdout)
print("stderr:" + output.stderr)
```
-> **Tip**
-> You can capture the output of some magics directly like this: `my_dir = %pwd`.
+::: {.callout-tip}
+
+You can capture the output of some magics directly like this: `my_dir = %pwd`.
+
+:::
The `%%script` magic is used for specifying a program (Bash, Perl, Ruby, ..)
with which to run the code (similar to a shebang). For some languages it's
@@ -361,10 +328,19 @@ environment you're using for this tutorial. However, you also have to load it
by running `%load_ext rpy2.ipython` in a cell.
:::
-Try this out if you know any of the languages above. Otherwise you can always
-try to print the quadratic formula with LaTeX!
+Try this out if you know any of the languages above. For example, to run some
+simple R code:
+
+```
+%%R
+print(paste("Hello","world", sep=" "))
+```
+
+
+Or to print the quadratic formula with LaTeX:
```no-highlight
+%%latex
\begin{array}{*{20}c} {x = \frac{{ - b \pm \sqrt {b^2 - 4ac} }}{{2a}}} & {{\rm{when}}} & {ax^2 + bx + c = 0} \\ \end{array}
```
@@ -398,7 +374,7 @@ magics
An essential feature of Jupyter Notebooks is of course the ability to visualize
data and results via plots. A full guide to plotting in Python is beyond the
-scope of this course, but will offer a few glimpses into the plotting landscape
+scope of this course, but we will offer a few glimpses into the plotting landscape
of Python.
First of all, Python has a library for plotting called
@@ -419,8 +395,8 @@ line, = plt.plot(x, y, color='red', linestyle="-")
```
By default plots are rendered in the notebook as rasterised images which can
-make the quality poor. To render in scalable vector graphics format use the
-`set_matplotlib_formats` from the matplotlib_inline package:
+make the quality poor. To render in scalable vector graphics format add the
+following to a cell and run it:
```python
import matplotlib_inline
@@ -745,13 +721,11 @@ While an in-depth listing of available extensions is well beyond the scope
of this tutorial we offer this list of a few extensions that are of particular
relevance to this course:
-- [Jupyterlab/GitHub](https://github.com/jupyterlab/jupyterlab-github) -
+- [jupyterlab-quarto](https://github.com/quarto-dev/jupyterlab-quarto)
+- [jupyterlab-github](https://github.com/jupyterlab/jupyterlab-github) -
view and open files from GitHub
-- [Jupyterlab/Git](https://github.com/jupyterlab/jupyterlab-git) - version
+- [jupyterlab-git](https://github.com/jupyterlab/jupyterlab-git) - version
controlling with git
-- [mamba-org/gator-lab](https://github.com/mamba-org/gator) - manage Conda
- environments
-- [voila-dashboards/Jupyterlab-preview](https://github.com/voila-dashboards/voila) - preview a rendered version of your notebook
::: {.callout-note title="Quick recap"}
In this section we've learned:
@@ -762,10 +736,10 @@ In this section we've learned:
## Reproducibility
Now that you have a feeling for what Jupyter can do we'll spend a
-little time on things to consider specifically from a repdroducibility point of
+little time on things to consider specifically from a reproducibility point of
view when it comes to Jupyter notebooks.
-## Version control of Jupyter notebooks
+### Version control of Jupyter notebooks
As we've seen, Jupyter notebooks are plain-text JSON files. This means that they
can be version controlled with Git just like any other text file. However,
@@ -868,7 +842,7 @@ easy to see changes made both to code and outputs such as tables and plots.
diffs](https://code.visualstudio.com/docs/datascience/jupyter-notebooks#_custom-notebook-diffing)
directly from the editor
-## Making sure notebooks work as expected
+### Making sure notebooks work as expected
One of the great things with Jupyter notebooks is the ability to do data
exploration in an interactive way. Because loaded data, defined variables and
@@ -903,8 +877,8 @@ each column grouped by `island` using the following code:
penguins.groupby("island").mean(numeric_only=True)
```
-Run the cell to see the output. Looks good. Now we have a very simple example of
-some exploratory analyses on a dataset.
+Run the cell to see the output. Now we have a very simple example of some
+exploratory analyses on a dataset.
Save the notebook and try running `nbval` on it to see if it works as
expected. From the commandline, run:
@@ -967,7 +941,8 @@ fails on `Cell 3` it actually refers to the 4th cell in the notebook.
This problem could have been solved if we had re-run the cell where we output
the mean of each column grouped by `island`. In fact, it is good practice to
re-run all cells in a notebook before saving it. If you in addition restart the
-kernel before re-running you make sure that you haven't introduced any 'hidden states'
+kernel before re-running you make sure that you haven't introduced any 'hidden
+states'.
::: {.callout-tip title="Ignoring specific cells"}
One caveat of `nbval` is that it doesn't work well with cells that generate
@@ -976,9 +951,12 @@ plots. You can tell `nbval` to ignore the output of specific cells by adding
:::
::: {.callout-note title="Quick recap"}
+
In this section we've learned:
+
- How to use `nbdime` to view diffs of Jupyter notebooks
- How to use `nbval` to test that notebooks work as expected
+
:::
## Converting notebooks
@@ -987,46 +965,56 @@ Notebooks can be converted to various output formats such as HTML, PDF, LaTeX
*etc.* directly from the **File** -> **Save and Export Notebook As...** menu.
Conversion can also be performed on the command line using the `jupyter nbconvert`
-command. `nbconvert` is installed together with the `jupyter` Conda
-package and is executed on the command line by running `jupyter nbconvert`.
+command.
The syntax for converting a Jupyter notebook is:
```bash
-jupyter nbconvert --to notebook.ipynb
+jupyter nbconvert --to
```
-Here `` can be any of `asciidoc`, `custom`, `html`, `latex`, `markdown`,
+Here `` is the filename of the notebook you want to convert and
+`` can be any of `asciidoc`, `custom`, `html`, `latex`, `markdown`,
`notebook`, `pdf`, `python`, `rst`, `script`, `slides`. Converting to some
-output formats (_e.g._ PDF) may require you to install separate software such
-as [Pandoc](https://pandoc.org/) or a **TeX** environment.
+output formats (_e.g._ PDF) may require you to install separate software such as
+[Pandoc](https://pandoc.org/) or a **TeX** environment.
+
+You can also specify a different output file with `--output `.
Try converting the `jupyter-tutorial.ipynb` notebook that you have been working
on for this tutorial to HTML using `jupyter nbconvert`.
::: {.callout-tip}
-If the plots in HTML rendered version of your notebook are not displayed
-properly, try changing the `matplotlib_inline.backend_inline.set_matplotlib_formats('pdf', 'svg')`
-line to `matplotlib_inline.backend_inline.set_matplotlib_formats('retina')`.
+
+If the plots in the HTML rendered version of your notebook are not displayed
+properly, try changing the
+`matplotlib_inline.backend_inline.set_matplotlib_formats('pdf', 'svg')` line to
+`matplotlib_inline.backend_inline.set_matplotlib_formats('retina')`.
+
:::
-`nbconvert` can also be used to run a Jupyter notebook from the command line
-by running:
+We can also execute each cell of a notebook from the commandline and convert the
+results using the `--execute` flag, like so:
```bash
-jupyter nbconvert --execute --to notebook.ipynb
+jupyter nbconvert --execute --to
```
-`nbconvert` executes the cells in a notebook, captures the output and saves the
-results in a new file. Try running it on the `jupyter-tutorial.ipynb` notebook.
+When the notebook is executed, nbconvert will use a
+[kernel](https://docs.jupyter.org/en/latest/projects/kernels.html#kernels) to
+run the code and by default the kernel associated with the notebook is used.
+When you start a notebook, the kernel you select is stored in the notebook
+metadata and becomes associated with it. If you want to use a different kernel,
+you can specify it with the flag `--ExecutePreprocessor.kernel_name
+`. To see available kernels you can run `jupyter kernelspec list`.
-You can also specify a different output file with `--output `.
-
-So in order to execute your `jupyter-tutorial.ipynb` notebook and save it to a file
-named `report.html` you could run:
+Let's execute and convert the `jupyter-tutorial.ipynb` notebook to an HTML file
+called `report.html`. The `jupyter-env` kernel is most likely already associated
+with the notebook, but let's be explicit and specify it anyway. Run the
+following command:
```bash
-jupyter nbconvert --to html --output report.html --execute jupyter-tutorial.ipynb
+jupyter nbconvert --to html --output report.html --ExecutePreprocessor.kernel_name jupyter-env --execute jupyter-tutorial.ipynb
```
::: {.callout-note title="Quick recap"}
@@ -1061,32 +1049,44 @@ render the notebook to a high-quality report or manuscript.
To give you an example, take a look at the `supplementary_material.ipynb` file
in the `jupyter/` tutorial directory. Open this notebook in the Jupyter lab
-interface (make sure you have activated the `jupyter-env` Conda environment).
+interface.
As you can see this notebook contains some brief descriptions in Markdown and
-code to generate a few plots. It uses the output from the MRSA case-study
-Snakemake workflow you worked on in the Snakemake tutorial. This is a common
-use-case for Jupyter notebooks; to generate summary statistics and plots from
-the results of a workflow run. (A real-world example could of course include a
-lot more in-depth exploratory analyses).
+code to generate a few plots and tables. It uses the output from the MRSA
+case-study Snakemake workflow you worked on in the Snakemake tutorial. This is a
+common use-case for Jupyter notebooks; to generate summary statistics and plots
+from the results of a workflow run. (A real-world example could of course
+include a lot more in-depth exploratory analyses).
Now, let's say you want to share the results of this notebook with your PI or
-collaborators. We could simply share the notebook file, or as we saw in the
-previous section, convert it to HTML or PDF via `jupybter nbconvert`.
+collaborators. We could simply share the notebook file, or run all cells to
+generate the plots and tables and then convert it to HTML via `jupybter
+nbconvert`.
+
+We'll first use `nbconvert` so we have something to compare with.
-Let's do that first so we have something to compare with. Run the following:
+Run the following from your terminal to execute the cells in the notebook and
+convert it to HTML:
```bash
-jupyter nbconvert --to HTML --output supplementary_material.nbconvert.html supplementary_material.ipynb
+jupyter nbconvert --ExecutePreprocessor.kernel_name=jupyter-env --execute \
+ --to HTML --output supplementary_material.nbconvert.html supplementary_material.ipynb
```
-Open the `supplementary_material.nbconvert.html` file in a browser to see that
-it looks like you expect. This looks more or less like the original notebook.
+If you open the `supplementary_material.nbconvert.html` file in a browser you
+will see it looks more or less like the original notebook.
Now let's go one step further and render the notebook to a high-quality report
-using Quarto. We can actually add a YAML header to the notebook with some
-document options that Quarto understands. Create a new cell in the notebook
-(from the Jupyter lab interface) and move it to the top. In this cell, add the
+using Quarto.
+
+Take a look at the notebook again in the Jupyter lab interface. As you can see
+some of the code cells contain _chunk options_ just like the ones you learned
+about in the Quarto tutorial. These options are ignored when executing the cells
+from within Jupyter lab, but are used by Quarto when rendering the notebook.
+
+We will now use quarto from the commandline to both execute and render the
+notebook. But first we need to add a YAML header to the notebook. Create a new
+cell at the top of the notebook, set it to Markdown format and add the
following:
```yaml
@@ -1100,29 +1100,38 @@ format:
code-tools: true
language:
code-summary: Click to show code
+jupyter: jupyter-env
bibliography: references.bib
---
```
-Set the cell type to `Markdown`, then run the cell. Most likely that cell will
-look rather weird but that's OK. We'll fix that in a bit.
+This YAML header instructs Quarto to:
-Save the notebook and now render the document with Quarto from the commandline:
+- set a title and a subtitle for the document
+- render the document as HTML
+- embed resources such as images in the HTML file
+- enable [code folding](https://quarto.org/docs/output-formats/html-code.html#folding-code) and [code tools](https://quarto.org/docs/output-formats/html-code.html#code-tools)
+- sets the text for folded code to "Click to show code"
+- specifies to use the `jupyter-env` kernel for executing the notebook
+- sets the `references.bib` file to be used for [citations](https://quarto.org/docs/authoring/citations.html)
+
+Most likely that cell will look rather weird if you run it but that's OK. We'll fix that in a
+bit.
+
+Save the notebook and now execute and render the document with Quarto from the
+commandline:
```bash
-quarto render supplementary_material.ipynb
+quarto render supplementary_material.ipynb --execute
```
Open up the `supplementary_material.html` file in a browser and compare it to
-the `supplementary_material.nbconvert.html` file. You should see that the
-Quarto version looks a lot better. The fact that Quarto supports rendering of
-Jupyter notebooks means you can keep editing your notebooks as you normally
-would and use Quarto for rendering the final document. Also there's very little
-we had to change in the notebook to make it work with Quarto. If you look
-closely at the code cells used to generate the plots and table you'll see that
-they contain code-chunk options in the same form we used in the Quarto tutorial.
-These options do not impact the notebook when run in Jupyter, making it easy to
-use the two tools in combination.
+the `supplementary_material.nbconvert.html` file. You should see that the Quarto
+version looks a lot better. The fact that Quarto supports rendering of Jupyter
+notebooks means you can keep editing your notebooks as you normally would and
+use Quarto for rendering the final document. Also there's very little we had to
+change in the notebook to make it work with Quarto: just the YAML header and the
+chunk options neither of which impact the notebook when run in Jupyter.
Let's go back to the YAML header cell and fix how it looks in the Jupyter
notebook. The reason it looks weird is that Jupyter doesn't understand the
@@ -1163,67 +1172,30 @@ general:
- A [guide](http://ipywidgets.readthedocs.io/en/stable/index.html) to using
widgets for creating interactive notebooks.
-## Running Jupyter notebooks on a cluster
-
-- Login to Uppmax, making sure to use a specific login node, _e.g._ `rackham1`:
-
-```
-ssh @rackham1.uppmax.uu.se
-```
-
-- Create/activate a Conda environment containing `jupyter`, _e.g._:
-
-```
-conda create -n jupyter -c conda-forge jupyter
-```
-
-- activate the environment, then run:
-
-```
-jupyter notebook --no-browser
-```
-
-When the Jupyter server starts up you should see something resembling:
-
-```
-[I 2023-11-13 22:15:36.944 ServerApp] Serving notebooks from local directory:
-[I 2023-11-13 22:15:36.944 ServerApp] Jupyter Server 2.10.0 is running at:
-[I 2023-11-13 22:15:36.944 ServerApp] http://localhost:8888/tree?token=25fa07e89b7c0bc2e518f259ba79c67847ca813cdf4eeed6
-[I 2023-11-13 22:15:36.944 ServerApp] http://127.0.0.1:8888/tree?token=25fa07e89b7c0bc2e518f259ba79c67847ca813cdf4eeed6
-[I 2023-11-13 22:15:36.944 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
-```
-
-Now a Jupyter notebook server is running on the Uppmax end. The line that says:
-
-```
-[I 2023-11-13 22:15:36.944 ServerApp] http://localhost:8888/tree?token=25fa07e89b7c0bc2e518f259ba79c67847ca813cdf4eeed6
-```
-
-Contains information on the port used on the server side (8888 in this case) and
-the token required to use the server (`25fa07e89b7c0bc2e518f259ba79c67847ca813cdf4eeed6`).
-
-Next step is to use this information to login to the server from your local
-computer.
-
-**On your local computer**
-
-In a terminal, run the following command to start port forwarding of
-port 8080 on your local computer to the remote port on the Uppmax side. Replace
- with the port given when you started the server on Uppmax. Also
-replace with your user name on Uppmax.
-
-```bash
-ssh -N -L localhost:8080:localhost:@rackham1.uppmax.uu.se
-```
-
-As long as this process is running the port forwarding is running. To disable it
-simply interrupt it with `CTRL + C`.
-
-Connect to the Jupyter server by opening `localhost:8080` in your browser. When
-prompted, paste the token you got when starting the server on Uppmax and set a
-new password.
-
-## Using Binder to share interactive notebooks
+### Running Jupyter notebooks on a cluster
+
+If you sometimes work on a remote cluster you can start up a Jupyter server on
+the cluster side and connect to it from your local computer. This way you can
+create, edit and run notebooks from your local computer but have the actual
+computations done on the cluster. This can be useful if you have a lot of data
+on the cluster side, or need to run computations that require a lot of resources.
+
+One way to do this is to start a [public Jupyter
+server](https://jupyter-server.readthedocs.io/en/latest/operators/public-server.html)
+on the cluster side and then connect to it via an SSH tunnel. This requires a
+fair amount of setup, especially to ensure that the server is properly secured,
+as explained
+[here](https://jupyter-server.readthedocs.io/en/latest/operators/public-server.html#securing-a-jupyter-server).
+
+As an alternative you can install [VS Code](https://code.visualstudio.com/) on
+your local computer. As we've mentioned VS code has [built-in
+support](https://code.visualstudio.com/docs/datascience/jupyter-notebooks) for
+Jupter notebooks. If you also install the [Remote -
+Explorer](https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-explorer)
+extension you can connect to the cluster and run Jupyter notebooks on the
+cluster side directly from VS Code on your laptop.
+
+### Using Binder to share interactive notebooks
[Binder](https://mybinder.org/) is a service that allows you to share Jupyter
notebooks with others, while also allowing them to run the notebooks in the
diff --git a/tutorials/jupyter/jupyter-tutorial-example.ipynb b/tutorials/jupyter/jupyter-tutorial-example.ipynb
deleted file mode 100644
index 4ebd0c81..00000000
--- a/tutorials/jupyter/jupyter-tutorial-example.ipynb
+++ /dev/null
@@ -1,4074 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "6e87037d-b180-4f51-944c-aaa1d8948f27",
- "metadata": {},
- "source": [
- "# The basics"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "07bb04c6",
- "metadata": {},
- "source": [
- "## Introduction\n",
- "In this notebook I will try out some of the **fantastic** concepts of Jupyter\n",
- "Notebooks.\n",
- "\n",
- "## Markdown basics\n",
- "Examples of text attributes are:\n",
- "\n",
- "* *italics*\n",
- "* **bold**\n",
- "* `monospace`\n",
- "\n",
- "Sections can be separated by horizontal lines."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "02726021",
- "metadata": {},
- "source": [
- "---\n",
- "\n",
- "Blockquotes can be added, for instance to insert a Monty Python quote:\n",
- "\n",
- "> Spam!\n",
- "> Spam!\n",
- "> Spam!\n",
- "> Spam!\n",
- "\n",
- "See [here](https://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Working%20With%20Markdown%20Cells.html) for more information."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "8fc746f0",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Hello world!\n"
- ]
- }
- ],
- "source": [
- "print(\"Hello world!\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "c4f8feff",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "environment.yml references.bib\n",
- "\u001b[1m\u001b[36mintermediate\u001b[m\u001b[m \u001b[1m\u001b[36mresults\u001b[m\u001b[m\n",
- "jupyter-tutorial-example.ipynb supplementary_material.ipynb\n"
- ]
- }
- ],
- "source": [
- "!ls"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "77ec8160",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "head: jupyter-tutorial.ipynb: No such file or directory\n"
- ]
- }
- ],
- "source": [
- "!head jupyter-tutorial.ipynb"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "96582697",
- "metadata": {},
- "outputs": [],
- "source": [
- "def print_me(str):\n",
- " print(str)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "8b4b3e37",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Hi!\n"
- ]
- }
- ],
- "source": [
- "print_me(\"Hi!\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "25825c38-522e-4696-9f6b-4dc915ffdada",
- "metadata": {},
- "source": [
- "# Magics"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "996fa490",
- "metadata": {},
- "outputs": [],
- "source": [
- "%load_ext rpy2.ipython"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "739326dd",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "[1] \"Hello World\"\n"
- ]
- }
- ],
- "source": [
- "%%R\n",
- "paste(\"Hello\",\"World\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "7cbafd35",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/latex": [
- "\\begin{array}{*{20}c} {x = \\frac{{ - b \\pm \\sqrt {b^2 - 4ac} }}{{2a}}} & {{\\rm{when}}} & {ax^2 + bx + c = 0} \\\\ \\end{array}\n"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "%%latex\n",
- "\\begin{array}{*{20}c} {x = \\frac{{ - b \\pm \\sqrt {b^2 - 4ac} }}{{2a}}} & {{\\rm{when}}} & {ax^2 + bx + c = 0} \\\\ \\end{array}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "id": "f0405fcb",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "33.333333333333336"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "float(100/3)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "id": "32991924",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'%.4f'"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%precision 4"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6b5a6fef-b005-4a43-90a5-53de317b4063",
- "metadata": {},
- "source": [
- "# Plotting"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "id": "1137e967",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "application/pdf": "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MzE4IDMzNyA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2CjYzNiA2MzYgMzM3IDMzNyA4MzggODM4IDgzOCA1MzEgMTAwMCA2ODQgNjg2IDY5OCA3NzAgNjMyIDU3NSA3NzUgNzUyIDI5NQoyOTUgNjU2IDU1NyA4NjMgNzQ4IDc4NyA2MDMgNzg3IDY5NSA2MzUgNjExIDczMiA2ODQgOTg5IDY4NSA2MTEgNjg1IDM5MCAzMzcKMzkwIDgzOCA1MDAgNTAwIDYxMyA2MzUgNTUwIDYzNSA2MTUgMzUyIDYzNSA2MzQgMjc4IDI3OCA1NzkgMjc4IDk3NCA2MzQgNjEyCjYzNSA2MzUgNDExIDUyMSAzOTIgNjM0IDU5MiA4MTggNTkyIDU5MiA1MjUgNjM2IDMzNyA2MzYgODM4IDYwMCA2MzYgNjAwIDMxOAozNTIgNTE4IDEwMDAgNTAwIDUwMCA1MDAgMTM0MiA2MzUgNDAwIDEwNzAgNjAwIDY4NSA2MDAgNjAwIDMxOCAzMTggNTE4IDUxOAo1OTAgNTAwIDEwMDAgNTAwIDEwMDAgNTIxIDQwMCAxMDIzIDYwMCA1MjUgNjExIDMxOCA0MDEgNjM2IDYzNiA2MzYgNjM2IDMzNwo1MDAgNTAwIDEwMDAgNDcxIDYxMiA4MzggMzYxIDEwMDAgNTAwIDUwMCA4MzggNDAxIDQwMSA1MDAgNjM2IDYzNiAzMTggNTAwCjQwMSA0NzEgNjEyIDk2OSA5NjkgOTY5IDUzMSA2ODQgNjg0IDY4NCA2ODQgNjg0IDY4NCA5NzQgNjk4IDYzMiA2MzIgNjMyIDYzMgoyOTUgMjk1IDI5NSAyOTUgNzc1IDc0OCA3ODcgNzg3IDc4NyA3ODcgNzg3IDgzOCA3ODcgNzMyIDczMiA3MzIgNzMyIDYxMSA2MDUKNjMwIDYxMyA2MTMgNjEzIDYxMyA2MTMgNjEzIDk4MiA1NTAgNjE1IDYxNSA2MTUgNjE1IDI3OCAyNzggMjc4IDI3OCA2MTIgNjM0CjYxMiA2MTIgNjEyIDYxMiA2MTIgODM4IDYxMiA2MzQgNjM0IDYzNCA2MzQgNTkyIDYzNSA1OTIgXQplbmRvYmoKMTYgMCBvYmoKPDwgL2VpZ2h0IDE3IDAgUiAvZml2ZSAxOCAwIFIgL2ZvdXIgMTkgMCBSIC9vbmUgMjEgMCBSIC9wZXJpb2QgMjIgMCBSCi9zZXZlbiAyMyAwIFIgL3NpeCAyNCAwIFIgL3R3byAyNSAwIFIgL3plcm8gMjYgMCBSID4+CmVuZG9iagozIDAgb2JqCjw8IC9GMSAxNSAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0ExIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDAgL2NhIDEgPj4KL0EyIDw8IC9UeXBlIC9FeHRHU3RhdGUgL0NBIDEgL2NhIDEgPj4gPj4KZW5kb2JqCjUgMCBvYmoKPDwgPj4KZW5kb2JqCjYgMCBvYmoKPDwgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL0YxLURlamFWdVNhbnMtbWludXMgMjAgMCBSID4+CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9QYWdlcyAvS2lkcyBbIDExIDAgUiBdIC9Db3VudCAxID4+CmVuZG9iagoyNyAwIG9iago8PCAvQ3JlYXRvciAoTWF0cGxvdGxpYiB2My44LjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcpCi9Qcm9kdWNlciAoTWF0cGxvdGxpYiBwZGYgYmFja2VuZCB2My44LjEpCi9DcmVhdGlvbkRhdGUgKEQ6MjAyMzExMTEwNzAxNDkrMDInMDAnKSA+PgplbmRvYmoKeHJlZgowIDI4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNiAwMDAwMCBuIAowMDAwMDA2NjIwIDAwMDAwIG4gCjAwMDAwMDYzOTggMDAwMDAgbiAKMDAwMDAwNjQzMCAwMDAwMCBuIAowMDAwMDA2NTI5IDAwMDAwIG4gCjAwMDAwMDY1NTAgMDAwMDAgbiAKMDAwMDAwNjU3MSAwMDAwMCBuIAowMDAwMDAwMDY1IDAwMDAwIG4gCjAwMDAwMDAzNDQgMDAwMDAgbiAKMDAwMDAwMjA1NCAwMDAwMCBuIAowMDAwMDAwMjA4IDAwMDAwIG4gCjAwMDAwMDIwMzMgMDAwMDAgbiAKMDAwMDAwNTIwNSAwMDAwMCBuIAowMDAwMDA0OTk4IDAwMDAwIG4gCjAwMDAwMDQ2MjcgMDAwMDAgbiAKMDAwMDAwNjI1OCAwMDAwMCBuIAowMDAwMDAyMDc0IDAwMDAwIG4gCjAwMDAwMDI1NDIgMDAwMDAgbiAKMDAwMDAwMjg2NCAwMDAwMCBuIAowMDAwMDAzMDMwIDAwMDAwIG4gCjAwMDAwMDMyMDIgMDAwMDAgbiAKMDAwMDAwMzM1NyAwMDAwMCBuIAowMDAwMDAzNDgwIDAwMDAwIG4gCjAwMDAwMDM2MjIgMDAwMDAgbiAKMDAwMDAwNDAxNSAwMDAwMCBuIAowMDAwMDA0MzM5IDAwMDAwIG4gCjAwMDAwMDY2ODAgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAyOCAvUm9vdCAxIDAgUiAvSW5mbyAyNyAwIFIgPj4Kc3RhcnR4cmVmCjY4MzcKJSVFT0YK",
- "image/svg+xml": [
- "\n",
- "\n",
- "\n"
- ],
- "text/plain": [
- "
"
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "# Import packages\n",
- "import numpy as np\n",
- "import matplotlib.pyplot as plt\n",
- "import matplotlib_inline\n",
- "matplotlib_inline.backend_inline.set_matplotlib_formats('pdf', 'svg')\n",
- "# Generate a set of evenly spaced numbers between 0 and 100\n",
- "x = np.linspace(0,3*np.pi,100)\n",
- "# Use the sine function to generate y-values\n",
- "y = np.sin(x)\n",
- "# Plot the data\n",
- "line, = plt.plot(x, y, color='red', linestyle=\"-\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "id": "62ce1f0d",
- "metadata": {},
- "outputs": [],
- "source": [
- "import seaborn as sns"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "id": "5aae0487",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "