{ "cells": [ { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden" }, "source": [ "This notebook is part of the `nbsphinx` documentation: https://nbsphinx.readthedocs.io/." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Code Cells\n", "\n", "## Code, Output, Streams\n", "\n", "An empty code cell:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two empty lines:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Leading/trailing empty lines:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n", "\n", "# 2 empty lines before, 1 after\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A simple output:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "6 * 7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The standard output stream:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Hello, world!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Normal output + standard output" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Hello, world!')\n", "6 * 7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The standard error stream is highlighted and displayed just below the code cell.\n", "The standard output stream comes afterwards (with no special highlighting).\n", "Finally, the \"normal\" output is displayed." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import sys\n", "\n", "print(\"I'll appear on the standard error stream\", file=sys.stderr)\n", "print(\"I'll appear on the standard output stream\")\n", "\"I'm the 'normal' output\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "Note\n", "\n", "Using the IPython kernel, the order is actually mixed up,\n", "see https://github.com/ipython/ipykernel/issues/280.\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Special Display Formats\n", "\n", "See [IPython example notebook](https://nbviewer.jupyter.org/github/ipython/ipython/blob/main/examples/IPython Kernel/Rich Output.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Local Image Files" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import Image\n", "i = Image(filename='images/notebook_icon.png')\n", "i" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "display(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "See also [SVG support for LaTeX](markdown-cells.ipynb#SVG-support-for-LaTeX)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import SVG\n", "SVG(filename='images/python_logo.svg')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Image URLs" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Image(url='https://www.python.org/static/img/python-logo-large.png')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Image(url='https://www.python.org/static/img/python-logo-large.png', embed=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Image(url='https://jupyter.org/assets/homepage/main-logo.svg')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Math" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import Math\n", "eq = Math(r'\\int\\limits_{-\\infty}^\\infty f(x) \\delta(x - x_0) dx = f(x_0)')\n", "eq" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "display(eq)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import Latex\n", "Latex(r'This is a \\LaTeX{} equation: $a^2 + b^2 = c^2$')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%latex\n", "\\begin{equation}\n", "\\int\\limits_{-\\infty}^\\infty f(x) \\delta(x - x_0) dx = f(x_0)\n", "\\end{equation}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plots" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "Make sure to use at least version 0.1.6 of the `matplotlib-inline` package\n", "(which is an automatic dependency of the `ipython` package).\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By default, the plots created with the \"inline\" backend have the wrong size.\n", "More specifically, PNG plots (the default) will be slightly larger than SVG and PDF plots.\n", "\n", "This can be fixed easily by creating a file named `matplotlibrc`\n", "(in the directory where your Jupyter notebooks live,\n", "e.g. in this directory: [matplotlibrc](matplotlibrc))\n", "and adding the following line:\n", "\n", " figure.dpi: 96\n", "\n", "If you are using Git to manage your files,\n", "don't forget to commit this local configuration file to your repository.\n", "Different directories can have different local configurations.\n", "If a given configuration should apply to multiple directories,\n", "symbolic links can be created in each directory.\n", "\n", "For more details, see\n", "[Default Values for Matplotlib's \"inline\" Backend](https://nbviewer.jupyter.org/github/mgeier/python-audio/blob/master/plotting/matplotlib-inline-defaults.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By default, plots are generated in the PNG format.\n", "In most cases,\n", "it looks better\n", "if SVG plots are used for HTML output\n", "and PDF plots are used for LaTeX/PDF.\n", "This can be achieved by setting\n", "[nbsphinx_execute_arguments](configuration.ipynb#nbsphinx_execute_arguments)\n", "in your `conf.py` file like this:\n", "\n", "```python\n", "nbsphinx_execute_arguments = [\n", " \"--InlineBackend.figure_formats={'svg', 'pdf'}\",\n", "]\n", "```\n", " \n", "In the following example, `nbsphinx` should use an SVG image in the HTML output\n", "and a PDF image for LaTeX/PDF output\n", "(other Jupyter clients like JupyterLab will still show the default PNG format)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=[6, 3])\n", "ax.plot([4, 9, 7, 20, 6, 33, 13, 23, 16, 62, 8]);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For comparison,\n", "this is how it would look in PNG format ..." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%config InlineBackend.figure_formats = ['png']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "... and in `'png2x'` (a.k.a. `'retina'`) format:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%config InlineBackend.figure_formats = ['png2x']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pandas Dataframes\n", "\n", "[Pandas dataframes](https://pandas.pydata.org/pandas-docs/stable/user_guide/dsintro.html#dataframe)\n", "should be displayed as nicely formatted HTML tables (if you are using HTML output)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(np.random.randint(0, 100, size=[10, 4]),\n", " columns=[r'$\\alpha$', r'$\\beta$', r'$\\gamma$', r'$\\delta$'])\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Markdown Content" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import Markdown" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "md = Markdown(\"\"\"\n", "# Markdown\n", "\n", "It *should* show up as **formatted** text\n", "with things like [links] and images.\n", "\n", "[links]: https://jupyter.org/\n", "\n", "![Jupyter notebook icon](images/notebook_icon.png)\n", "\n", "## Markdown Extensions\n", "\n", "There might also be mathematical equations like\n", "$a^2 + b^2 = c^2$\n", "and even tables:\n", "\n", "A | B | A and B\n", "------|-------|--------\n", "False | False | False\n", "True | False | False\n", "False | True | False\n", "True | True | True\n", "\n", "\"\"\")\n", "md" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### YouTube Videos" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import YouTubeVideo\n", "YouTubeVideo('9_OIs49m56E')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Interactive Widgets (HTML only)\n", "\n", "The basic widget infrastructure is provided by\n", "the [ipywidgets](https://ipywidgets.readthedocs.io/) module.\n", "More advanced widgets are available in separate packages,\n", "see for example https://jupyter.org/widgets.\n", "\n", "The JavaScript code which is needed to display Jupyter widgets\n", "is loaded automatically (using RequireJS).\n", "If you want to use non-default URLs or local files,\n", "you can use the\n", "[nbsphinx_widgets_path](configuration.ipynb#nbsphinx_widgets_path) and\n", "[nbsphinx_requirejs_path](configuration.ipynb#nbsphinx_requirejs_path)\n", "settings." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import ipywidgets as w" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "slider = w.IntSlider()\n", "slider.value = 42\n", "slider" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A widget typically consists of a so-called \"model\" and a \"view\" into that model.\n", "\n", "If you display a widget multiple times,\n", "all instances act as a \"view\" into the same \"model\".\n", "That means that their state is synchronized.\n", "You can move either one of these sliders to try this out:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "slider" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also link different widgets.\n", "\n", "Widgets can be linked via the kernel\n", "(which of course only works while a kernel is running)\n", "or directly in the client\n", "(which even works in the rendered HTML pages).\n", "\n", "Widgets can be linked uni- or bi-directionally.\n", "\n", "Examples for all 4 combinations are shown here:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "link = w.IntSlider(description='link')\n", "w.link((slider, 'value'), (link, 'value'))\n", "jslink = w.IntSlider(description='jslink')\n", "w.jslink((slider, 'value'), (jslink, 'value'))\n", "dlink = w.IntSlider(description='dlink')\n", "w.dlink((slider, 'value'), (dlink, 'value'))\n", "jsdlink = w.IntSlider(description='jsdlink')\n", "w.jsdlink((slider, 'value'), (jsdlink, 'value'))\n", "w.VBox([link, jslink, dlink, jsdlink])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tabs = w.Tab()\n", "for idx, obj in enumerate([df, fig, eq, i, md, slider]):\n", " out = w.Output()\n", " with out:\n", " display(obj)\n", " tabs.children += out,\n", " tabs.set_title(idx, obj.__class__.__name__)\n", "tabs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "Other Languages\n", "\n", "The examples shown here are using Python,\n", "but the widget technology can also be used with\n", "different Jupyter kernels\n", "(i.e. with different programming languages).\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Troubleshooting\n", "\n", "To obtain more information if widgets are not displayed as expected, you will need to look at the error message in the web browser console.\n", "\n", "> To figure out how to open the web browser console, you may look at the web browser documentation: \n", "> Chrome: https://developer.chrome.com/docs/devtools/open/#shortcuts \n", "> Firefox: https://developer.mozilla.org/en-US/docs/Tools/Web_Console#opening-the-web-console\n", "\n", "The error is most probably linked to the JavaScript files not being loaded or loaded in the wrong order within the HTML file. To analyze the error, you can inspect the HTML file within the web browser (e.g.: right-click on the page and select *View Page Source*) and look at the `` section of the page. That section should contain\n", "some JavaScript libraries. Those relevant for widgets are:\n", "\n", "```html\n", "\n", "\n", "\n", "\n", "\n", "\n", "```\n", "\n", "The two first elements are mandatory. The third one is required only if you designed your own widgets but did not publish them on npm.js.\n", "\n", "If those libraries appear in a different order, the widgets won't be displayed. \n", "\n", "Here is a list of possible solutions:\n", "\n", "- If the widgets are **not displayed**, see [#519](https://github.com/spatialaudio/nbsphinx/issues/519).\n", "- If the widgets are **displayed multiple times**, see [#378](https://github.com/spatialaudio/nbsphinx/issues/378)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Arbitrary JavaScript Output (HTML only)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%javascript\n", "\n", "var text = document.createTextNode(\"Hello, I was generated with JavaScript!\");\n", "// Content appended to \"element\" will be visible in the output area:\n", "element.appendChild(text);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Unsupported Output Types\n", "\n", "If a code cell produces data with an unsupported MIME type, the Jupyter Notebook doesn't generate any output.\n", "`nbsphinx`, however, shows a warning message." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "display({\n", " 'text/x-python': 'print(\"Hello, world!\")',\n", " 'text/x-haskell': 'main = putStrLn \"Hello, world!\"',\n", "}, raw=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ANSI Colors\n", "\n", "The standard output and standard error streams may contain [ANSI escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code) to change the text and background colors." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('BEWARE: \\x1b[1;33;41mugly colors\\x1b[m!', file=sys.stderr)\n", "print('AB\\x1b[43mCD\\x1b[35mEF\\x1b[1mGH\\x1b[4mIJ\\x1b[7m'\n", " 'KL\\x1b[49mMN\\x1b[39mOP\\x1b[22mQR\\x1b[24mST\\x1b[27mUV')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following code showing the 8 basic ANSI colors is based on https://web.archive.org/web/20231225185739/https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html.\n", "Each of the 8 colors has an \"intense\" variation, which is used for bold text." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "text = ' XYZ '\n", "formatstring = '\\x1b[{}m' + text + '\\x1b[m'\n", "\n", "print(' ' * 6 + ' ' * len(text) +\n", " ''.join('{:^{}}'.format(bg, len(text)) for bg in range(40, 48)))\n", "for fg in range(30, 38):\n", " for bold in False, True:\n", " fg_code = ('1;' if bold else '') + str(fg)\n", " print(' {:>4} '.format(fg_code) + formatstring.format(fg_code) +\n", " ''.join(formatstring.format(fg_code + ';' + str(bg))\n", " for bg in range(40, 48)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ANSI also supports a set of 256 indexed colors.\n", "The following code showing all of them is based on [http://bitmote.com/index.php?post/2012/11/19/Using-ANSI-Color-Codes-to-Colorize-Your-Bash-Prompt-on-Linux](https://web.archive.org/web/20190109005413/http://bitmote.com/index.php?post/2012/11/19/Using-ANSI-Color-Codes-to-Colorize-Your-Bash-Prompt-on-Linux)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "formatstring = '\\x1b[38;5;{0};48;5;{0}mX\\x1b[1mX\\x1b[m'\n", "\n", "print(' + ' + ''.join('{:2}'.format(i) for i in range(36)))\n", "print(' 0 ' + ''.join(formatstring.format(i) for i in range(16)))\n", "for i in range(7):\n", " i = i * 36 + 16\n", " print('{:3} '.format(i) + ''.join(formatstring.format(i + j)\n", " for j in range(36) if i + j < 256))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can even use 24-bit RGB colors:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "start = 255, 0, 0\n", "end = 0, 0, 255\n", "length = 79\n", "out = []\n", "\n", "for i in range(length):\n", " rgb = [start[c] + int(i * (end[c] - start[c]) / length) for c in range(3)]\n", " out.append('\\x1b['\n", " '38;2;{rgb[2]};{rgb[1]};{rgb[0]};'\n", " '48;2;{rgb[0]};{rgb[1]};{rgb[2]}mX\\x1b[m'.format(rgb=rgb))\n", "print(''.join(out))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.9" } }, "nbformat": 4, "nbformat_minor": 4 }