W. MacTurk
W. MacTurk

Reputation: 170

Python3 - Plotting the same matplotlib axes object on multiple figures?

I have a script which I'm adapting to include a GUI. In it, I create a plot with subplots (the arrangement of which depends on the number of plots - e.g. 4 plots go into a square rather than 4-across). That plot (with a subplot for each of the "targets" analyzed) gets saved to a .png.

In building the GUI, I'm writing up the 'results' frame and would like to show these individual subplots on their own tabs. I've written the code to lay out the frame how I want it, but in order to separate the subplots into their own plots, I need to draw the completed Axes object (e.g. the entire subplot for that target) onto a new figure in the frame.

Since the number of subplots isn't known before runtime, I already have my Axes objects/subplots in an array (/list?) axs, whose members are the individual Axes objects (each containing data points created with ax.scatter() and several lines and annotations created with ax.plot() and ax.annotate).

When I initially create the axes, I do so with

fig, axs = plt.subplots(num='Title', nrows=numrow, ncols=numcol, 
                        figsize=[numcol*5, numrow*5], 
                        subplot_kw={'adjustable':'box', 'aspect':1})

Is there a way to now take these axes and draw them onto a new figure (the one that will be contained in the 'results' frame of the GUI)? In my searches, I only came up with ways to plot multiple axes onto a single figure (i.e. how to use subplots()) but nothing came up on how I'd throw a pre-existing Axes object into a new figure that it wasn't originally associated with. I'd rather not re-draw the axes from scratch -- there's quite a bit of decoration and multiple datasets / lines plotted onto them already.

Any ideas? Happy to post code as requested, but since this more of a "How do I do this" than a "why doesn't my code work", I didn't post much of it.

Thank you!

Upvotes: 5

Views: 2055

Answers (1)

john-hen
john-hen

Reputation: 4856

I believe that's not possible and you will have to recreate the Axes objects inside the other figure. Which is just a matter of code reorganization. Note that your approach would not noticeably improve rendering performance. Matplotlib would have to re-render the Axes objects anyway, and that's the computationally expensive part. Creating the objects is relatively cheap.

What you're trying to do is pretty much this:

from matplotlib import pyplot

pyplot.ion()

figure1 = pyplot.figure()
axes = figure1.add_subplot()
axes.plot([0, 1], [0, 1])

figure2 = pyplot.figure()
figure2.add_axes(axes)

Which raises:

ValueError: The Axes must have been created in the present figure

And the documentation of add_axes() notes:

In rare circumstances, add_axes may be called with a single argument, an Axes instance already created in the present figure but not in the figure's list of Axes.

So that's a pretty clear indication that this is not a supported use case.

Upvotes: 2

Related Questions