Reputation: 1329
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')
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
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
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)
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
fig.gca().scatter(x3, y3, color='g', linewidth=5)
fig
fig.legend(['Blue Data','Red Data','Green Data'], loc='lower right')
fig
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
As you can see by my code, each addition to the plot (data, axis titles, etc.) was done in separate cells
Upvotes: 3