我想创建一个多页的PDF文件,使用python打印。我更喜欢在任何环境下都能正常工作的库,所以我尝试使用matplotlib。
我可以生成所需的A4大小的图形,并创建一个多页PDF文件,但图形艺术家缩小,不占用整个页面。
我可以生成一个A4大小的PDF页面,并在图形周围填充,也可以生成一个较小页面大小的PDF文件(页面在图形周围收缩以移除填充,图形保持相同大小)。
有人能帮忙吗?
(我不认为这是重复的,还有关于填充物的其他问题,但目的与我不同,我看不到任何对我有用的答案-我已经找了好几天了!)
到目前为止,我一直在尝试以下几个问题/答案:
bbox_inches='tight', pad_inches=0函数中使用pyplot.savefig(),这将提供一个小于A4 PDF的无填充页面。
(奇怪的是,这与EPS格式很好地配合,EPS格式直接以A4纸打印成实际大小,但我不知道如何从中创建多页文件。)
如果我不使用bbox_inches='tight', pad_inches=0,图形大小看起来差不多相同,但周围的填充填充填充了空间,使A4页。
使用保持填充的fig.tight_layout(rect=[0,0,1,1])fig.tight_layout(pad=0)
此示例代码生成EPS(A4无填充)、PDF(A4有填充)和TIFF(无填充,但尺寸较小,因此打印时有填充)中的图形:

import matplotlib.pyplot as plt
from matplotlib import gridspec

def plot_form_page():
    # A4 canvas
    fig_width_cm = 21                                # A4 page
    fig_height_cm = 29.7
    inches_per_cm = 1 / 2.54                         # Convert cm to inches
    fig_width = fig_width_cm * inches_per_cm         # width in inches
    fig_height = fig_height_cm * inches_per_cm       # height in inches
    fig_size = [fig_width, fig_height]

    plt.rc('text', usetex=False) # so that LaTeX is not needed when creating a PDF with PdfPages later on
    fig = plt.figure()
    fig.set_size_inches(fig_size)
    fig.set_facecolor('#9999ff')

    gs = gridspec.GridSpec(29, 21, wspace=0.1, hspace=0.1)

    # external axis
    ax0 = fig.add_subplot(gs[:, :])
    # for side in ["top", "bottom", "left", "right"]:
    #     ax0.spines[side].set_visible(False)

    # header
    ax1 = fig.add_subplot(gs[1:4, 1:4])
    ax1.set_facecolor('#bbffbb')

    ax2 = fig.add_subplot(gs[1:4, 4:-6])
    ax2.set_facecolor('#ffbbff')

    ax3 = fig.add_subplot(gs[1:4, -6:-1])
    ax3.set_facecolor('#00bbff')

    # form
    ax4, ax5, ax6, ax7   = [fig.add_subplot(gs[ 5+(i*6):10+(i*6), 1:10]) for i in range(4)]
    [ax8, ax9, ax10, ax11] = [fig.add_subplot(gs[ 5+(i*6):10+(i*6), 11:20]) for i in range(4)]
    axes = [ax4, ax8, ax5, ax9, ax6, ax10, ax7, ax11]
    for ax in axes:
        ax.set_facecolor('#bbbbbb')

    for ax in fig.axes:
        ax.set_xticks([])
        ax.set_yticks([])

    print(fig.properties()['figwidth'], fig.properties()['figheight'])

    # from previous tests:
    #fig.tight_layout(pad=0)

plot_form_page()

plt.savefig('page.tiff',
            dpi=300,
            orientation='portrait',
            box_inches='tight', pad_inches=0)
plt.savefig('page.pdf',
            dpi=300,
            orientation='portrait',
            bbox_inches='tight', pad_inches=0)
plt.savefig('page.eps',
            dpi=300,
            orientation='portrait',
            papertype='a4',
            bbox_inches='tight', pad_inches=0)

图properties()给出A4的正确大小(英寸):
fig.properties()['figwidth']
fig.properties()['figheight']

8.26771653543307 11.69291338582677
但这个数字会缩小,以便在打印时使用填充
您可以在以下PDF文件中看到效果:
https://www.dropbox.com/s/naqy9vj4ht6g2mv/Screenshot%202019-04-16%20at%2011.46.48.png?dl=0
使用EPS的问题较小:
https://www.dropbox.com/s/umycd8ofwod3nk5/Screenshot%202019-04-16%20at%2012.05.52.png?dl=0
(但同样,我不知道如何创建多页EPS)
对于TIFF文件,我得到的是相同的:
https://www.dropbox.com/s/eid1zstbm954121/Screenshot%202019-04-16%20at%2012.11.59.png?dl=0
这不一定是因为打印软件增加了填充——这个数字现在实际上更小了,因为300dpi时是1929××2655像素,这使得它比A4小了6.43×8.85英寸。
编辑:当然,这可以通过打印“适合页面”来解决,但这可以处理任何比例为A4的图像,如果可能的话,我想控制大小。

最佳答案

感谢@ImportanceOfBeingErnest的评论和一些尝试和错误,我找到了一个解决方案,它创建了一个A4形状的图形,当保存为A4 PDF页面时,它占据了整个页面(不是100%正确,有很小的边距,但它起到了作用)。
只需要添加gs.tight_layout(fig, pad=0)。我不完全明白为什么,但我怀疑当我试图消除figure对象的填充时(使用plt.savefig(..., bbox_inches='tight', pad_inches=0)fig.tight_layout(...)),图形可能会到达A4页的边框,但GridSpec不会,所以我看到的填充是在GridSpecfigure的边框之间,而不是与纸张的边框之间。当GridSpecfigure之间的填充设置为0,并且figure的大小为A4时,一切似乎都按我的要求进行。
(我仍然不明白为什么在某些情况下PDF文件的页面会缩小,但我将把它留在这里)。
这是我想要的代码,如果创建PDF文件,打开并检查属性,大小是A4,矩形靠近边框。对于其他选项,要么有一个宽的页边距,要么有一个较小的页面大小。

import matplotlib.pyplot as plt
from matplotlib import gridspec

def plot_form_page():
    # A4 canvas
    fig_width_cm = 21                                # A4 page
    fig_height_cm = 29.7
    inches_per_cm = 1 / 2.54                         # Convert cm to inches
    fig_width = fig_width_cm * inches_per_cm         # width in inches
    fig_height = fig_height_cm * inches_per_cm       # height in inches
    fig_size = [fig_width, fig_height]

    plt.rc('text', usetex=False) # so that LaTeX is not needed when creating a PDF with PdfPages later on
    fig = plt.figure()
    fig.set_size_inches(fig_size)
    fig.set_facecolor('#9999ff')

    gs = gridspec.GridSpec(29, 21, wspace=0.1, hspace=0.1)

    # external axis
    ax0 = fig.add_subplot(gs[:, :])
    # for side in ["top", "bottom", "left", "right"]:
    #     ax0.spines[side].set_visible(False)

    # header
    ax1 = fig.add_subplot(gs[1:4, 1:4])
    ax1.set_facecolor('#bbffbb')

    ax2 = fig.add_subplot(gs[1:4, 4:-6])
    ax2.set_facecolor('#ffbbff')

    ax3 = fig.add_subplot(gs[1:4, -6:-1])
    ax3.set_facecolor('#00bbff')

    # form
    ax4, ax5, ax6, ax7   = [fig.add_subplot(gs[ 5+(i*6):10+(i*6), 1:10]) for i in range(4)]
    [ax8, ax9, ax10, ax11] = [fig.add_subplot(gs[ 5+(i*6):10+(i*6), 11:20]) for i in range(4)]
    axes = [ax4, ax8, ax5, ax9, ax6, ax10, ax7, ax11]
    for ax in axes:
        ax.set_facecolor('#bbbbbb')

    for ax in fig.axes:
        ax.set_xticks([])
        ax.set_yticks([])

    #print(fig.properties()['figwidth'], fig.properties()['figheight'])

    gs.tight_layout(fig, pad=0)

plot_form_page()

plt.savefig('page.pdf',
            dpi=300,
            orientation='portrait')

关于python - 如何保存占据PDF文件整个页面的图,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55706943/

10-13 05:07