Python matplotlib:多页保存为pdf

2024-06-16 08:44:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我正努力做到以下几点:

我使用matplotlib创建了一个图形,其中包含几个子图。 更具体地说,2x4子批次

输出非常适合在屏幕上显示,但不能保存为pdf格式。在

如果我只使用save_fig,它将打印一个带有2x4网格的单页pdf文档。在

我想做的是重新排列我的子图,比如说一个2x4的网格(选择哪个子图放在哪里是好的,但不是必要的),然后将其打印到一个2页的pdf文件中,每个子图有4个子图。(为了能够适合A4页面大小)

这可能吗?在

提前谢谢你!在


Tags: 文件文档图形网格pdf屏幕matplotlibsave
2条回答

我建议创造3个数字。一个用于显示,2个用于保存和打印相同的数据。在

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()

由于我的工作需要一些类似的东西,我花了一些努力来实现根据显示介质将图分组为图形的过程的自动化。起初,我有一个想法,每一个绘图只做一次,只需将子图添加到要保存在pdf中的图形中,但遗憾的是,根据this answer中的一条评论,这是不可能的,所以所有的东西都需要重新绘制。代码显示了如何使用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()

核心函数plot_funcs接受max_col和{}关键字,然后用相应数量的子图创建图形。然后,它循环遍历要绘制的给定函数列表,每个函数都在自己的子批中。将删除未使用的子批次。最后返回所有数字的列表。在

在我的例子中,我有9个不同的功能,我首先在屏幕上以2x3布局显示(总共有两个图形,一个有6个子图,一个有3个子图)。如果用户满意,则在2x4布局中重做绘图(同样是两张图,但这次一张有8个子图,1张图有1个子图),然后保存到名为multipage_pdf.pdf的文件中,紧跟着example in the documentation。在

在Python3.5上测试

相关问题 更多 >