如何将散景图保存为 PDF?

问题描述

我经常使用 bokeh,我正在寻找一种方法来根据我创建的图形创建 PDF。

有没有办法实现这个目标?

解决方法

三个python包bokehsvglibreportlab的组合非常适合我。

这将包括 3 个步骤:

  1. 创建散景 svg 输出
  2. 阅读此 svg
  3. 将此 svg 保存为 pdf

最小示例

要说明这是如何工作的,请参见以下示例。

from bokeh.plotting import figure
from bokeh.io import export_svgs
import svglib.svglib as svglib
from reportlab.graphics import renderPDF

test_name = 'bokeh_to_pdf_test'

# Example plot p
p = figure(plot_width=400,plot_height=400,tools="")
p.circle(list(range(1,6)),[2,5,8,2,7],size=10)
# See comment 1
p.xaxis.axis_label_standoff = 12
p.xaxis.major_label_standoff = 12

# step 1: bokeh save as svg
p.output_backend = "svg"
export_svgs(p,filename = test_name + '.svg')

# see comment 2
svglib.register_font('helvetica','/home/fonts/Helvetica.ttf')
# step 2: read in svg
svg = svglib.svg2rlg(test_name+".svg")

# step 3: save as pdf
renderPDF.drawToFile(svg,test_name+".pdf")

评论 1

有一个额外的信息用于 axis_label_standoffmajor_label_standoff,因为 x 轴的刻度在没有这个定义的情况下移动了一点,这看起来不太好。

评论 2

如果您收到一长串警告,例如

Unable to find a suitable font for 'font-family:helvetica'
Unable to find a suitable font for 'font-family:helvetica'
....
Unable to find a suitable font for 'font-family:helvetica'

这并不意味着创建了 pdf。出现此警告是因为散景中的默认字体名为 helveticasvglib 不知道该字体。 svglib 在定义的位置查找此字体。如果此字体不存在,则会显示该消息。

要清除此消息,您可以像这样在 svglib 中注册字体

#                    name in svglib,path to font
svglib.register_font('helvetica',f'/{PATH_TO_FONT}/Helvetica.ttf')

就在调用 svglib.svg2rlg() 之前。

输出

此代码将创建两次相同的图形,一个带有后缀 .svg,另一个带有后缀 .pdf

这个图是这样的:

example figure