Home > Software design >  Adding a subplot to a figure produced by a function
Adding a subplot to a figure produced by a function

Time:09-21

I use the enter image description here

Problem: as you can see, the lower plot (irf plot) is clipped off. When I add plt.subplots_adjust(hspace = 10), I get:

enter image description here

This helps a bit but at the cost of reducing the size of the top subplot, which is undesirable.

Question: How can I get both subplots of equal size without any clippings. I wish I could start with fig, (ax1, ax2) = plt.subplots(2,1) and then pass ax1 to the irf.plot(). Then I could have control over both axes. But apparently there is no way to pass an ax to irf.plot(). it just creates its own figure. I would even be satisfied with creating the two figures separately and then joining them and saving them as one figure, if there is a way for that.

CodePudding user response:

The essential problem here is that irf.plot is creating a figure with a single subplot on it (one row, one column). You then add a second subplot with add_subplot(211), which is telling matplotlib to arrange it in the top row of a 2-row configuration. But the original subplot is not being altered, so part of it is hidden by the new subplot (ax1).

irf.plot doesn't appear to have any options to control this at the time of creation as far as I can see.

But what we can do is modify the subplot position using GridSpec after creation (e.g. like in this answer), before adding the new subplot.

For example, something like this might work:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

irf = results.irf()
fig = irf.plot(plot_stderr=False, impulse=columns[1], response=columns[0])

# Change position of irf plot axes
ax_irf = fig.get_axes()[0]
gs = gridspec.GridSpec(nrows=2, ncols=2)
ax_irf.set_position(gs[0, 0].get_position(fig))
ax_irf.set_subplotspec(gs[0, 0])  # this might be superfluous

# Now add second subplot
ax1 = fig.add_subplot(gs[1, 0])          

ax1.plot(df[columns].dropna().index, df[columns].dropna().iloc[:, 1], color='red')
ax1.tick_params(axis='y', labelcolor='red')

ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis
ax2.plot(df[columns].dropna().index, df[columns].dropna().iloc[:, 0], color='blue')
ax2.tick_params(axis='y', labelcolor='blue')
  • Related