Redisplaying modified plot in subsequent IPython notebook cells

ipython, matplotlib, python

Solution

You can use variables to reference the figure and Axe objects:

In cell 1:

fig, ax = subplots(1, 1)
plot(randn(100));

In cell 2:

ax.set_xlim(20, 40)
fig

Problem

I am creating a demo using IPython notebook. I launch the notebook in the pylab inline mode, e.g. `ipython notebook --pylab=inline`, and what I would like to do is progressively build a plot, modifying aspects of the plot in subsequent cells, and having the chart redisplay after each modification. For instance, I would like to have consecutive cells, CELL 1: ``` from pandas.io.data import DataReader from datetime import datetime import matplotlib.pyplot as plt goog = DataReader("GOOG", "yahoo", datetime(2000,1,1), datetime(2012,1,1)) close_vals = goog['Close'] plot(close_vals.index, close_vals.values) CHART DISPLAYED INLINE ``` CELL 2: ``` xlim(datetime(2009,1,1), datetime(2010,1,1)) MODIFIED CHART DISPLAYED INLINE ``` However, the original chart doesn't seem to make it's way into subsequent cells, and the chart displayed in CELL 2 is empty. In order to see the original plot with the modification, I have to re-issue the plot command, CELL 2: ``` plot(close_vals.index, close_vals.values) xlim(datetime(2009,1,1), datetime(2010,1,1)) ``` This quickly gets clunky and inelegant as I add moving average trend lines and labels. Also, working from the IPython console, this method of progressively building a plot works just fine. Anyone know of a better way to create this kind of demo in the notebook? Thanks. UPDATE: My final code ended up looking like this. CELL 1: ``` from pandas.io.data import DataReader from datetime import datetime import matplotlib.pyplot as plt goog = DataReader("GOOG", "yahoo", datetime(2000,1,1), datetime(2012,1,1)) close_vals = goog['Close'] fig, ax = subplots(1,1) ax.plot(close_vals.index, close_vals.values,label='GOOG Stock Price') ``` CELL 2: ``` ax.set_xlim(datetime(2009,1,1), datetime(2010,1,1)) fig ``` CELL 3: ``` avg_20 = [ sum(close_vals.values[i-20:i])/20.0 for i in range(20,len(close_vals))] avg_20_times = close_vals.index[20:] ax.plot(avg_20_times, avg_20, label='20 day trailing average') ax.legend() fig ``` After updating `ax` in each subsequent cell, calling `fig` redisplays the plot; exactly what I was looking for. Thanks!

Original source