1

I currently have some code like this:

import numpy as np
import matplotlib.pyplot as plt

def generate_data():
    return np.random.randint(10, size=10)

plt.figure(1)
for i in range(4):
    plt.subplot(2, 2, i + 1)
    plt.plot(generate_data())

plt.savefig("C:\\test.pdf")

Suppose if want to generate 5 of these graph each with 4 pictures. How do I save them onto a pdf with the same page.

I have read a few answers on here talking about how to save figures. For example, this one

Python saving multiple figures into one PDF file

However, I don't understand how to create the figures needed.

Lost1
  • 990
  • 1
  • 14
  • 34

2 Answers2

3

Combining your code and the link you gave, this saves one pdf (output.pdf) with 5 pages, and on each page there is one figure:

import matplotlib.backends.backend_pdf
pdf = matplotlib.backends.backend_pdf.PdfPages("output.pdf")
import numpy as np
import matplotlib.pyplot as plt

def generate_data():
    return np.random.randint(10, size=10)

figs = []
n_figs = 5

for j in range(n_figs): # create all figures

    plt.figure(j)
    plt.suptitle("figure {}" .format(j+1))
    for i in range(4):
        plt.subplot(2, 2, i + 1)
        plt.plot(generate_data())

for fig in range(0, plt.gcf().number + 1): # loop over all figures
    pdf.savefig( fig ) # save each figure in the pdf
pdf.close()

EDIT: after the comment, here is version attempting to use less memory when lots of figures are produced. The idea is to save each figure once it is created, and then to close it.

for j in range(n_figs): # create all figures

    plt.figure(j)
    plt.suptitle("figure {}" .format(j+1))
    for i in range(4):
        plt.subplot(2, 2, i + 1)
        plt.plot(generate_data())
    pdf.savefig(j) # save on the fly
    plt.close() # close figure once saved

pdf.close()

EDIT2: here is a third version, I am unsure which of saves more memory. The idea now is, instead of creating and closing many figures, to create only one, save it, clear it, and reuse it.

plt.figure(1) # create figure outside loop

for j in range(n_figs): # create all figures

    plt.suptitle("figure {}" .format(j+1))
    for i in range(4):
        plt.subplot(2, 2, i + 1)
        plt.plot(generate_data())
    pdf.savefig(1) # save on the fly
    plt.clf() # clear figure once saved

pdf.close()

presenter
  • 384
  • 1
  • 9
  • those last 3 lines are exactly what i needed. thanks a lot. I have another question. namely, when there there are too many figures open, pycharm complains about memory usage. Is there a way of getting around this? Can we note save the figure once create it and somehow clears it from the cache? – Lost1 Nov 06 '19 at 22:09
  • I added a second version. Let me know if this works. – presenter Nov 06 '19 at 22:20
  • 1
    nice, nice... i think i finally got the hang of this. – Lost1 Nov 06 '19 at 22:31
  • https://stackoverflow.com/questions/58751355/matplotlib-writing-graphs-to-two-different-pdfs I asked another question related to this. :) – Lost1 Nov 07 '19 at 14:54
  • The link is dead now. Is your question somewhere else? – presenter Nov 07 '19 at 15:45
  • i solved it, it was not working because of something completely unrelated. – Lost1 Nov 07 '19 at 16:05
0

Like this.

fig, ax = plt.subplots(2, 2) 
for i in range(5):
    ax[i].plot(generate_data())
fig.savefig("C:\\test.pdf")
Lost1
  • 990
  • 1
  • 14
  • 34
Florian Bernard
  • 2,561
  • 1
  • 9
  • 22
  • can you elaborate a bit more. i don't quite follow this. What does ax[i] do? – Lost1 Nov 06 '19 at 22:02
  • note the function generate_data() is just a dummy function for illustrative purposes only. In practice, i want to plot each of the subplots in a for loop. – Lost1 Nov 06 '19 at 22:03