I am trying to create multiple plots in my Jupyter notebook. However, when I create one, it replaces the one before it instead of creating a brand new graph. Ex.
#plotting revenue_adj vs vote_average data
df.plot.scatter(x='revenue_adj',y='vote_average',s=.5,title='Average Movie Vote per Budget',figsize=(8,5));
creates a scatter plot, but when I try to plot below it (on a new code line),
df.groupby('genres')['vote_average'].mean().plot()
it replaces the above plot instead of creating a new one under that code. What is going on?
Remember, the plotting functions of pandas use actually matplotlib.
So you can use matplotlib figure() or subplots() functions to create new figures:
import matplotlib.pyplot as plt
fig = plt.figure()
df.plot.scatter()
fig = plt.figure()
df.plot.scatter()
# | or using subplots()
fig, ax = plt.subplots(1,2)
df.plot.scatter(ax=ax[0])
df.plot.scatter(ax=ax[1])
Related
I need to create a figure in a file without displaying it within IPython notebook. I am not clear on the interaction between IPython and matplotlib.pylab in this regard. But, when I call pylab.savefig("test.png") the current figure get's displayed in addition to being saved in test.png. When automating the creation of a large set of plot files, this is often undesirable. Or in the situation that an intermediate file for external processing by another app is desired.
Not sure if this is a matplotlib or IPython notebook question.
This is a matplotlib question, and you can get around this by using a backend that doesn't display to the user, e.g. 'Agg':
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('/tmp/test.png')
EDIT: If you don't want to lose the ability to display plots, turn off Interactive Mode, and only call plt.show() when you are ready to display the plots:
import matplotlib.pyplot as plt
# Turn interactive plotting off
plt.ioff()
# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)
# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')
# Display all "open" (non-closed) figures
plt.show()
We don't need to plt.ioff() or plt.show() (if we use %matplotlib inline). You can test above code without plt.ioff(). plt.close() has the essential role. Try this one:
%matplotlib inline
import pylab as plt
# It doesn't matter you add line below. You can even replace it by 'plt.ion()', but you will see no changes.
## plt.ioff()
# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('test0.png')
plt.close(fig)
# Create a new figure, plot into it, then don't close it so it does get displayed
fig2 = plt.figure()
plt.plot([1,3,2])
plt.savefig('test1.png')
If you run this code in iPython, it will display a second plot, and if you add plt.close(fig2) to the end of it, you will see nothing.
In conclusion, if you close figure by plt.close(fig), it won't be displayed.
When using %matplotlib notebook I'm getting two plots instead of one from a pandas Series.
Code in cell is:
%matplotlib notebook
import matplotlib.pyplot as plt
fig=plt.figure()
ax1=fig.add_subplot(1,1,1)
cTitle='H-alpha plot '+galaxy[10:17]
cXAxisTitle='Galactocentric radius/pixels'
cYAxisTitle='Data counts'
ax1.set_title(cTitle)
ax1.set_xlabel(cXAxisTitle)
ax1.set_ylabel(cYAxisTitle)
ax1.grid()
ds.plot()
I'm getting Fig 1 and Fig 2:
Title, axis labels and grid lines in Fig 1 are what I want (expect) and plot in Fig 2 is also what I expect. But why am I getting two plots anyway?
Start from:
%matplotlib inline
import matplotlib.pyplot as plt
once, at the beginning of your notebook.
My suggestion is to use inline instead of notebook.
Then run:
cTitle = 'H-alpha plot '+ galaxy[10:17]
cXAxisTitle = 'Galactocentric radius/pixels'
cYAxisTitle = 'Data counts'
ax1 = ds.plot(title=cTitle, grid=True)
ax1.set(xlabel=cXAxisTitle, ylabel=cYAxisTitle);
Note the semicolon at the end of the last instruction.
Otherwise you will have additional "messages" superimposed
on your drawing.
I am trying to plot multiple rgb images with matplotlib
the code I am using is:
import numpy as np
import matplotlib.pyplot as plt
for i in range(0, images):
test = np.random.rand(1080, 720,3)
plt.subplot(images,2,i+1)
plt.imshow(test, interpolation='none')
the subplots appear tiny though as thumbnails
How can I make them bigger?
I have seen solutions using
fig, ax = plt.subplots()
syntax before but not with plt.subplot ?
plt.subplots initiates a subplot grid, while plt.subplot adds a subplot. So the difference is whether you want to initiate you plot right away or fill it over time. Since it seems, that you know how many images to plot beforehand, I would also recommend going with subplots.
Also notice, that the way you use plt.subplot you generate empy subplots in between the ones you are actually using, which is another reason they are so small.
import numpy as np
import matplotlib.pyplot as plt
images = 4
fig, axes = plt.subplots(images, 1, # Puts subplots in the axes variable
figsize=(4, 10), # Use figsize to set the size of the whole plot
dpi=200, # Further refine size with dpi setting
tight_layout=True) # Makes enough room between plots for labels
for i, ax in enumerate(axes):
y = np.random.randn(512, 512)
ax.imshow(y)
ax.set_title(str(i), fontweight='bold')
I've drawn a plot that looks something like the following:
It was created using the following code:
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
# 1. Plot a figure consisting of 3 separate axes
# ==============================================
plotNames = ['Plot1','Plot2','Plot3']
figure, axisList = plt.subplots(len(plotNames), sharex=True, sharey=True)
tempDF = pd.DataFrame()
tempDF['date'] = pd.date_range('2015-01-01','2015-12-31',freq='D')
tempDF['value'] = np.random.randn(tempDF['date'].size)
tempDF['value2'] = np.random.randn(tempDF['date'].size)
for i in range(len(plotNames)):
axisList[i].plot_date(tempDF['date'],tempDF['value'],'b-',xdate=True)
# 2. Create a new single axis in the figure. This new axis sits over
# the top of the axes drawn previously. Make all the components of
# the new single axis invisibe except for the x and y labels.
big_ax = figure.add_subplot(111)
big_ax.set_axis_bgcolor('none')
big_ax.set_xlabel('Date',fontweight='bold')
big_ax.set_ylabel('Random normal',fontweight='bold')
big_ax.tick_params(labelcolor='none', top='off', bottom='off', left='off', right='off')
big_ax.spines['right'].set_visible(False)
big_ax.spines['top'].set_visible(False)
big_ax.spines['left'].set_visible(False)
big_ax.spines['bottom'].set_visible(False)
# 3. Plot a separate figure
# =========================
figure2,ax2 = plt.subplots()
ax2.plot_date(tempDF['date'],tempDF['value2'],'-',xdate=True,color='green')
ax2.set_xlabel('Date',fontweight='bold')
ax2.set_ylabel('Random normal',fontweight='bold')
# Save plot
# =========
plt.savefig('tempPlot.png',dpi=300)
Basically, the rationale for plotting the whole picture is as follows:
Create the first figure and plot 3 separate axes using a loop
Plot a single axis in the same figure to sit on top of the graphs
drawn previously. Label the x and y axes. Make all other aspects of
this axis invisible.
Create a second figure and plot data on a single axis.
The plot displays just as I want when using jupyter-notebook but when the plot is saved, the file contains only the second figure.
I was under the impression that plots could have multiple figures and that figures could have multiple axes. However, I suspect I have a fundamental misunderstanding of the differences between plots, subplots, figures and axes. Can someone please explain what I'm doing wrong and explain how to get the whole image to save to a single file.
Matplotlib does not have "plots". In that sense,
plots are figures
subplots are axes
During runtime of a script you can have as many figures as you wish. Calling plt.save() will save the currently active figure, i.e. the figure you would get by calling plt.gcf().
You can save any other figure either by providing a figure number num:
plt.figure(num)
plt.savefig("output.png")
or by having a refence to the figure object fig1
fig1.savefig("output.png")
In order to save several figures into one file, one could go the way detailed here: Python saving multiple figures into one PDF file.
Another option would be not to create several figures, but a single one, using subplots,
fig = plt.figure()
ax = plt.add_subplot(611)
ax2 = plt.add_subplot(612)
ax3 = plt.add_subplot(613)
ax4 = plt.add_subplot(212)
and then plot the respective graphs to those axes using
ax.plot(x,y)
or in the case of a pandas dataframe df
df.plot(x="column1", y="column2", ax=ax)
This second option can of course be generalized to arbitrary axes positions using subplots on grids. This is detailed in the matplotlib user's guide Customizing Location of Subplot Using GridSpec
Furthermore, it is possible to position an axes (a subplot so to speak) at any position in the figure using fig.add_axes([left, bottom, width, height]) (where left, bottom, width, height are in figure coordinates, ranging from 0 to 1).
So I'm trying to create a figure that presents a 3d plot from data points, along with the plots 3 projections in 3 other subplots. I can add the subplots for the projections with no problems, but when I try to place the 3 dimensional plot into the figure things backfire.
here's my code:
def plotAll(data):
fig = plt.figure()
plot_3d = fig.add_subplot(221)
ax = Axes3D(plot_3d)
for i,traj in enumerate(data.values()):
ax.plot3D([traj[0][-1]],[traj[1][-1]],[traj[2][-1]],".",color=[0.91,0.39,0.046])
#plot_12v13 = fig.add_subplot(222)
#plot_projections(data,0,1)
#plot_13v14 = fig.add_subplot(223)
#plot_projections(data,1,2)
#plot_12v14 = fig.add_subplot(224)
#plot_projections(data,0,2)
#plt.plot()
which throws back:
'AxesSubplot' object has no attribute 'transFigure'
I'm using matplotlib 0.99.3, any help would be greatly appreciated, thanks!
I was searching for a way to create my 3D-plots with the nice fig, axes = plt.subplots(...) shortcut, but since I just browsed Matplotlib's mplot3d tutorial, I want to share a quote from the top of this site.
New in version 1.0.0: This approach is the preferred method of creating a 3D axes.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
Note
Prior to version 1.0.0, the method of creating a 3D axes was different. For those using older versions of matplotlib, change ax = fig.add_subplot(111, projection='3d') to ax = Axes3D(fig).
So if you have to use the <1.0.0 version of Matplotlib, this should be taken into account.
If you would like to use plt.subplots instead of plt.subplot (see the difference here), then you can do something like this one:
import matplotlib.pyplot as plt
from matplotlib import cm # for a scatter plot
from mpl_toolkits.mplot3d import Axes3D
fig, ax = plt.subplots(1,2,figsize=(10,10),subplot_kw=dict(projection='3d'))
sc1 = ax[0].scatter(x,y,z, c = true, cmap=cm.jet)
ax[0].set_title('True solution')
sc2 = ax[1].scatter(x,y,z c = y_pred, cmap=cm.jet)
ax[1].set_title('Predicted Solution')
Well, I don't know how to set individual axes as 3D using plt.subplots. It would be helpful if someone could comment down.
The preferred way of creating an 3D axis is giving the projection keyword:
def plotAll(data):
fig = plt.figure()
ax = fig.add_subplot(221, projection='3d')
for i,traj in enumerate(data.values()):
ax.plot3D([traj[0][-1]],[traj[1][-1]],[traj[2][-1]],".",color=[0.91,0.39,0.046])
plot_12v13 = fig.add_subplot(222)
plot_projections(data,0,1)
plot_13v14 = fig.add_subplot(223)
plot_projections(data,1,2)
plot_12v14 = fig.add_subplot(224)
plot_projections(data,0,2)
plt.plot()
Unfortunately, you didn't supply a working example with suitable data, so I couldn't test the code. Also, I would recommend updating to a newer version of matplotlib.