I'm working with Bokeh a lot and I'm looking for a way to create a PDF from the figure I created.
Is there an option to achieve this goal?
This is possible with a combination of the three python package bokeh
, svglib
and reportlab
which works perfect for me.
This will include 3 steps:
Minimal Example
To show how this could work please see the following example.
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")
Comment 1
There is an extra information used for axis_label_standoff
and major_label_standoff
because the ticks of the x-axis are moving without this definition a bit up and this looks not so good.
Comment 2
If you get a long list of warnings like
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'
the pdf is still created. This warning appears because the default font in bokeh is named helvetica
, which is not known by svglib
. svglib
looks for this font at a defined place. If this font is not there, the message appears. This means bokeh will use its own default font instead.
To get rid of this message you can register a font in svglib
like this
# name in svglib, path to font
svglib.register_font('helvetica' , f'/{PATH_TO_FONT}/Helvetica.ttf')
right before calling svglib.svg2rlg()
.
Output
This code will create the same figure twice, once with the suffix .svg
and once with the suffix .pdf
.
The figure looks like this: