1

I have a figure with many different plots (contour plots and lots of other stuff). I want to extract the contour plot to another single figure to see more details. But I fail how to do so.

Have a look on this code:

import numpy as np
from matplotlib import gridspec as gs, pyplot as plt

# Figure 1 with many different plots.
fig1 = plt.figure()
gridSpec = gs.GridSpec(2, 3)
for i in range(6):
    fig1.add_subplot(gridSpec[i])

# Create contour plot
x = np.arange(-3.0, 3.0, 0.02)
y = np.arange(-2.0, 2.0, 0.01)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) ** 4

# Plot it to a particular axes.
ax1 = fig1.axes[2]
contour = ax1.contour(X, Y, Z)

# Try to copy the contour plot to another figure (with only 1 subplot).
fig2, ax2 = plt.subplots()
# How to copy the content of ax1 to ax2?

plt.show()

This will give me the following:

ContourPlot

I want to create a second figure with only 1 subplot and its content should be the same as you can see in top right corner of the first figure with 6 subplots.

First thing I tried was

ax2.add_collection(contour.collections[1])

but I got the error message

RuntimeError: Can not put single artist in more than one figure

This is because the content is already plottet to figure 1, so it is not possible to plot it to figure 2 as well. So I tried to make a copy of the contour plot:

from copy import deepcopy
ax2.add_collection(deepcopy(contour.collections[1]))

But this will get me a new error that copiing is not possible ...

NotImplementedError: TransformNode instances can not be copied. Consider using frozen() instead.

So .. what can I do? Any ideas for that problem? :) Thanks a lot!

(Python 3.7.4, Matplotlib 3.1.1)

Max16hr
  • 438
  • 2
  • 5
  • 20
  • Matplotlib artists cannot be copied (I think the errors are clear enough). The alternative is to create two identical instances, one in figure 1, the other in figure 2, which should be as easy as `contour2 = ax2.contour(X, Y, Z)` in this case. – ImportanceOfBeingErnest Aug 05 '19 at 01:09
  • The point is that it takes lots of time to create the plot. (Here I just used a minimal example.) There is no way to copy the plot content? For simple lines it seems to be possible (https://stackoverflow.com/a/10503940/3401634) but not for LineCollections? – Max16hr Aug 05 '19 at 01:12
  • That answer copies the artist *before* it is added to an axes. But anyways, even if you were to succeed in copying the artist, you would not save much time, because the drawing step is what is expensive, not the artist creation. And both figures necessarily need to be drawn. – ImportanceOfBeingErnest Aug 05 '19 at 01:22
  • 1
    There is actually an alternative, which is to pickle the figure. This is shown in [pyplot - copy an axes content and show it in a new figure](https://stackoverflow.com/questions/45810557/pyplot-copy-an-axes-content-and-show-it-in-a-new-figure/45812071#45812071). I just tested the timing, and recreating the same artist twice is faster than pickling. (This is because pickling needs to also draw the figure, so dumping and loading just adds up to the timing.) – ImportanceOfBeingErnest Aug 05 '19 at 02:02

0 Answers0