Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configure a first cell by default in Jupyter notebooks

TIs there a way to configure a default first cell for a specific python kernel in the Jupyter notebook? I agree that default python imports go against good coding practices.

So, can I configure the notebook such that the first cell of a new python notebook is always

import numpy as np

for instance?

like image 953
Demian Wassermann Avatar asked Mar 24 '16 07:03

Demian Wassermann


3 Answers

Creating an IPython profile as mentioned above is a good first solution, but IMO it isn't totally satisfying, especially when it comes to code sharing.

The names of your libraries imported through the command exec_lines do not appear in the notebook, so you can easily forget it. And running the code on another profile / machine would raise an error.

Therefore I would recommend to use a Jupyter notebook extension, because the imported libraries are displayed. It avoids importing always the same libraries at the beginning of a notebook. First you need to install the nbextension of Jupyter. You can either clone the repo : https://github.com/ipython-contrib/jupyter_contrib_nbextensions or use the pip : pip install jupyter_contrib_nbextensions

Then you can create a nb extension by adding a folder 'default_cells' to the path where the nb extensions are installed. For example on Ubuntu it's /usr/local/share/jupyter/nbextensions/., maybe on windows : C:\Users\xxx.xxx\AppData\Roaming\jupyter\nbextensions\

You have to create 3 files in this folder:

  • main.js which contains the js code of the extension
  • default_cells.yaml description for the API in Jupyter
  • README.MD the usual description for the reader appearing in the API.

I used the code from : https://github.com/jupyter/notebook/issues/1451my main.js is :

    define([
        'base/js/namespace'
    ], function(
        Jupyter
    ) {
        function load_ipython_extension() {
          if (Jupyter.notebook.get_cells().length===1){
       //do your thing
            Jupyter.notebook.insert_cell_above('code', 0).set_text("# Scientific libraries\nimport numpy as np\nimport scipy\n\n# import Pandas\n\nimport pandas as pd\n\n# Graphic libraries\n\nimport matplotlib as plt\n%matplotlib inline\nimport seaborn as sns\nfrom plotly.offline import init_notebook_mode, iplot, download_plotlyjs\ninit_notebook_mode()\nimport plotly.graph_objs as go\n\n# Extra options \n\npd.options.display.max_rows = 10\npd.set_option('max_columns', 50)\nsns.set(style='ticks', context='talk')\n\n# Creating alias for magic commands\n%alias_magic t time");
          }
        }
        return {
            load_ipython_extension: load_ipython_extension
        };
    });

the .yaml has to be formatted like this :

    Type: IPython Notebook Extension
    Compatibility: 3.x, 4.x
    Name: Default cells
    Main: main.js
    Link: README.md
    Description: |
      Add a default cell for each new notebook. Useful when you import always the same libraries$
    
    
    Parameters:
    - none

and the README.md

    default_cells
    =========
    
    Add default cells to each new notebook. You have to modify this line in the main.js file to change your default cell. For example
    
    `Jupyter.notebook.insert_cell_above('code', 0).set_text("import numpy as np/nimportpandas as pd")`
    
    
    You can also add another default cell by creating a new line just below :
    
    `Jupyter.notebook.insert_cell_above('code', 1).set_text("from sklearn.meatrics import mean_squared_error")`
    
    **Don't forget to increment 1 if you want more than one extra cell. **

Then you just have to enable the 'Default cells' extension in the new tab 'nbextensions' which appeared in Jupyter.

The only issue is that it detects if the notebook is new, by looking at the number of cells in the notebook. But if you wrote all your code in one cell, it will detect it as a new notebook and still add the default cells.

like image 80
MCMZL Avatar answered Oct 05 '22 07:10

MCMZL


Another half-solution: keep the default code in a file, and manually type and execute a %load command in your first cell.

I keep my standard imports in firstcell.py:

%reload_ext autoreload
%autoreload 2

import numpy as np
import pandas as pd
... 

Then in each new notebook, I type and run %load firstcell.py in the first cell, and jupyter changes the first cell contents to

# %load firstcell.py
%reload_ext autoreload
%autoreload 2

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

If you really just want a single import statement, this doesn't get you anything, but if you have several you always want to use, this might help.

like image 43
Dan Goldner Avatar answered Oct 05 '22 07:10

Dan Goldner


Go there:

~/.ipython/profile_default/startup/

You can read the README:

This is the IPython startup directory

.py and .ipy files in this directory will be run prior to any code or files specified via the exec_lines or exec_files configurables whenever you load this profile.

Files will be run in lexicographical order, so you can control the execution order of files with a prefix, e.g.::

00-first.py
50-middle.py
99-last.ipy

So you just need to create a file there like 00_imports.py which contains:

import numpy as np

if you want to add stuff like %matplotlib inline use .ipy, which you can use directly as well.

Alternatively, there seems to exist another solution with notebook extension, but I don't know how it works, see here for the github issue of the topic: https://github.com/jupyter/notebook/issues/640

HTH

like image 37
jrjc Avatar answered Oct 05 '22 06:10

jrjc