2

Suppose I have the following code (modified version of matplotlib gridspec tutorial)

import matplotlib.pyplot as plt

def make_ticklabels_invisible(fig):
    for i, ax in enumerate(fig.axes):
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
        for tl in ax.get_xticklabels() + ax.get_yticklabels():
            tl.set_visible(False)


plt.figure(0)
ax1 = plt.subplot2grid((3,3), (0,0), colspan=3)
ax2 = plt.subplot2grid((3,3), (1,0), colspan=2)
ax3 = plt.subplot2grid((3,3), (1, 2), rowspan=2)
ax4 = plt.subplot2grid((3,3), (2, 0))
plt.subplot2grid((3,3), (2, 1))  # OOPS! Forgot to store axes object

plt.suptitle("subplot2grid")
make_ticklabels_invisible(plt.gcf())
plt.show()

which results in

enter image description here

How can I 'extract' ax5 and plot it 'full screen' in a separate figure without having to recreate the plot?

Milo
  • 3,172
  • 3
  • 19
  • 21
  • Please post your code that you are using to generate the plot you see above. Always post your code, it makes it easier for others to help you. – alkasm Jun 27 '17 at 12:57
  • Thanks for the hint. I have reformulated the question. Cheers! – Milo Jun 27 '17 at 13:20

1 Answers1

2

I can't find anything in official documentation to back up what I'm saying, but my understanding is that it is impossible to "clone" an existing axes onto a new figure. In fact, no artist (line, text, legend) defined in one axes may be added to another axes. This discussion on Github may explain it to some degree.

For example, attempting to add a line from an axes defined on fig1 to an axes on a different figure fig2 raises an error:

import matplotlib.pyplot as plt
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
line, = ax1.plot([0,1])
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
ax2.add_line(line)
>>>RuntimeError: Can not put single artist in more than one figure`

And attempting to add a line that was drawn in ax1 to a second axes ax2 on the same figure raises an error:

fig1 = plt.figure()
ax1 = fig1.add_subplot(121)
line, = ax1.plot([0,1])
ax12 = fig1.add_subplot(122)
ax12.add_line(line)
>>>ValueError: Can not reset the axes.  You are probably trying to re-use an artist in more than one Axes which is not supported

The best recommendation I can make is extract the data from the axes you want to copy, and manually plot that into a new axes object that is sized to your liking. Something like below demonstrates this. Note that this works for Line2D objects plotted via ax.plot. If the data was plotted using ax.scatter, then you need to change things just a little bit and I refer you here for instructions on how to extract data from a scatter.

import matplotlib.pyplot as plt
import numpy as np

def rd(n=5):
    # Make random data
    return np.sort(np.random.rand(n))

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
# Plot three lines on one axes
ax1.plot(rd(), rd(), rd(), rd(), rd(), rd())

xdata = []
ydata = []
# Iterate thru lines and extract x and y data
for line in ax1.get_lines():
    xdata.append( line.get_xdata() )
    ydata.append( line.get_ydata() )

# New figure and plot the extracted data
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
for X,Y in zip(xdata,ydata):
    ax2.plot(X,Y)

Hope it helps.

saintsfan342000
  • 1,724
  • 1
  • 13
  • 16