user1718097
user1718097

Reputation: 4292

Second Matplotlib figure doesn't save to file

I've drawn a plot that looks something like the following:

enter image description here

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:

  1. Create the first figure and plot 3 separate axes using a loop
  2. 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.
  3. 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.

Upvotes: 1

Views: 2473

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339072

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).

Upvotes: 2

Related Questions