Michael Michael - 2 months ago 16
Python Question

IPython notebook: How to write cell magic which can access notebook variables?

My question is: How can I write an IPython cell magic which has access to the namespace of the IPython notebook?

IPython allows writing user-defined cell magics. My plan is creating a plotting function which can plot one or multiple arbitrary Python expressions (expressions based on Pandas Series objects), whereby each line in the cell string is a separate graph in the chart.

This is the code of the cell magic:

def p(line, cell):
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame()
line_list = cell.split('\n')

counter = 0
for line in line_list:
df['series' + str(counter)] = eval(line)
counter += 1

plt.figure(figsize = [20,6])
ax = plt.subplot(111)
df.plot(ax = ax)


def load_ipython_extension(ipython):
ipython.register_magic_function(p, 'cell')


The function receives the entire cell contents as a string. This string is then split by line breaks and evaluated using eval(). The result is added to a Pandas DataFrame. Finally the DataFrame is plotted using matplotlib.

Usage example: First define the Pandas Series object in IPython notebook.

import pandas as pd
ts = pd.Series([1,2,3])


Then call the magic in IPython notebook (whereby the whole code below is one cell):

%%p
ts * 3
ts + 1


This code fails with the following error:

NameError: name 'ts' is not defined


I suspect the problem is that the
p
function only receives
ts * 3\n ts + 1
as a string and that it does not have access to the
ts
variable defined in the namespace of IPython notebook (because the
p
function is defined in a separate .py file).

How does my code have to be changed so the cell magic has access to the
ts
variable defined in the IPython notebook (and therefore does not fail with the NameError)?

Answer Source

Use the @needs_local_scope decorator decorator. Documentation is a bit missing, but you can see how it is used, and contributing to docs would be welcome.