2017-06-21 4 views
1

Je suis en train de faire ce qui suit:Python matplotlib: Enregistrer au format PDF en plusieurs pages

J'ai créé un personnage, en utilisant matplotlib, avec plusieurs intrigues secondaires. Plus précisément, sous-boîtes 2x4

La sortie est géniale pour l'afficher à l'écran, mais pas pour l'enregistrer au format PDF.

Si j'utilise simplement save_fig, il imprime un document pdf d'une seule page, avec la grille 2x4. Ce que je voudrais faire, c'est réorganiser mes sous-placettes, disons une grille de 2x4 (choisir quelle sous-placette va où, ce serait bien, mais pas nécessaire) et l'imprimer en pdf de 2 pages avec 4 sous-parcelles chacun. (afin de pouvoir l'adapter au format de page A4)

Est-ce possible?

Nous vous remercions d'avance!

+1

Je pense que vous devrez diviser le chiffre « manuellement » en deux et les enregistrer dans le même fichier pdf. –

+1

vous pouvez enregistrer des pdf de plusieurs pages avec 'PdfPages': https://matplotlib.org/examples/pylab_examples/multipage_pdf.html mais vous aurez probablement besoin de créer deux objets de figure pour le faire – tom

+0

J'ai vu l'exemple de plusieurs pages code, mais je voudrais garder la mise en page actuelle pour la visualisation, et créer une nouvelle mise en page pour l'enregistrement. Je n'arrive pas à trouver un moyen d'obtenir les sous-placettes de la figurine originale, et de les réarranger à une nouvelle ... – GSta

Répondre

2

Je suggère de créer 3 chiffres. Un pour montrer et 2 pour sauver et tracer les mêmes données à eux.

import matplotlib.pyplot as plt 
import numpy as np 


data = np.sort(np.cumsum(np.random.rand(24,16), axis=0), axis=0) 

def plot(ax, x, y, **kwargs): 
    ax.plot(x,y, **kwargs) 

colors = ["crimson", "indigo", "limegreen", "gold"] 
markers = ["o", "", "s", ""] 
lines = ["", "-", "", ":"] 

# figure 0 for showing 
fig0, axes = plt.subplots(nrows=2,ncols=4) 

for i, ax in enumerate(axes.flatten()): 
    plot(ax, data[:,2*i], data[:,2*i+1], marker=markers[i%4], ls=lines[i%4],color=colors[i%4]) 


# figure 1 for saving 
fig1, axes = plt.subplots(nrows=1,ncols=4) 
for i, ax in enumerate(axes.flatten()): 
    plot(ax, data[:,2*i], data[:,2*i+1], marker=markers[i], ls=lines[i],color=colors[i]) 

#figure 2 for saving 
fig2, axes = plt.subplots(nrows=1,ncols=4) 
for i, ax in enumerate(axes.flatten()): 
    plot(ax, data[:,2*i+4], data[:,2*i+1+4], marker=markers[i], ls=lines[i],color=colors[i]) 

#save figures 1 and 2 
fig1.savefig(__file__+"1.pdf") 
fig2.savefig(__file__+"2.pdf") 

#close figures 1 and 2 
plt.close(fig1) 
plt.close(fig2) 
#only show figure 0 
plt.show() 
1

Comme je l'ai besoin quelque chose de semblable pour mon travail, je mets un peu d'effort dans l'automatisation du processus de regroupement des parcelles en chiffres en fonction du support d'affichage. Au début, j'ai eu l'idée de faire chaque parcelle une seule fois et d'ajouter les sous-parcelles aux figures à enregistrer dans le pdf, mais malheureusement, selon un commentaire en this answer, ce n'est pas possible, donc tout doit être reprogrammé . Le code montre l'idée générale de la façon dont cela peut être automatisé en utilisant PdfPages:

from matplotlib import pyplot as plt 
import numpy as np 
from matplotlib.backends.backend_pdf import PdfPages 


def niter(iterable, n): 
    """ 
    Function that returns an n-element iterator, i.e. 
    sub-lists of a list that are max. n elements long. 
    """ 
    pos = 0 
    while pos < len(iterable): 
     yield iterable[pos:pos+n] 
     pos += n 


def plot_funcs(x, functions, funcnames, max_col, max_row): 
    """ 
    Function that plots all given functions over the given x-range, 
    max_col*max_row at a time, creating all needed figures while doing 
    so. 
    """ 

    ##amount of functions to put in one plot  
    N = max_col*max_row 

    ##created figures go here 
    figs = [] 

    ##plotted-on axes go here 
    used_axes = [] 

    ##looping through functions N at a time: 
    for funcs, names in zip(niter(functions, N), niter(funcnames,N)): 

     ##figure and subplots 
     fig, axes = plt.subplots(max_col, max_row) 

     ##plotting functions 
     for name,func,ax in zip(names, funcs, axes.reshape(-1)): 
      ax.plot(x, func(x)) 
      ax.set_title(name) 
      used_axes.append(ax) 

     ##removing empty axes: 
     for ax in axes.reshape(-1): 
      if ax not in used_axes: 
       ax.remove() 

     fig.tight_layout() 
     figs.append(fig) 

    return figs 

##some functions to display 
functions = [ 
    lambda x: x, lambda x: 1-x, lambda x: x*x, lambda x: 1/x, #4 
    np.exp, np.sqrt, np.log, np.sin, np.cos,     #5 
    ] 
funcnames = ['x','1-x', 'x$^2$', '1/x', 'exp', 'sqrt', 'log', 'sin','cos'] 

##layout for display on the screen 
disp_max_col = 3 
disp_max_row = 2 

##layout for pdf 
pdf_max_col = 2 
pdf_max_row = 4 

##displaying on the screen: 
x = np.linspace(0,1,100) 
figs = plot_funcs(x, functions, funcnames, disp_max_row, disp_max_col) 
plt.show() 


##saving to pdf if user wants to: 
answer = input('Do you want to save the figures to pdf?') 
if answer in ('y', 'Y', 'yes', ''): 

    ##change number of subplots 
    N = disp_max_col*disp_max_row 
    figs = plot_funcs(x, functions, funcnames, pdf_max_row, pdf_max_col) 

    ##from https://matplotlib.org/examples/pylab_examples/multipage_pdf.html 
    with PdfPages('multipage_pdf.pdf') as pdf: 
     for fig in figs: 
      plt.figure(fig.number) 
      pdf.savefig() 

La fonction de base, plot_funcs prend max_col et max_row mots-clés et crée ensuite les chiffres avec la quantité selon des intrigues secondaires. Il boucle ensuite à travers une liste donnée de fonctions à tracer, chacune sur son propre sous-schéma. Les sous-plans inutilisés sont supprimés. Enfin, une liste de toutes les figures est renvoyée. Dans mon exemple, j'ai 9 fonctions différentes, que je montre d'abord sur l'écran dans une disposition 2x3 (faisant un total de deux figures, une avec 6 sous-placettes et une avec 3 sous-placettes). Si l'utilisateur est satisfait, les tracés sont refaits dans une disposition 2x4 (encore deux chiffres, mais cette fois-ci avec 8 intrigues secondaires et 1 avec 1 intrigue secondaire), puis enregistrés dans un fichier appelé multipage_pdf.pdf, en suivant le example in the documentation.

testé sur python 3.5