简体   繁体   中英

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. 在此处输入图片说明

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: 在此处输入图片说明

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:

  • Python 3.7.0
  • matplotlib 3.2.2
  • ipykernel 5.2.1
  • ipywidgets 7.5.1
  • jupyter 1.0.0
  • jupyter_core 4.6.3
  • jupyter_client 6.1.6
  • notebook 6.0.3
  • Windows 10

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)

情节 1
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

情节2
Add final data:

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

图 3
Add a legend:

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

图 4
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

图 5

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM