lazarea
lazarea

Reputation: 1329

How to change a matplotlib figure in a different cell in Jupyter Notebook?

I am learning how to create and modify plots using matplotlib in Jupyter Notebook. I added the following magic function and import statements right at the beginning of the notebook:

%matplotlib inline
import numpy as np 
import matplotlib.pyplot as plt

Then, I created a cell and added all the following code:


x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
y = x
plt.figure()
plt.scatter(x[:2], y[:2], s=100, c='red', label='Red data')
plt.scatter(x[2:], y[2:], s = 100, c='blue', label='Blue data')
plt.xlabel('This is my x label')
plt.ylabel('This is my y label')
plt.title('This is my plot title')

The plot itself seems fine in this case, although I don't understand why the additional Text(0.5, 1.0, 'This is my plot title') line gets added, and nothing about the xlabel and ylabel text objects. enter image description here

Now I find it rather impractical to always have to force every command pertaining to a plot into one cell. I would like to be able to create the basic plot in one cell and add labels and legend to it in a different cell (and later on do other manipulations on the plot, this is not a topic for this question though). To achieve this, I would need to reference the plot created in the first cell - for this, I used plt.gcf(). However, when I run the following code, Python / matplotlib / Jupyter treats the different cells as different plots entirely. (Note: the dashed separations indicate different Jupyter Notebook cells.)

plt.figure()
plt.scatter(x[:2], y[:2], s=100, c='red', label='Red data')
plt.scatter(x[2:], y[2:], s = 100, c='blue', label='Blue data')
#-------------------------------------------------------------
plt.gcf()
plt.xlabel('This is my x label')
plt.ylabel('This is my y label')
plt.title('This is my plot title')
#-------------------------------------------------------------
plt.gcf()
plt.legend(loc=4, frameon=False, title='Legend')

The output is as follows: enter image description here

I tried changing %matplotlib inline to the apparently more modern %matplotlib notebook but it didn't help. I also tried removing the plt.gcf() rows from the beginning of the cells but I still got the same output.

Edit My versions are:

Upvotes: 2

Views: 3836

Answers (2)

tom10
tom10

Reputation: 69192

What you have will work if instead of having the first line as

%matplotlib inline

You use instead,

%matplotlib notebook

For example, see the discussion here. (And you'll need to restart the kernal to get this to take.)

Also, keep in mind that the pyplot interface is "mainly intended for interactive plots and simple cases of programmatic plot generation".

For building more complicated plots, like it seems you're doing, the OO interface is more powerful. For example, with the OO interface you can easily create two axes, set the title to each in one cell, and the labels for each in the next cell. It's much easier to keep and handle on everything.

Upvotes: 2

Jacob K
Jacob K

Reputation: 784

Saving a figure to a variable like fig and then using fig.gca() to get the current axes
(for additional plot commands) will do the trick.

Start by importing the packages and using the matplotlib inline environment:

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

Then get your data and create a scatter plot for it (while saving the plot to a figure)

# Generate some random data
x = np.arange(1,3)
y = x
x2 = np.arange(3,11)
y2 = x2
x3 = np.arange(11,21)
y3 = x3

# Create initial figure
fig = plt.figure()
plt.scatter(x, y, linewidth=5)

Plot1
Then plot more data using the fig.gca() trick (the fig line shows the plot under the cell):

fig.gca().scatter(x2, y2, color='r', linewidth=5)
fig

Plot2
Add final data:

fig.gca().scatter(x3, y3, color='g', linewidth=5)
fig

Plot3
Add a legend:

fig.legend(['Blue Data','Red Data','Green Data'], loc='lower right')
fig

Plot4
Lastly, add x/y labels and title:

fig.gca().set_xlabel('My x label')
fig.gca().set_ylabel('My y label')
fig.gca().set_title('A title')
fig

Plot5

As you can see by my code, each addition to the plot (data, axis titles, etc.) was done in separate cells

Upvotes: 3

Related Questions