【问题标题】:bounding box problems saving to pdf保存为 pdf 的边界框问题
【发布时间】:2013-10-24 04:23:40
【问题描述】:

我需要将 matplotlib 数字保存为 pdf。我按照Matplotlib howto 上的说明进行操作,但我不显示结果,而是将其保存为 pdf。奇怪的是,pdf 画布不受画布调整大小的影响。相反,保存为 png 可以正常使用放大的画布。

import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10))
ax.set_yticks((2,5,7))
labels = ax.set_yticklabels(('really, really, really', 'long', 'labels'))

def on_draw(event):
    bboxes = []
    for label in labels:
        bbox = label.get_window_extent()
        # the figure transform goes from relative coords->pixels and we
        # want the inverse of that
        bboxi = bbox.inverse_transformed(fig.transFigure)
        bboxes.append(bboxi)

    # this is the bbox that bounds all the bboxes, again in relative
    # figure coords
    bbox = mtransforms.Bbox.union(bboxes)
    if fig.subplotpars.left < bbox.width:
        # we need to move it over
        fig.subplots_adjust(left=1.1*bbox.width) # pad a little
        fig.canvas.draw()
    return False

fig.canvas.mpl_connect('draw_event', on_draw)

plt.savefig("test.pdf", format="pdf")

screen capture of pdf image

更新

plt.tight_layout()

对标题和轴刻度执行此操作,但如果将图例放置在框架之外,则忽略图例,如下图所示。请注意,我将图例放在了图的右侧。

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
p1, = plt.plot(range(10))
p2, = plt.plot(range(10,0,-1))
ax.set_yticks((2,5,7))
plt.labels = ax.set_yticklabels(('really, really, really', 'long', 'labels'))
plt.legend([p2, p1], ["line with a loong label", "line with an even longer label, dude!"],\
           loc="center left", bbox_to_anchor=(1, 0.5))
plt.tight_layout()
plt.savefig("test.pdf", format="pdf")

【问题讨论】:

标签: python pdf matplotlib bounding-box


【解决方案1】:

一种可能的破解方法是将plt.tight_layout() 替换为

plt.tight_layout(rect = [0, 0, 0.4, 1])

但这不是很好。对我有用的是使用参数bbox_inches

plt.savefig("test.pdf", format="pdf", bbox_inches = 'tight')

【讨论】:

  • bbox_inches='tight' 的缺点是您无法控制最终数字的大小。如果您要尝试匹配标签的字体大小和嵌入图形的文本,这可能非常重要。
  • @tcaswell 好点。这是一个警告,但在大多数情况下它不会使该方法无效。
【解决方案2】:

使用可以试试这个例子并解决你的问题。

import matplotlib.pyplot as plt
import numpy as np
sin, cos = np.sin, np.cos

fig = plt.figure(frameon = False)
fig.set_size_inches(5, 8)
ax = plt.Axes(fig, [0., 0., 1., 1.], )
ax.set_axis_off()
fig.add_axes(ax)

x = np.linspace(-4, 4, 20)
y = np.linspace(-4, 4, 20)
X, Y = np.meshgrid(x, y)
deg = np.arctan(Y**3-3*Y-X)
plt.quiver(X, Y, cos(deg), sin(deg), pivot = 'tail', units = 'dots', color = 'red', )
plt.savefig('/tmp/test.png', dpi = 200)

您可以通过将图形设置为 5x8 英寸来使结果图像为 1000x1600 像素

fig.set_size_inches(5, 8)
and saving with DPI = 200:

plt.savefig('/tmp/test.png', dpi = 200)
The code to remove the border was taken from here.

(The image posted above is not to scale since 1000x1600 is rather large).

【讨论】:

  • 该问题与定义或保存到 png 无关。问题是保存到 pdf.
猜你喜欢
  • 2020-01-18
  • 1970-01-01
  • 2019-05-19
  • 2018-07-09
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
相关资源
最近更新 更多