{ "cells": [ { "cell_type": "markdown", "id": "4a8ba901-956b-49da-88f3-7a41036c4dbc", "metadata": { "toc-hr-collapsed": true }, "source": [ "# Workshop \"Teaching Sciences and Engineering with Jupyter Notebooks\" 2023-2024\n", "\n", "Notebook by Cécile Hardebolle, 2023
\n", "Except where otherwise noted, the content of this notebook is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
\n", "\"Creative \n", "\n", "
\n", " How to use this notebook?
\n", " This notebook is made of text cells and code cells. The code cells have to be executed to see the result of the program.
To execute a cell, simply select it and click on the \"play\" button () in the tool bar just above the notebook, or type shift + enter.
It is important to execute the code cells in their order of appearance in the notebook.\n", "
" ] }, { "cell_type": "markdown", "id": "37abfac0-d5d8-44be-8572-425abf875a19", "metadata": {}, "source": [ "# Demo: hiding the code of your interactive visualizations\n", "\n", "This notebook demonstrates how the code from an interactive visualization can be hidden from a notebook. \n", "Again there are different ways to achieve the same result, this is only one possible solution.\n", "\n", "In this demo, we use the same \"interactive house\" visualization example as [in this notebook](GettingStarted-02-InteractiveVisualization.ipynb)." ] }, { "cell_type": "markdown", "id": "c0c4751d-38b6-449b-8db2-8699e51a8eba", "metadata": {}, "source": [ "## Putting the code in an external Python file\n", "The main principle is to put the code that generates the interactive visualization into an external Python file. \n", "In such a file, code can take the form of functions or classes.\n", "\n", "Here is an exemple: [interactivevisualization.py (click here to open the file)](lib/interactivevisualization.py). \n", "In this demo, we have simply created a function that generates the interactive house visualization and displays it. " ] }, { "cell_type": "markdown", "id": "c0e26a53-bc03-429f-aeb0-71abb560f549", "metadata": { "tags": [] }, "source": [ "## Using the file\n", "To be able to use the code defined in our Python file, we simply use the built-in `import` feature of Python." ] }, { "cell_type": "code", "execution_count": null, "id": "8aa8717e-44e5-4df6-b79f-0f6e01488d9c", "metadata": {}, "outputs": [], "source": [ "# Let's import the content of our Python file\n", "from lib.interactivevisualization import *" ] }, { "cell_type": "markdown", "id": "b0c5c5ec-6a13-4bd7-aa39-d2531010c0bf", "metadata": {}, "source": [ "Then we can simply call the function we have defined." ] }, { "cell_type": "code", "execution_count": null, "id": "a15eab91-850b-4402-b8fa-a244fbce9f70", "metadata": {}, "outputs": [], "source": [ "# Now we can use the functions defined in the file\n", "displayInteractiveHouse()" ] }, { "cell_type": "markdown", "id": "1c44abd2-1641-42e7-b7eb-c5e14c77251c", "metadata": {}, "source": [ "---\n", "\n", "## Differences between the code in the notebook and in the external file\n", "\n", "### Choosing the matplotlib backend\n", "\n", "We cannot use the instruction `%matplotlib widget` to choose the backend of matplotlib in a Python file because it works only when in a [notebook](GettingStarted-02-InteractiveVisualization.ipynb). \n", "Instead we need to use the following two lines, which do exactly the same thing:\n", "```python\n", "from IPython import get_ipython\n", "get_ipython().run_line_magic('matplotlib', 'widget')\n", "\n", "```\n", "\n", "### Turning the interactive mode on/off\n", "\n", "Since the code is in one piece only - compared to split over several cells in a [notebook](GettingStarted-02-InteractiveVisualization.ipynb) - we don't need to switch the interactive mode of matplotlib off and back on again. \n", "Matplotlib will simply render the full visualization in one shot when the function is called.\n", "\n", "Therefore, we **don't need to**:\n", "- call `plt.ioff()` to turn the interactive mode off\n", "- call `plt.ion()` to turn it back on\n", "- display the figure explicitely (`display(fig.canvas)`) - matplotlib will display it automatically while it is drawn\n", "\n", "NB: try it out, if you display the figure, you will see the figure twice..." ] }, { "cell_type": "markdown", "id": "1bd36fc9-b9cd-464a-acd1-d2b574cc59a7", "metadata": {}, "source": [ "---\n", "\n", "## Function or class?\n", "\n", "Note that, in this design, the event handler function becomes a *nested* function, which some would argue is not a great design. \n", "Another way to achieve the same thing is to create a class with the different variables of the visualization as attributes and the event handler function as a method. \n", "For this, you need to be familiar with [object-oriented programming in Python](https://realpython.com/python3-object-oriented-programming/). \n", "\n", "Here is an example of a more complex visualization example implemented as a Python class: [lib/suspendedobjectinteractive.py (click here to open the file)](lib/suspendedobjectinteractive.py). \n", "\n", "Execute the code cell below to see the result. \n", "Note: it is usually recommended to have only one interactive visualization per notebook although this is now supported, for retro-compatibility with older execution platforms." ] }, { "cell_type": "code", "execution_count": null, "id": "a7737bde-e3f6-4c33-8bf7-fe95e9382e26", "metadata": {}, "outputs": [], "source": [ "from lib.suspendedobjectinteractive import *\n", "SuspendedObjectLab();" ] } ], "metadata": { "kernelspec": { "display_name": "Python3", "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.11.5" } }, "nbformat": 4, "nbformat_minor": 5 }