1 line
29 KiB
JSON
1 line
29 KiB
JSON
{"repo": "adw-19/llmpic", "files": {"doc/README_CN.md": {"584449ccfcd7469408a160c40928141837c00a60": {"t": 1785674664.088481, "n": 20325, "h": "20003f82ce604785", "c": "<p align=\"center\">\n <img src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License\">\n <a href=\"https://github.com/ADW-19/llmpic\"><img src=\"https://img.shields.io/badge/github-ADW--19%2Fllmpic-lightgrey.svg\" alt=\"GitHub\"></a>\n <img src=\"https://img.shields.io/badge/python-≥3.10-green.svg\" alt=\"Python\">\n <img src=\"https://img.shields.io/badge/version-0.3.0-orange.svg\" alt=\"Version\">\n <img src=\"https://img.shields.io/badge/pypi-llmpic-blue.svg\" alt=\"PyPI\">\n</p>\n\n<p align=\"center\"><img src=\"../llmpic_logo.png\" alt=\"llmpic logo\" width=\"120\"></p>\n\n<h1 align=\"center\">LLMPIC</h1>\n<p align=\"center\"><strong>自然语言驱动 · 一行代码出图</strong></p>\n\n<p align=\"center\">\n <a href=\"https://github.com/ADW-19/llmpic\">English</a> | \n <a href=\"https://ADW-19.github.io/llmpic/\">文档官网</a> | \n <a href=\"chinese/API_REFERENCE_CN.md\">API 参考</a> | \n <a href=\"chinese/GUIDE_CN.md\">使用指南</a> | \n <a href=\"../notebook_examples/llmpic_demo_cn.ipynb\">Notebook 示例</a>\n</p>\n\n---\n## 💡 为什么选择 llmpic?\n\n传统 Python 画图,你需要死记硬背 matplotlib 那上百个 API —— `plt.subplots()`、`ax.set_xticklabels()`、`fig.tight_layout()` —— 一张图几十行代码,查文档的时间比分析数据的时间还长。\n\n**llmpic** 让 Python 绘图进入**大模型时代**。用中文、英文、日文或韩文描述需求,即刻生成可投入生产的高质量 matplotlib 图表。\n\n| | 传统 matplotlib 画图 | llmpic |\n|---|---|---|\n| 代码量 | 15–40 行 | **1–3 行** |\n| API 门槛 | 100+ 个函数 | **0**(自然语言) |\n| 图表类型 | 手动选择 | **12 种 + 智能推荐** |\n| 修改迭代 | 重写大段代码 | **`result.edit(\"改成红色柱子\")`** |\n| Jupyter | 仅 `plt.show()` | **`result.show()` 内联渲染** |\n| 多格式导出 | 多次 savefig | **一个 `save()` 搞定 PNG/SVG/PDF** |\n| 报错修复 | 人工调试 | **LLM 自动修复(最多2轮)** |\n| 并发处理 | 手动线程管理 | **`AsyncllmPIC.batch()` 并发生成** |\n| 安全防护 | 无 | **双重防护:32 条正则 + 可选 LLM 审查** |\n\n### 同一张图,两种写法\n\n**任务**:分组柱状图 — 3 个产品 × 4 个季度,带数值标签、自定义配色、虚线网格、标题、图例。\n\n<table>\n<tr>\n<td width=\"50%\"><b>传统 matplotlib — 35 行</b></td>\n<td width=\"50%\"><b>llmpic — 2 行</b></td>\n</tr>\n<tr>\n<td>\n\n```python\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nproducts = [\"云服务\", \"AI\", \"安全\"]\nquarters = [\"Q1\",\"Q2\",\"Q3\",\"Q4\"]\ndata = np.array([\n [120,145,160,180],\n [ 95,110,130,155],\n [140,165,180,200],\n])\nx = np.arange(len(quarters))\nw = 0.25\ncolors = [\"#3498DB\",\"#2ECC71\",\"#E74C3C\"]\n\nfig, ax = plt.subplots(figsize=(10,6),dpi=150)\nfor i, p in enumerate(products):\n bars = ax.bar(x+i*w, data[i], w,\n label=p, color=colors[i])\n for bar in bars:\n h = bar.get_height()\n ax.text(bar.get_x()+bar.get_width()/2,\n h+1, f\"{h:.0f}\", ha=\"center\",\n va=\"bottom\", fontsize=9)\nax.set_xticks(x + w)\nax.set_xticklabels(quarters)\nax.set_title(\"各产品季度营收\",\n fontsize=14, pad=12)\nax.set_ylabel(\"营收(万元)\")\nax.legend(loc=\"upper left\")\nax.grid(axis=\"y\", linestyle=\"--\", alpha=0.4)\nfig.tight_layout()\nplt.savefig(\"revenue.png\", dpi=150)\nplt.close()\n```\n\n</td>\n<td>\n\n```python\nfrom llmpic import llmPIC\nlp = llmPIC(api_key=\"sk-...\",\n base_url=\"https://api.openai.com/v1\")\n\nlp.bar(\n \"各产品季度营收:\"\n \"云服务=[120,145,160,180],\"\n \"AI=[95,110,130,155],\"\n \"安全=[140,165,180,200]。\"\n \"分组柱状图,加数值标签,\"\n \"虚线网格,图例。\"\n).style({\n \"figsize\": [10, 6], \"dpi\": 150,\n \"color_scheme\": \"cool\",\n}).save(\"revenue.png\")\n```\n\n</td>\n</tr>\n</table>\n\n---\n\n**以下展示 12 种图表类型中的 6 种**(折线图、散点图、柱状图、饼图、热力图、雷达图),完整列表见 [核心特性](#-核心特性)。\n\n```python\nfrom llmpic import llmPIC\n\nlp = llmPIC(api_key=\"sk-...\", base_url=\"https://api.openai.com/v1\")\n\n# 支持 12 种图表类型 — 一行代码出图,无需 matplotlib 知识\nlp.plot(\"2025年度营收趋势,蓝色填充区域\").data(df).save(\"revenue.png\")\nlp.scatter(\"客户年龄 vs 年消费额,带趋势线\").data(df).save(\"scatter.png\")\nlp.bar(\"Q4产品营收对比,水平柱状图\").data(df).save(\"bar.png\")\nlp.pie(\"市场份额分布,最大扇区突出显示\").data(df).save(\"pie.png\")\nlp.heatmap(\"周活跃用户热力图,Blues主题\").data(df).save(\"heatmap.png\")\nlp.radar(\"产品能力六维评估\").data(df).save(\"radar.png\")\n\n# 地图图表 (v0.3.0) — 支持 cartopy 或纯 matplotlib 回退\nlp.map(\"世界人口分布等值区域图\").data(df).save(\"world.png\")\n```\n\n<p align=\"center\"><i>以上 6 张图表 — 全部为 llmpic V0.3.0 实际输出,非示意图</i></p>\n\n<table>\n<tr>\n <td width=\"50%\" align=\"center\">\n <b>plot — 折线图</b><br>\n <code>lp.plot(\"年度营收趋势,蓝色填充区域\").data(df).save()</code><br>\n <img src=\"../assets/demo_line.png\" width=\"95%\"/>\n </td>\n <td width=\"50%\" align=\"center\">\n <b>scatter — 散点图</b><br>\n <code>lp.scatter(\"年龄 vs 消费额,带趋势线\").data(df).save()</code><br>\n <img src=\"../assets/demo_scatter.png\" width=\"95%\"/>\n </td>\n</tr>\n<tr>\n <td width=\"50%\" align=\"center\">\n <b>bar — 柱状图</b><br>\n <code>lp.bar(\"产品营收对比,水平柱状图\").data(df).save()</code><br>\n <img src=\"../assets/demo_bar.png\" width=\"95%\"/>\n </td>\n <td width=\"50%\" align=\"center\">\n <b>pie — 饼图</b><br>\n <code>lp.pie(\"市场份额分布,最大扇区突出\").data(df).save()</code><br>\n <img src=\"../assets/demo_pie.png\" width=\"95%\"/>\n </td>\n</tr>\n<tr>\n <td width=\"50%\" align=\"center\">\n <b>heatmap — 热力图</b><br>\n <code>lp.heatmap(\"周活跃用户热力图,Blues主题\").data(df).save()</code><br>\n <img src=\"../assets/demo_heatmap.png\" width=\"95%\"/>\n </td>\n <td width=\"50%\" align=\"center\">\n <b>radar — 雷达图</b><br>\n <code>lp.radar(\"产品能力六维评估\").data(df).save()</code><br>\n <img src=\"../assets/demo_radar.png\" width=\"95%\"/>\n </td>\n</tr>\n</table>\n\n---\n\n## ✨ 核心特性\n\n- 🗣️ **自然语言输入** — 支持中文、英文、日文、韩文\n- 📊 **12 种图表类型** — 折线图、散点图、柱状图、饼图、直方图、热力图、箱线图、面积图、雷达图、地图、子图仪表盘、智能推荐\n- 🔗 **流式构建器 API** — 链式调用 `.data()` → `.style()` → `.format()` → `.save()` / `.render()`\n- 📓 **Jupyter 内联显示** — `result.show()` 在 cell 下方直接渲染图表\n- ⚡ **异步批量生成** — `AsyncllmPIC.batch()` 多图表并发生成(总耗时≈最慢那张)\n- 🔧 **自动修复** — 代码执行出错时,LLM 自动修正(最多 2 轮)\n- ✏️ **迭代编辑** — `result.edit(\"改成红色,加网格\")` 用自然语言逐步修改图表\n- 📦 **多格式导出** — 一个 `save()` 搞定 PNG(位图)/ SVG(矢量)/ PDF(打印)\n- 🌍 **多语言标签** — 自动检测查询语言,图表标题/坐标轴自动匹配中文\n- 🛡️ **双重安全** — 32 条预编译正则(~0ms)+ 可选 LLM 语义审查\n- 🗺️ **地图图表** — 基于 cartopy 的地理地图;世界地图、等值区域图、散点标记图、国家/地区视图\n- 💻 **跨平台** — Windows / Linux / macOS 全兼容,中文字体自动配置\n- 🔄 **指数退避重试** — LLM 调用失败自动重试(1s, 2s, 4s)\n- 📊 **JSON 结构化输出** — 使用 JSON mode 稳定提取 LLM 生成的 matplotlib 代码\n\n---\n\n## 📦 安装\n\n```bash\npip install llmpic # 一键安装:matplotlib + numpy + openai + pandas + seaborn + scikit-learn + scipy\n```\n\n**环境要求:**\n- Python ≥ 3.10\n- 任意兼容 OpenAI API 的大模型接口(OpenAI、DeepSeek、Azure、智谱 GLM、Ollama 等)\n- 中文/日文/韩文图表需要系统安装对应字体(首次运行时自动检测)\n\n### 验证安装\n\n```python\nfrom llmpic import llmPIC, AsyncllmPIC, ChartResult, PlotBuilder, AsyncPlotBuilder\nimport llmpic\nprint(llmpic.__version__) # → \"0.3.0\"\n```\n\n---\n\n## 🚀 快速入门\n\n### 1. 初始化 SDK\n\n```python\nfrom llmpic import llmPIC\n\n# OpenAI\nlp = llmPIC(\n api_key=\"sk-your-openai-key\",\n base_url=\"https://api.openai.com/v1\",\n model=\"gpt-4o\",\n)\n\n# DeepSeek(国内推荐,性价比高)\nlp = llmPIC(\n api_key=\"sk-your-deepseek-key\",\n base_url=\"https://api.deepseek.com/v1\",\n model=\"deepseek-chat\",\n)\n\n# 智谱 GLM\nlp = llmPIC(\n api_key=\"your-zhipu-key\",\n base_url=\"https://open.bigmodel.cn/api/paas/v4\",\n model=\"glm-4-plus\",\n)\n\n# 任何兼容 OpenAI 接口的服务都可以\nlp = llmPIC(\n api_key=\"your-key\",\n base_url=\"https://your-endpoint/v1\",\n model=\"your-model\",\n)\n```\n\n### 2. 你的第一张图表\n\n```python\n# 基础用法 — 一句话出图\nlp.plot(\"过去12个月的月度销售趋势\").save(\"sales.png\")\n\n# Jupyter 内联显示\nlp.plot(\"30天内CPU使用率变化\").render().show()\n\n# 默认保存路径(不传参数 → 用户主目录)\nlp.plot(\"温度变化趋势\").save() # → ~/llmpic_charts/chart_20250101_120000.png\n```\n\n### 3. 带真实数据出图\n\n```python\nimport pandas as pd\n\ndf = pd.read_csv(\"sales.csv\")\nlp.bar(\"2024年各地区销售额对比\").data(df).style({\n \"color_scheme\": \"warm\",\n \"figsize\": [12, 7],\n \"title_fontsize\": 16,\n}).save(\"regional_sales.png\")\n```\n\n### 4. 常用代码模板(30秒速查)\n\n```python\n# 折线图 + SVG 输出\nlp.plot(\"CPU使用率趋势\").format('svg').save(\"cpu.svg\")\n\n# 散点图 + DataFrame\nlp.scatter(\"年龄与收入的相关性分析\").data(df).save(\"scatter.png\")\n\n# 饼图 + 内联数据\nlp.pie(\"市场份额: A产品=40%, B产品=25%, C产品=20%, D产品=15%\").save(\"pie.png\")\n\n# 热力图 + 相关性矩阵\nlp.heatmap(\"多特征相关性热力图\").data(corr_df).save(\"heatmap.png\")\n\n# 综合仪表盘\nlp.subplots(\"2x2看板: 趋势折线图, 地区对比柱状图, 客户分布散点图, 增长分布直方图\").save(\"dash.png\")\n\n# 地理地图 (v0.3.0)\nlp.map(\"世界人口分布等值区域图,Blues配色\").data(df).save(\"world.png\")\n\n# 智能推荐图表类型\nlp.custom(\"分析用户留存率变化趋势及影响因素\").data(df).save(\"auto.png\")\n\n# 查看生成的代码\nresult = lp.plot(\"测试图\").render()\nprint(result.code) # LLM 生成的 matplotlib 代码\nprint(result.token_usage) # {'input': 320, 'output': 180}\n\n# 迭代修改\nresult = lp.plot(\"月度销售: 1月=100, 2月=120\").render()\nresult.edit(\"改成柱状图,使用红色系\").edit(\n \"标题改为'第一季度收入',添加网格线\").save(\"final.png\")\n```\n\n---\n\n## 📊 图表类型\n\n| 方法 | 图表类型 | 适用场景 | LLM 提示词 |\n|------|---------|---------|-----------|\n| `.plot()` | 折线图 | 趋势分析、时间序列、连续数据 | `ax.plot()` |\n| `.scatter()` | 散点图 | 相关性分析、聚类可视化 | `ax.scatter()` |\n| `.bar()` | 柱状图 | 分类对比、排名 | `ax.bar()` / `ax.barh()` |\n| `.pie()` | 饼图 | 占比分布、市场份额 | `ax.pie(autopct='%1.1f%%')` |\n| `.hist()` | 直方图 | 数据分布、频率统计 | `ax.hist()` |\n| `.heatmap()` | 热力图 | 相关性矩阵、二维密度 | `ax.imshow()` / `sns.heatmap()` |\n| `.boxplot()` | 箱线图 | 多组数据统计分布对比 | `ax.boxplot()` / `sns.boxplot()` |\n| `.area()` | 面积图 | 堆积趋势、成分变化 | `ax.fill_between()` / `ax.stackplot()` |\n| `.radar()` | 雷达图 | 多维指标对比、能力评估 | 极坐标轴 |\n| `.map()` | 地图 | 地理地图、等值区域图、世界/国家/地区 | `cartopy` 或 `ax.scatter()` |\n| `.subplots()` | 综合仪表盘 | 多图表综合展示 | `plt.subplots(nrows, ncols)` |\n| `.custom()` | 智能推荐 | LLM 自动判断最佳图表类型 | 上下文感知 |\n\n---\n\n## 🔗 核心工作流\n\n```\n sdk.plot(\"需求描述\") ← 用自然语言描述图表需求\n → PlotBuilder 构建器\n .data(df) ← 传入真实数据(可选)\n .style({...}) ← 自定义样式(可选)\n .format('png') ← 选择输出格式(可选)\n .render() ← 触发:LLM 生成 → 安全检查 → 沙箱执行 → ChartResult\n .save(\"路径.png\") ← 触发并保存到文件\n```\n\n### 构建器模式详解\n\n```python\n# 所有图表方法返回 PlotBuilder 对象。构建器是惰性的——\n# 在调用 .render() / .save() 或访问 .image_bytes / .code 之前,什么都不会发生。\n\nbuilder = lp.plot(\"月度销售趋势\") # 返回 PlotBuilder —— 还没有调用 LLM\nbuilder = builder.data(df) # 绑定数据\nbuilder = builder.style({\"figsize\": [12, 6]}) # 设定样式\nbuilder = builder.format('svg') # 设定格式\n\nresult = builder.render() # ← 到这里才执行:LLM生成 → 安全审查 → 沙箱执行\nresult.save(\"chart.svg\") # 保存文件\n```\n\n### ChartResult — 结果对象的完全用法\n\n```python\nresult = lp.plot(\"CPU使用率趋势\").render()\n\n# 基本信息\nresult.success # bool — 是否成功\nresult.code # str — LLM 生成的 matplotlib 代码\nresult.token_usage # dict — {'input': 320, 'output': 180}\nresult.size_kb # float — 图片大小 (KB)\n\n# 保存到文件\nresult.save() # → ~/llmpic_charts/chart_{timestamp}.png\nresult.save(\"out.png\") # PNG\nresult.save(\"out.svg\") # SVG\nresult.save(\"out.pdf\") # PDF\n\n# Jupyter 内联展示\nresult.show()\n\n# Base64 编码(前端嵌入)\nresult.base64() # data:image/png;base64,...\nresult.base64_svg() # data:image/svg+xml;base64,...\n\n# 访问其他格式(懒加载,首次访问时重新渲染并缓存)\nresult.svg_bytes # SVG 字节数据\nresult.pdf_bytes # PDF 字节数据\nresult.svg # SVG 字符串\n\n# 自然语言迭代修改\nv2 = result.edit(\"改成柱状图,使用暖色系\")\nv3 = v2.edit(\"标题字号加大到18\")\n```\n\n---\n\n## ⚡ 异步与批量生成\n\n使用 `AsyncllmPIC` 实现图表并发生成,总耗时接近最慢的那张图表。\n\n```python\nfrom llmpic import AsyncllmPIC\nimport asyncio\n\nasync def main():\n lp = AsyncllmPIC(\n api_key=\"sk-...\",\n base_url=\"https://api.deepseek.com/v1\",\n model=\"deepseek-chat\",\n )\n\n # 批量生成:5 张图表并发执行\n results = await lp.batch([\n (\"plot\", \"过去12个月销售趋势\"),\n (\"bar\", \"各地区销售额对比\"),\n (\"pie\", \"市场份额分布\"),\n (\"scatter\", \"用户年龄与消费金额关系\"),\n (\"heatmap\", \"多维度特征相关性矩阵\"),\n ])\n\n for i, r in enumerate(results):\n if r.success:\n r.save(f\"batch_{i}.png\")\n print(f\"[{i}] 成功 — {r.size_kb:.1f}KB, \"\n f\"Token: 输入={r.token_usage['input']} 输出={r.token_usage['output']}\")\n else:\n print(f\"[{i}] 失败: {r.error_message}\")\n\nasyncio.run(main())\n```\n\n### 手动控制并发\n\n```python\nasync def main():\n lp = AsyncllmPIC(...)\n\n # 精细控制:不同图表使用不同格式\n builders = [\n lp.plot(\"CPU趋势\").format('png'),\n lp.bar(\"销售对比\").data(df).style({\"color_scheme\": \"warm\"}).format('svg'),\n lp.pie(\"市场份额\").format('pdf'),\n ]\n results = await asyncio.gather(*[b.render() for b in builders])\n # 三张图表完全并发生成\n\nasyncio.run(main())\n```\n\n---\n\n## ✏️ 迭代编辑\n\n不需要为小修改重写整个需求 —— 用 `edit()` 逐步打磨图表。\n\n```python\n# 起点\nresult = lp.plot(\"月度销售: 1月=100, 2月=120, 3月=90, 4月=150\").render()\n\n# 逐步修改 —— 每次 .edit() 返回新 ChartResult,不改变原对象\nresult = result.edit(\"换成柱状图\")\nresult = result.edit(\"柱子颜色用红色系,暖色调\")\nresult = result.edit(\"添加网格线,标题字号改大到18\")\nresult = result.edit(\"标题改为'2025年Q1销售报告',Y轴加标签'营收(万元)'\")\n\nresult.save(\"final.png\")\nresult.show()\n```\n\n**原理:** 每次 `edit()` 将当前代码 + 修改描述发给 LLM,LLM 返回修改后的代码,经过安全审查 → 沙箱执行的完整管线,返回新 `ChartResult`。原始 `ChartResult` 始终不变。\n\n---\n\n## 📦 输出格式\n\n| 格式 | 扩展名 | 类型 | 适用场景 |\n|------|-------|------|---------|\n| PNG | `.png` | 位图 | 通用场景、快速预览、嵌入文档 |\n| SVG | `.svg` | 矢量 | 网页嵌入、无限缩放、前端展示 |\n| PDF | `.pdf` | 矢量/打印 | 学术论文、商业报告、印刷输出 |\n\n```python\n# 方式一:渲染前用 .format() 指定格式\nlp.plot(\"趋势\").format('svg').save(\"chart.svg\")\nlp.plot(\"趋势\").format('pdf').save(\"chart.pdf\")\n\n# 方式二:保存时根据扩展名自动切换格式\nresult = lp.plot(\"趋势\").render() # 默认 PNG\nresult.save(\"output.svg\") # → SVG(根据扩展名自动检测)\nresult.save(\"output.pdf\") # → PDF\n\n# 方式三:通过属性访问其他格式(懒加载,首次访问时重新渲染)\nresult = lp.plot(\"趋势\").render() # image_bytes 为 PNG\nsvg_data = result.svg_bytes # 懒加载,重新渲染为 SVG(并缓存)\npdf_data = result.pdf_bytes # 懒加载,重新渲染为 PDF(并缓存)\n```\n\n---\n\n## 🎨 样式定制\n\n### 6 种预设配色方案\n\n```python\nlp.plot(\"趋势\").style({\"color_scheme\": \"blues\"}).save(\"b.png\") # 蓝调\nlp.plot(\"趋势\").style({\"color_scheme\": \"warm\"}).save(\"w.png\") # 暖色\nlp.plot(\"趋势\").style({\"color_scheme\": \"cool\"}).save(\"c.png\") # 冷色\nlp.plot(\"趋势\").style({\"color_scheme\": \"pastel\"}).save(\"p.png\") # 柔和\nlp.plot(\"趋势\").style({\"color_scheme\": \"dark\"}).save(\"d.png\") # 暗色\nlp.plot(\"趋势\").style({\"color_scheme\": \"grayscale\"}).save(\"g.png\") # 灰度\n```\n\n### 所有样式参数\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----|------|-------|------|\n| `figsize` | `[int, int]` | `[10, 6]` | 图表尺寸(英寸),[宽, 高] |\n| `dpi` | `int` | `150` | 输出分辨率(每英寸像素数) |\n| `color_scheme` | `str` | `\"blues\"` | 配色方案:`blues` `warm` `cool` `pastel` `dark` `grayscale` |\n| `title_fontsize` | `int` | `14` | 标题字号 |\n| `label_fontsize` | `int` | `12` | 坐标轴标签字号 |\n| `tick_fontsize` | `int` | `10` | 刻度标签字号 |\n| `grid` | `bool` | `True` | 是否显示背景网格 |\n| `grid_alpha` | `float` | `0.3` | 网格线透明度(0–1) |\n| `tight_layout` | `bool` | `True` | 是否自动调整布局避免裁剪 |\n| `facecolor` | `str` | `\"white\"` | 图表背景色(支持任意 CSS 颜色) |\n\n### 样式定制示例\n\n```python\n# 学术论文级别\nlp.plot(\"实验结果对比\").style({\n \"figsize\": [8, 5],\n \"dpi\": 300,\n \"color_scheme\": \"dark\",\n \"title_fontsize\": 16,\n \"label_fontsize\": 14,\n}).save(\"paper.png\")\n\n# PPT 汇报专用\nlp.bar(\"Q4营收对比\").data(df).style({\n \"figsize\": [14, 8],\n \"color_scheme\": \"warm\",\n \"title_fontsize\": 22,\n \"label_fontsize\": 16,\n \"tick_fontsize\": 14,\n \"grid\": False,\n \"facecolor\": \"#FAFAFA\",\n \"dpi\": 200,\n}).save(\"ppt.png\")\n\n# 也可以通过 JSON 字符串传入样式\nlp.plot(\"趋势\").style('{\"color_scheme\":\"cool\",\"figsize\":[12,8]}').save(\"trend.png\")\n```\n\n---\n\n## 🛡️ 安全保障\n\nllmpic 在**沙箱环境**中执行 LLM 生成的代码,提供双层防护:\n\n### 第一层:正则模式匹配(~0ms,零延迟)\n\n32 条预编译正则表达式阻止已知危险模式:\n- **系统命令**:`os.system()`, `os.popen()`, `subprocess`\n- **文件操作**:`open()`(LLM 不应直接读写文件)\n- **动态执行**:`exec()`, `eval()`, `compile()`, `__import__()`\n- **网络访问**:`socket`, `urllib`, `requests`, `httpx`\n- **危险模块**:`shutil`, `ctypes`, `pickle`\n- **反射逃逸**:`__subclasses__`, `__bases__`, `__mro__`\n\n### 第二层:沙箱执行\n\n- **受限命名空间**:仅包含安全内置函数 + matplotlib, numpy, pandas, seaborn\n- **Figure.savefig 拦截**:阻止代码直接写文件,由沙箱统一接管渲染\n- **plt.show() / plt.savefig() / plt.close() 阻断**:全部拦截为空操作\n- **超时熔断**:ThreadPoolExecutor + 超时机制终止失控代码\n- **全局互斥锁**:模块级锁防止 matplotlib 全局状态竞争\n\n### 安全级别配置\n\n```python\n# 快速模式(默认,推荐生产环境)\nlp = llmPIC(..., safety_level=\"fast\")\n\n# 完整模式(正则 + LLM 语义审查,每张图额外增加约 1-2 秒)\nlp = llmPIC(..., safety_level=\"full\")\n```\n\n**建议:** 沙箱本身已经阻止所有实际执行路径,`fast` 模式在生产环境中足够安全。`full` 模式适用于对安全性有极高要求的场景。\n\n---\n\n## 🌐 LLM 服务商兼容性\n\nllmpic 兼容**所有提供 OpenAI 兼容接口**的大模型服务(需要支持 `chat/completions` 和 JSON 结构化输出):\n\n| 服务商 | base_url | 模型示例 |\n|--------|----------|---------|\n| OpenAI | `https://api.openai.com/v1` | `gpt-5.5`, `gpt-5.5-mini` |\n| DeepSeek | `https://api.deepseek.com/v1` | `deepseek-v4-pro` |\n| Azure OpenAI | `https://{resource}.openai.azure.com/openai/deployments/{deployment}` | 你的部署名称 |\n| 智谱 GLM | `https://open.bigmodel.cn/api/paas/v5` | `glm-5` |\n| 月之暗面 Moonshot | `https://api.moonshot.cn/v1` | `moonshot-v1-8k` |\n| 阿里通义千问 | `https://dashscope.aliyuncs.com/compatible-mode/v1` | `qwen-plus` |\n| 百度文心一言 | `https://qianfan.baidubce.com/v2` | `ernie-4.0-turbo-8k` |\n| Ollama(本地) | `http://localhost:11434/v1` | `llama3`, `qwen3.5` |\n| vLLM(本地) | `http://localhost:8000/v1` | 你部署的模型 |\n\n> **提示**:图表质量与代码生成能力直接相关。推荐使用 GPT-5.5、DeepSeek-V4、GLM-5 等代码能力强的模型。本地模型可能生成不够可靠的代码——建议增大 `max_retries` 和 `max_fix_attempts` 参数。\n\n---\n\n## 🔧 环境变量配置\n\n推荐将 API 密钥存储在环境变量或 `.env` 文件中:\n\n```bash\n# .env 文件 或 Shell 配置\nexport LLMPIC_API_KEY=\"sk-your-key\"\nexport LLMPIC_BASE_URL=\"https://api.deepseek.com/v1\"\nexport LLMPIC_MODEL=\"deepseek-chat\"\n```\n\n```python\nimport os\nfrom llmpic import llmPIC\n\nlp = llmPIC(\n api_key=os.getenv(\"LLMPIC_API_KEY\"),\n base_url=os.getenv(\"LLMPIC_BASE_URL\"),\n model=os.getenv(\"LLMPIC_MODEL\", \"gpt-4o\"),\n)\n```\n\n---\n\n## 🏗 架构总览\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ llmPIC / AsyncllmPIC │\n│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │\n│ │ .plot() │ │ .bar() │ │ .pie() │ │.custom() │ │\n│ │.scatter()│ │ .hist() │ │.heatmap()│ │ ...共12种 │ │\n│ │ .map() │ │.boxplot()│ │ .area() │ │ .radar() │ │\n│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │\n│ └──────────────┴──────────────┴──────────────┘ │\n│ │ │\n│ PlotBuilder / AsyncPlotBuilder │\n│ .data() .style() .format() │\n│ │ │\n│ .render() / .save() │\n│ │ │\n│ ┌───────────┴───────────┐ │\n│ │ 1. LLM 代码生成 │ OpenAI 兼容 API │\n│ │ (重试3次+指数退避) │ │\n│ └───────────┬───────────┘ │\n│ │ │\n│ ┌───────────┴───────────┐ │\n│ │ 2. 安全审查 │ CodeSafetyChecker │\n│ │ 32条正则 + 可选LLM│ │\n│ └───────────┬───────────┘ │\n│ │ │\n│ ┌───────────┴───────────┐ │\n│ │ 3. 沙箱执行 │ SandboxExecutor │\n│ │ (自动修复失败代码) │ ThreadPool + 超时 │\n│ └───────────┬───────────┘ │\n│ │ │\n│ ChartResult │\n│ .save() .show() .edit() .base64() .svg .pdf │\n└─────────────────────────────────────────────────────────────┘\n```\n\n**每张图表的生成管线:**\n1. **LLM 代码生成** — 自然语言 → matplotlib Python 代码(JSON 结构化输出,最多重试 3 次)\n2. **安全审查** — 32 条正则模式匹配 + 可选 LLM 语义审查\n3. **沙箱执行** — ThreadPoolExecutor 线程池 + 超时机制 + Figure 猴子补丁 + 受限命名空间\n4. **自动修复** — 执行失败时,将代码+错误信息发回 LLM 修正(最多 2 轮)\n5. **返回结果** — `ChartResult` 包含图像字节、源代码、Token 用量、懒加载格式转换\n\n---\n\n## 📖 文档导航\n\n| 文档 | 语言 | 说明 |\n|------|------|------|\n| [API 参考](chinese/API_REFERENCE_CN.md) | 中文 | 所有类、方法、参数的详细说明 |\n| [API Reference](english/API_REFERENCE_EN.md) | EN | Complete class, method, and parameter reference |\n| [使用指南](chinese/GUIDE_CN.md) | 中文 | 进阶用法、最佳实践、故障排查 |\n| [User Guide](english/GUIDE_EN.md) | EN | Advanced usage, best practices, troubleshooting |\n| [Jupyter 演示](https://github.com/ADW-19/llmpic/tree/main/notebook_examples) | 中/EN | 开箱即用的 Jupyter Notebook |\n| [English README](https://github.com/ADW-19/llmpic) | EN | Full English README |\n\n---\n\n## 📮 官方联系方式\n\n- **小红书**:[ADW_AI](https://xhslink.com/m/AQw13M5WIPc)\n- **GitHub Issues**:[github.com/ADW-19/llmpic/issues](https://github.com/ADW-19/llmpic/issues)\n\n---\n\n## 🙏 致谢\n\nllmpic 站在以下优秀开源项目的肩膀上构建:\n\n- [SciPy](https://scipy.org/) — 科学计算\n- [scikit-learn](https://scikit-learn.org/) — 机器学习工具\n- [pandas](https://pandas.pydata.org/) — 数据分析与 DataFrame\n- [NumPy](https://numpy.org/) — 数值计算\n- [Matplotlib](https://matplotlib.org/) — 图表渲染引擎\n- [seaborn](https://seaborn.pydata.org/) — 统计数据可视化\n\n衷心感谢这些项目的维护者与贡献者。\n\n---\n\n## 📄 开源协议\n\n[MIT](https://github.com/ADW-19/llmpic/blob/main/LICENSE) © 2026 ADW-19\n"}}}} |