5

I'm currently trying to combine multiple plots into a single plot (with sub-plots). Please check out the following code:

import matplotlib.pyplot as plt

a = list(range(1,10))
b = list(map(lambda x: x**2, a))
c = list(map(lambda x: x**3, a))
d = list(map(lambda x: x+200, a))

plots = []

plt.plot(a, b)
plots.append(plt.gcf())
plt.close()

plt.plot(a, c)
plots.append(plt.gcf())
plt.close()

plt.plot(b, c)
plots.append(plt.gcf())
plt.close()

plt.plot(a, d)
plots.append(plt.gcf())
plt.close()

fig, ax = plt.subplots(len(plots))
for i,plot_obj in enumerate(plots, start=1):
    print(f"{i=}, {plot_obj=}")
    ax[i].set_figure(plot_obj)
    plot_obj.show()


plt.tight_layout()
plt.show()

# plt.savefig('temp.png')

The constraints I have are -

  1. The plots will be created earlier - I'm storing the figure objects in a list.
  2. These plots need to be accessed later on in the code and a single figure needs to be created with each of the plot as a sub-plot.

On running the above code, I'm encountering the error - RuntimeError: Can not put single artist in more than one figure while trying to set the figure of each sub-plot. The thought process is to set each sub-plots's figure with the saved figure object. Is there any way to accomplish this ?

Thanks!

5
  • why not using subplots, see here Commented Sep 30, 2020 at 11:55
  • @ted930511 It doesn't help. The link tells you how to plot multiple sub-plots, what I'm looking for is more specific than that. The plots are generated before, and later a single figure needs to be created by compiling all the plots. Commented Sep 30, 2020 at 13:20
  • 1
    I want this functionality because single figure is expensive to plot ? Commented Sep 30, 2020 at 13:31
  • The issue is that calling plt.figure() without arguments creates a new figure, so what your code appends to the plots list are those new figures and not the plots that you want. Commented Sep 30, 2020 at 13:54
  • @Arne Yes, you're correct. I've updated the code now. I can save the figures in files while traversing through the plots, but I'm not able to build the final plot with the sub-plots as each saved plot. Commented Oct 1, 2020 at 13:02

2 Answers 2

2

If you save the individual plots to files, you can later use imshow() and imread() from the matplotlib.image library to piece them together into one plot:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

a = list(range(1,10))
b = list(map(lambda x: x**2, a))
c = list(map(lambda x: x**3, a))
d = list(map(lambda x: x+200, a))

def save_plot(x, y, name):
    fig, ax = plt.subplots()
    ax.plot(x, y)
    ax.figure.savefig(name)
    plt.close()
        
save_plot(a, b, 'plot1')
save_plot(a, c, 'plot2')
save_plot(b, c, 'plot3')
save_plot(a, d, 'plot4')

fig, axs = plt.subplots(2, 2)
for i, ax in enumerate(axs.flat):
    ax.set_axis_off()
    filename = 'plot' + str(i+1) + '.png'
    ax.imshow(mpimg.imread(filename))
plt.show()

You may want to look into the imshow() documentation to reduce the whitespace around each subplot.

Sign up to request clarification or add additional context in comments.

1 Comment

This isn't exactly what I was looking for, but it's a good workaround. Thanks @Arne !
1

This may not be the cleanest way to write it, but I guess it does what you want:

a = list(range(1,10))
b = list(map(lambda x: x**2, a))
c = list(map(lambda x: x**3, a))
d = list(map(lambda x: x+200, a))

plots = []

fig=plt.figure()
plt.plot(a, b)
plots.append(fig)
plt.close()

fig=plt.figure()
plt.plot(a, c)
plots.append(fig)
plt.close()

fig=plt.figure()
ax3= plt.plot(b, c)
plots.append(fig)
plt.close()

fig=plt.figure()
plt.plot(a, d)
plots.append(fig)
plt.close()

fig,axs =plt.subplots(2,2)
axs[0,0].plot(a,b)
axs[0,1].plot(a,c)
axs[1,0].plot(b,c)
axs[1,1].plot(a,d)
plt.tight_layout()

plt.savefig('temp.png')

1 Comment

Thanks. But it's not what I'm looking for. Your code saves the figure objects in plots list, but doesn't make use of them during the final figure (with subplot) creation. Moreover, each sub-plot is created by plotting the data again. Basically, the last few LOCs does the whole work. I need the plot objects to be saved first and then later on use them in sub-plots. The thing is, my project won't have access to the data (a,b,c,d) when building the final figure, only the figure objects will be there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.