Does this solve your problem?
x = [ 1, 2, 3, 5, 10, 100, 1000 ]
y1 = [ 1, 0.822, 0.763, 0.715, 0.680, 0.648, 0.645 ]
y2 = [ 1, 0.859, 0.812, 0.774, 0.746, 0.721, 0.718 ]
import matplotlib.pyplot as plt
from matplotlib.transforms import BlendedGenericTransform
# mode 01 from one case
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
line1, = ax1.plot( x, y1, label='mode 01' )
# mode 01 from other case
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
line2, = ax2.plot( x, y2, label='mode 01' )
# Create new figure and two subplots, sharing both axes
fig3, (ax3, ax4) = plt.subplots(1,2,sharey=True, sharex=True,figsize=(10,5))
# Plot data from fig1 and fig2
line3, = ax3.plot(line1.get_data()[0], line1.get_data()[1])
line4, = ax4.plot(line2.get_data()[0], line2.get_data()[1])
# If possible (easy access to plotting data) use
# ax3.plot(x, y1)
# ax4.lpot(x, y2)
ax3.set_ylabel('y-axis')
ax3.grid(True)
ax4.grid(True)
# Add legend
fig3.legend((line3, line4),
('label 3', 'label 4'),
loc = 'upper center',
bbox_to_anchor = [0.5, -0.05],
bbox_transform = BlendedGenericTransform(fig3.transFigure, ax3.transAxes))
# Make space for the legend beneath the subplots
plt.subplots_adjust(bottom = 0.2)
# Show only fig3
fig3.show()
This gives output as seen below
Edit
Looking at the code in your uploaded zip-file, I'd say most of the requested functionality is achieved?
I see you have changed the function creating the plots, making the solution to your problem radically different, as you are no longer trying to "merge" two subplots from different figures. Your solution is basically the same as the one I presented above, in the sense that both are creating both Axes
instances as subplots on the same figure (giving the desired layout), and then plotting, rather than plotting, then extract/move the axes, as your question was concerning originally.
As I suspected, the easiest and most trivial solution is to make the individual Axes
subplots of the same figure instead of having them tied to separate figures, as moving one Axes
instance from one Figure
to another is not easily accomplished (if at all possible), as specified in a comment. The "original" problem still seems to be very hard to accomplish, as simply adding an Axes
instance to the Figure
's _axstack
makes it hard to customize to the desired layout.
One modification to the ax.legend(...
of your current code, to make the legend centered horizontally, with the top just below the axes:
# Add this line
from matplotlib.transforms import BlendedGenericTransform
# Edit the function call to use the BlendedGenericTransform
ax.legend(loc='upper center',
ncol=7,
labelspacing=-0.7,
columnspacing=0.75,
fontsize=8,
handlelength=2.6,
markerscale=0.75,
bbox_to_anchor=(0.5, -0.05),
bbox_transform=BlendedGenericTransform(fig.transFigure, ax.transAxes))
Here, the bbox_to_anchor
argument should be customized to fit within the boundaries of our figure.
The BlendedGenericTransform
allows the transforms of the x-axis and y-axis to be different, which can be very useful in many situations.