Bokeh 图表导出完整指南:基于 Playwright 后端的 PNG 与 SVG 输出
发布时间:2026/9/14 14:39:33来源:尧图网络
Bokeh 图表导出完整指南基于 Playwright 后端的 PNG 与 SVG 输出【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokehBokeh 提供了从 Python 侧将图表、布局与控件导出为 PNG 与 SVG 文件的能力其核心是无头浏览器渲染 截图 / DOM 提取的导出流水线。本文以仓库中 export.rst 为骨架系统讲解导出依赖的安装、后端选择、export_png/export_svg/export_svgs等函数的完整用法并结合 src/bokeh/io/export.py、src/bokeh/io/browser.py 等源码揭示其底层实现原理。读完本文你将能独立完成把 Bokeh 图保存成高清 PNG、把矢量图导出为可编辑 SVG的完整工作流并能理解后端切换与参数调优的关键。导出功能的额外依赖无头浏览器后端Bokeh 的导出功能并非纯 Python 实现——它需要把一个布局渲染进真实浏览器环境再截取结果。因此使用导出函数前必须先准备一个无头浏览器后端。当前 Bokeh 默认使用Playwright同时为了兼容旧代码暂时保留了已弃用的Selenium后端src/bokeh/io/export.py中通过ExportBackendType Literal[selenium, playwright]定义后端类型。使用 Playwright默认后端Playwright 是 Bokeh 的默认导出后端。安装可选导出依赖与 Chromium 无头 Shell 即可pip install bokeh[export] playwright install --only-shell chromium其中bokeh[export]这一 extra 依赖在仓库 pyproject.toml 中定义为playwright 1.49。也可以单独安装playwright包无需手动管理浏览器驱动二进制——Bokeh 导出只要求 Chromium 的 headless shell这大大简化了环境搭建。从源码看Playwright 后端位于 src/bokeh/io/browser.py其启动 Chromium 时使用了以下参数见_PlaywrightState._ensure_browser--hide-scrollbars隐藏滚动条避免截图出现多余元素--force-device-scale-factor{scale_factor}按scale_factor控制设备像素比实现高分辨率导出--force-color-profilesrgb强制 sRGB 色彩空间保证颜色一致性。若 Chromium headless shell 未安装启动会抛出RuntimeError并提示运行playwright install --only-shell chromium。使用 Selenium已弃用Selenium后端自 4.0.0 起被弃用并将在未来版本移除新代码应使用 Playwright。Selenium 方案要求安装seleniumPython 包并把浏览器驱动二进制放到 PATH 中Firefox 使用geckodriverChrome / Chromium 使用ChromeDriver。文档给出了 conda 与 pip 两种安装路径conda 安装推荐便于保证驱动与浏览器版本匹配# Selenium geckodriverFirefox conda install selenium geckodriver -c conda-forge # geckodriver 需要系统中有兼容的 Firefox也可以从 conda-forge 安装 conda install firefox -c conda-forge # Selenium ChromeDriverChrome conda install selenium python-chromedriver-binary -c conda-forgepip 安装pip install selenium # 然后从 geckodriver 发布页下载 geckodriver 二进制并放入 PATHFirefox 方案 pip install selenium chromedriver-binary # 并确保 chromedriverWindows 下为 chromedriver.exe位于 PATHChrome 方案使用 ChromeDriver 时需要保证 ChromeDriver 与系统中的 Chrome / Chromium 版本兼容。此外Selenium 后端还有两个补充配置入口create_firefox_webdriver与create_chromium_webdriver见 src/bokeh/io/webdriver.py前者依赖 PATH 中的firefox与geckodriver后者会优先读取settings.chromedriver_path()找不到时再在 PATH 中依次查找chromedriver、chromium.chromedriver、chromedriver-binary仍找不到则报错并提示可用BOKEH_CHROMEDRIVER_PATH指定位置。选择导出后端环境变量、参数与全局设置Bokeh 默认使用 Playwright。你可以通过以下三种方式指定后端且优先级各不相同1. 环境变量——设置BOKEH_EXPORT_BACKEND取值auto、playwright、seleniumBOKEH_EXPORT_BACKENDplaywright python my_script.py该环境变量对应的全局设置在 src/bokeh/settings.py 中定义PrioritizedSetting(export_backend, BOKEH_EXPORT_BACKEND, defaultplaywright)默认值即playwright。2. 每次调用传参——直接把backend传给任意导出函数from bokeh.io import export_png export_png(plot, filenameplot.png, backendplaywright)3. 全局设置——修改settings.export_backendfrom bokeh.settings import settings settings.export_backend playwrightwebdriver关键字参数所有导出函数还接受webdriver参数可以直接传入一个浏览器实例——既可以是 Selenium 的WebDriver也可以是 Playwright 的Browser/BrowserContext。后端会根据传入实例的类型自动判断并覆盖backend参数与export_backend设置。传入 SeleniumWebDriver会走已弃用的 Selenium 后端并触发弃用警告。auto的语义auto会优先尝试 Playwright当 Playwright 未安装时回退到已弃用的 Selenium 后端。上述优先级在源码 src/bokeh/io/export.py 的_resolve_backend中有完整实现传入的是 PlaywrightBrowser/BrowserContext→ 始终用 Playwright 后端传入的是其他Seleniumdriver → 始终用 Selenium 后端显式指定了backend→ 使用该后端否则回退到BOKEH_EXPORT_BACKEND设置设置为auto时先探测playwright是否可导入其次探测selenium两者都未安装则抛出RuntimeError提示安装命令。导出 PNG 图像export_png函数可以把布局渲染为 RGBA 格式的 PNG 图片它在内存中完成渲染并截图输出图片尺寸与源布局一致。基本用法与save、show类似from bokeh.io import export_png export_png(plot, filenameplot.png)仓库中提供了可直接运行的完整示例 examples/output/export/export_to_png.py它用autompg_clean采样数据构造一个分组柱状图后调用export_png(p, filenameplot.png)from bokeh.io.export import export_png from bokeh.palettes import Spectral5 from bokeh.plotting import figure from bokeh.sampledata.autompg import autompg_clean as df from bokeh.transform import factor_cmap df.cyl df.cyl.astype(str) df.yr df.yr.astype(str) group df.groupby([cyl, mfr]) index_cmap factor_cmap(cyl_mfr, paletteSpectral5, factorssorted(df.cyl.unique()), end1) p figure(width800, height300, titleMean MPG by # Cylinders and Manufacturer, x_rangegroup, toolbar_locationNone, tooltips[(MPG, mpg_mean), (Cyl, Mfr, cyl_mfr)]) p.vbar(xcyl_mfr, topmpg_mean, width1, sourcegroup, line_colorwhite, fill_colorindex_cmap) p.y_range.start 0 p.x_range.range_padding 0.05 p.xgrid.grid_line_color None p.xaxis.axis_label Manufacturer grouped by # Cylinders p.xaxis.major_label_orientation 1.2 p.outline_line_color None export_png(p, filenameplot.png)透明背景若要生成透明背景的 PNG将Plot.background_fill_color与Plot.border_fill_color设为Noneplot.background_fill_color None plot.border_fill_color None尺寸可变性sizing mode警告响应式 sizing 模式responsive 等可能生成尺寸与宽高比不符合预期的布局。为了导出结果稳定可靠请使用默认的fixedsizing 模式。这一警告在 src/bokeh/io/export.py 的函数文档字符串中同样有标注。export_png参数详解从 src/bokeh/io/export.py 的函数签名与文档看完整参数如下参数类型说明objUIElement或Document要导出的布局Row/Column、Plot、控件或 DocumentfilenamePathLike如 str、Path可选保存文件名默认从脚本名推导如/foo/myplot.py生成/foo/myplot.png不可用时使用临时文件width/heightint可选仅当obj是 Plot 实例时生效的期望导出尺寸否则忽略scale_factorfloat默认1输出 PNG 的缩放因子可在保持元素相对比例的前提下获得更高分辨率webdriverSeleniumWebDriver或 PlaywrightBrowser/BrowserContext自定义浏览器实例后端自动检测timeoutint默认5等待 Bokeh 初始化的最长时间秒1.1.1 起引入stateState可选指定状态对象为None时使用当前隐式状态backendplaywright或selenium可选导出后端为None时使用BOKEH_EXPORT_BACKEND设置默认 Playwrightexport_png返回保存后的文件绝对路径如果截图宽或高为 0会抛出ValueError(unable to save an empty image)。直接获取图像对象get_screenshot_as_png如果不想落盘只想在代码中拿到图像对象可使用底层函数bokeh.io.export.get_screenshot_as_pngfrom bokeh.io.export import get_screenshot_as_png image get_screenshot_as_png(obj, heightheight, widthwidth, driverwebdriver)该函数返回PIL.Image.Image对象其内部实现见 src/bokeh/io/export.py会先通过_resolve_backend选出后端模块再调用对应后端的get_screenshot_as_png最终对截图做 RGBA 转换、按 DPR 裁剪并依据scale_factor缩放。注意这里的关键字参数名是driver而非webdriver用于接收 Selenium WebDriver 或 Playwright Browser / BrowserContext。导出 SVG 图像Bokeh 还可以用 SVG 元素替换默认的 HTML5 Canvas 绘图输出。SVG 是矢量格式可在 Adobe Illustrator 等图形软件中编辑或进一步转换为 PDF。需要说明的是SVG 后端的渲染性能不如默认的 Canvas 后端当图形元素glyph数量大或交互操作如平移频繁时尤其明显。因此在交互密集的 Web 场景下建议保持 Canvas仅在需要矢量输出时才切换到 SVG。激活 SVG 后端设置Plot.output_backend为svg即可# 方式一构造时指定 plot Plot(output_backendsvg) # 方式二创建后赋值 plot.output_backend svg与 PNG 一样设置background_fill_color None与border_fill_color None可以生成透明背景的 SVG。代码导出export_svg与export_svgs两种工具函数分别适用于合并为单个 SVG与拆分为独立 SVG两种需求from bokeh.io import export_svg # 把单个 plot 或整个布局保存为一个 SVG 文件 export_svg(plot, filenameplot.svg) from bokeh.io import export_svgs # 把布局中每个启用 SVG 的 plot 导出为相互独立的 SVG 文件 export_svgs(plot, filenameplot.svg)两个函数都返回文件名字符串列表src/bokeh/io/export.py。底层写文件逻辑_write_collection会为多个输出自动添加序号后缀第一个文件用给定文件名后续文件命名为plot_1.svg、plot_2.svg……。export_svgs在布局中没有找到任何 SVG 启用的 Plot 时会记录No SVG Plots were found.警告并返回空列表。仓库中的可运行示例见 examples/output/export/export_to_svg.py其绘图部分与 PNG 示例完全一致仅把结尾换成export_svg(p, filenameplot.svg)。浏览器端导出除了代码导出还可以在浏览器中直接保存 SVGSVG-Crowbar 书签工具在浏览器中加载 Bokeh 页面后运行该书签它会弹出提示把每个 plot 下载为独立的 SVG 文件。该工具与 Chrome 完全兼容大多数情况下也适用于 Firefox工具栏的 SaveTool保存工具注意通过 SaveTool 导出的文件在原本工具栏所在位置会留下一块空白区域。导出流水线的源码级原理理解导出函数背后发生了什么有助于排查导出空白 / 超时 / 尺寸异常等问题。两个后端的实现高度同构src/bokeh/io/browser.py 与 src/bokeh/io/webdriver.py核心步骤为生成临时 HTML通过get_layout_html见 src/bokeh/io/util.py把布局序列化为带内联资源的 HTML写入tmp_html()创建的临时文件主题则取自(state or curstate()).document.theme导航并等待渲染完成浏览器打开file://临时文件然后wait_until_render_complete轮询两个条件——先是_BOKEH_LOADED_EXPR检查typeof Bokeh ! undefined且存在 document随后执行_WAIT_SCRIPT等待首个 document 发出bokeh:idle事件Playwright 侧通过page.wait_for_function等待window._bokeh_render_complete标志确定裁剪区域_ROOT_VIEW_BBOX_SCRIPT读取第一个 root view 的getBoundingClientRect()与window.devicePixelRatio据此把视口调整到恰好容纳布局的大小Playwright 端在视口基础上再加 100px 余量最后按坐标裁剪避免某些窗口管理器无法精确设置窗口大小的问题截图或提取 SVGPNG 走page.screenshot(clip...)/web_driver.get_screenshot_as_png()SVG 则执行_SVG_SCRIPT(obj)或_SVGS_SCRIPT——后者在页面内用Bokeh.require(models/layouts/layout_dom)与Bokeh.require(models/plots/plot)遍历Bokeh.index中的视图收集所有PlotView的 SVG 序列化结果。值得一提的实现细节Playwright 后端使用一个常驻的后台守护线程_PlaywrightThread运行 asyncio 事件循环src/bokeh/io/browser.pyWindows 上强制使用ProactorEventLoop因为 Playwright 以 asyncio 子进程方式启动其 driver同时通过atexit注册清理函数进程退出时自动关闭浏览器与线程。浏览器实例默认复用_PlaywrightState.reuse当新请求的scale_factor大于当前浏览器的启动倍率时会先重启浏览器——这也解释了为什么先导出 1x 再导出高倍率图会比反向顺序更快。Selenium 侧的webdriver_control_WebdriverState同样实现 driver 复用并在 PATH 中探测不到任何可用驱动时报出安装建议。仓库单元测试 tests/unit/bokeh/io/test_export.py 覆盖了export_png、export_svg、export_svgs、get_screenshot_as_png等函数的调用路径与参数校验可作为理解各函数行为边界的参考。常见问题与最佳实践小结导出空白或超时通常是 Chromium headless shell 未安装运行playwright install --only-shell chromium或timeout过短默认 5 秒可将timeout调大后重试导出尺寸不符预期优先检查是否使用了响应式 sizing 模式导出场景请使用默认fixedsizing mode高分辨率 PNG使用scale_factor如2而非直接放大布局可以在保持元素相对比例的前提下获得高清输出透明背景同时把background_fill_color与border_fill_color设为None矢量输出设置plot.output_backend svg后再用export_svg导出布局中多图拆分用export_svgs混合环境若同时装有 Selenium 与 Playwrightauto会优先选 Playwright如需强制某个后端用BOKEH_EXPORT_BACKEND环境变量或每次调用传backend参数即可。至此从依赖安装、后端选择到 PNG / SVG 导出的完整链路已经打通你可以把这套能力直接应用到报表生成、文档插图与 CI 截图校验等场景中。【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网