You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandoc的Matplotlib过滤器中高效共享Pandas数据源?

Pandoc Matplotlib过滤器共享数据源解决方案

核心思路

利用Pandoc过滤器的全局状态保存特性,在首次执行时初始化数据源,后续代码片段直接复用资源,最后在过滤器结束时自动清理数据库连接等资源。


具体实现步骤

1. 编写自定义Pandoc过滤器脚本

用Python实现过滤器,通过全局变量维护共享的数据库连接和DataFrame:

import pandocfilters as pf
import sqlite3
import pandas as pd
import matplotlib.pyplot as plt
import io

# 全局容器存储共享资源
_shared_resources = {
    'db_conn': None,
    'dataset': None
}

def process_matplotlib_block(key, value, fmt, meta):
    if key == 'CodeBlock' and len(value) == 2:
        attrs, code = value
        classes, _, _ = attrs
        if 'matplotlib' in classes:
            global _shared_resources
            try:
                # 首次执行时初始化数据源
                if _shared_resources['dataset'] is None:
                    _shared_resources['db_conn'] = sqlite3.connect('somedb.db')
                    query = '''SELECT something'''
                    _shared_resources['dataset'] = pd.read_sql_query(query, _shared_resources['db_conn']).dropna()
                
                # 将共享变量注入代码执行环境
                exec_env = {
                    'df': _shared_resources['dataset'],
                    'plt': plt,
                    'pd': pd
                }
                exec(code, globals(), exec_env)
                
                # 提取生成的图表并转为Base64格式嵌入文档
                fig = exec_env.get('fig') or plt.gcf()
                buf = io.BytesIO()
                fig.savefig(buf, format='png')
                buf.seek(0)
                img_base64 = buf.getvalue().hex()
                plt.close(fig)
                
                # 返回Pandoc图片节点
                return pf.Para([pf.Image(['', [], []], [], [f'data:image/png;base64,{img_base64}', 'chart'])])
            except Exception as e:
                return pf.Str(f"图表生成失败: {str(e)}")
    return None

if __name__ == '__main__':
    pf.toJSONFilter(process_matplotlib_block)
    # 过滤器结束时自动关闭数据库连接
    if _shared_resources['db_conn'] is not None:
        _shared_resources['db_conn'].close()

2. 简化Markdown中的代码片段

文档内无需重复初始化数据源,直接调用共享的df变量生成图表:

第一幅图表:

~~~{.matplotlib}
fig, ax = plt.subplots()
ax.hist(df['target_column'])
ax.set_title('数值分布直方图')
~~~

第二幅图表:

~~~{.matplotlib}
fig, ax = plt.subplots()
ax.scatter(df['feature1'], df['feature2'])
ax.set_title('双特征散点图')
~~~

3. 调用Pandoc并启用过滤器

执行转换命令时指定自定义过滤器脚本:

pandoc input.md -o output.pdf --filter ./matplotlib_filter.py

关键细节说明

  • 资源隔离:用全局字典存储共享资源,避免与用户代码的变量命名冲突
  • 自动清理:过滤器脚本末尾统一关闭数据库连接,确保会话结束后释放资源
  • 容错机制:添加异常捕获,单个图表生成失败不会中断整个文档的转换流程

内容的提问来源于stack exchange,提问作者Scott Deerwester

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:13:09