做数据可视化这些年,我最大的感受是:真正卡住你的往往不是想法,而是把想法翻译成代码的过程。你脑子里清清楚楚知道要一张“各国家奖牌数对比柱状图”,可真到了ECharts配置里,xAxis、series、tooltip、legend这些东西能纠缠你一下午。与其说这是技术问题,不如说是翻译问题——把自然语言翻译成图表配置项的翻译问题。而现在,借助AI大模型,这段翻译工作可以压缩到几秒钟。
前阵子我帮朋友赶一份亚运会奖牌榜的可视化图表,从新建HTML文件到跑出第一版可交互的柱状图,前后花了不到5分钟。核心就一句话:用自然语言把需求讲清楚,让AI帮你写ECharts代码。今天这篇就把完整路径拆开揉碎了分享出来,主题就是“借助AI用自然语言完成亚运会数据可视化”。不管你是赶作业的学生、做汇报的职场人,还是想快速验证想法的研究者,照着这条思路都能省下至少半天时间。文章最后,我会把那条可以直接复制的完整Prompt原样贴出来。
1. 为什么AI+自然语言做数据可视化能这么快
1.1 传统流程中最耗时的环节是“翻译”
说实话,做数据可视化,数据处理和图表设计本身并不难,难的是把“我要什么”变成“代码怎么写”。举个例子:你想要一张“各国金牌数降序排列的柱状图”,听起来就一句话的事。但ECharts的option对象长这样:
option = { xAxis: { type: 'category', data: ['中国', '日本', '韩国'] }, yAxis: { type: 'value' }, series: [{ type: 'bar', data: [201, 52, 42] }] };demo代码还算简单,复杂一点的需求,比如添加图例、设置堆叠、调整颜色,配置项会成倍增长。以前我每次都要翻一遍ECharts官方文档,确认坐标轴类型、series的name、tooltip的trigger,再来回试样式。真正写业务逻辑的时间没多少,大部分时间都耗在“记忆API”和“调试样式”上。
1.2 AI大模型真正替代掉的是“API知识检索”
现在的对话式AI大模型,训练的时候见过海量的ECharts代码。你只要把自然语言描述说清楚,比如“柱状图,按金牌数从高到低排序,每个国家显示金银铜三根柱子,标题居中”,它就能一次性生成对应配置。它替你完成了“查文档→理解API→组装代码”这整条链路。
我用下来的感觉是:AI做数据可视化代码生成,比很多普通代码任务更靠谱。因为ECharts本身是一个配置驱动的框架,只要数据格式正确,option对象写对,图表就能渲染。这正好契合大模型“模式识别”的强项——海量常见图表配置已经被它学得很透。
1.3 “5分钟”这个目标现实吗?
先说结论:只要数据是准备好的,5分钟完全现实。我实际执行的时间分配大致是这样的:
- 30秒:把演示数据整理成CSV格式。
- 30秒:写好Prompt,明确图表类型、数据字段、排序方式。
- 1分钟:粘贴给AI,等它返回代码。
- 2分钟:复制代码保存为HTML,浏览器打开验证。
当然,如果你要从零开始扒数据,那5分钟肯定不够。所以“5分钟完成可视化”的前提是:数据已就绪,你只需要把数据变成图表。这也是为什么我在下一章会先准备好一份亚运会奖牌数据,再让AI动手。
2. 5分钟跑通一个亚运会奖牌可视化(先用简版Prompt)
2.1 只需要一个HTML文件的环境
做纯前端可视化最简单的方式是新建一个HTML文件,通过CDN引入ECharts。不需要装Node,不需要配置构建工具,双击文件就能在浏览器里看到效果。我建议你先把下面这个骨架文件存为base.html,后面让AI生成的内容可以直接嵌进去:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>亚运会奖牌榜</title> <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> </head> <body> <div id="chart" style="width:900px;height:600px;"></div> </body> </html>注意这个骨架里有一个宽高明确的div#chart,这是图表渲染的容器。很多新手图表不显示,就是忘了给容器设置高度。
2.2 给AI喂一份演示数据
为了让AI不乱猜,我先把一份演示用亚运会奖牌数据整理好。这里我选了2023年杭州亚运会奖牌榜的前十名,为方便展示做成了CSV格式。注意:这只是一份用于演示的数据,并不保证和最终官方口径完全一致,做真实项目时你需要替换成自己核实过的数据。
国家,金牌,银牌,铜牌 中国,201,111,71 日本,52,43,23 韩国,42,59,68 印度,38,31,43 乌兹别克斯坦,25,18,23 泰国,14,11,13 伊朗,12,21,18 印度尼西亚,7,11,17 沙特阿拉伯,5,8,10 巴林,4,6,92.3 发送一个简版Prompt
接下来,把上面这段数据和下面的Prompt一起发给AI。简版Prompt我尽量控制得很短,只包含必要元素:
你是一个ECharts专家。下面是一份亚运会奖牌榜数据(国家,金牌,银牌,铜牌)。请用ECharts 5生成一个完整HTML文件,展示柱状图,X轴是国家,Y轴是奖牌数,按金牌数从高到低排序,用图例区分金牌、银牌、铜牌。只输出完整HTML代码,不要任何解释,不要Markdown代码块包裹。AI返回的代码一般会是下面这种结构,我们在浏览器里保存打开就能看到图表:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> </head> <body> <div id="chart" style="width:900px;height:600px;"></div> <script> var chart = echarts.init(document.getElementById('chart')); chart.setOption({ title: { text: '亚运会奖牌榜TOP10', left: 'center' }, tooltip: { trigger: 'axis' }, legend: { data: ['金牌', '银牌', '铜牌'], top: '8%' }, xAxis: { type: 'category', data: ['中国','日本','韩国','印度','乌兹别克斯坦','泰国','伊朗','印度尼西亚','沙特阿拉伯','巴林'] }, yAxis: { type: 'value' }, series: [ { name: '金牌', type: 'bar', data: [201,52,42,38,25,14,12,7,5,4] }, { name: '银牌', type: 'bar', data: [111,43,59,31,18,11,21,11,8,6] }, { name: '铜牌', type: 'bar', data: [71,23,68,43,23,13,18,17,10,9] } ] }); </script> </body> </html>2.4 拿到代码后的验证与调整
把AI返回的HTML内容保存为index.html,浏览器打开。如果一切正常,你看到的是一张分组柱状图,十支代表队按金牌数排序展示,图例和提示框也都是现成的。
这一步里最容易翻车的是AI真的用Markdown代码块包住了HTML,或者输出了一些解释性文字。遇到这种情况,你只需要把反引号之间的内容完整复制出来,粘贴到一个空文件里保存即可。别多复制一个空格,不然可能报语法错误。
3. 数据质量是关键:给AI一份“不坑”的亚运会数据
3.1 亚运会数据从哪里拿?
很多人问亚运会奖牌数据有没有公开API。说实话,大型综合运动会的官方数据接口通常不对外开放,现成的API也很少稳定可靠。实际项目里,我更建议大家去官方网站、新闻媒体发布的奖牌榜页面复制原始表格,或者直接搜索“杭州亚运会奖牌榜”,从搜索结果页面里找权威表格复制。
复制下来的表格不是拿来就能用,你至少要做两步:一是把“国家/地区”这种带斜杠的字段名改简单,二是在Excel或文本编辑器里确认分隔符是逗号、制表符还是空格。AI对CSV的解析最稳,所以我一般会统一整理成逗号分隔的csv文本。
3.2 数据预处理的两个关键动作
第一,排序。如果想让图表按金牌数降序排列,最佳做法是在数据里直接排好序,而不是让AI去排序。AI的排序代码有时候没问题,但多一层逻辑就多一分出错概率。我自己通常会在Excel里按金牌列降序排好,再复制给AI。
第二,字段名统一。不要出现“国家/地区”、Country、金这种混着用的情况。建议全部统一为中文全称字段:国家,金牌,银牌,铜牌,表头和数据一一对应。否则AI解析CSV时容易出错,而且后续你调试起来也费劲。
3.3 别让AI“凭记忆”补全数据
这条坑我踩过很多次。早先我偷懒,Prompt里只写“请生成一张上届亚运会金牌榜柱状图”,不给数据。AI当然不知道真实数据,但它会一本正经地编一组“看起来合理”的数字,甚至还会编出根本不存在的国家队名。用这种图表做汇报,后果很严重。
所以正确做法是:数据必须由你提供,并且明确告诉AI“只使用我给出的数据,不要自己补充或修改”。在我给你的完整Prompt里,这句话会写得很直白。
4. 完整Prompt拆解:角色、任务、数据、输出格式四要素
4.1 完整Prompt原文
这是本文最重要的一部分。下面这条Prompt是我反复调整后沉淀下来的版本,包含角色、任务、数据和输出格式四个部分。你可以直接复制使用,只需要把数据替换成你自己的。
【角色】 你是一名资深前端数据可视化工程师,精通ECharts 5的配置与调优。接下来请你用我提供的数据,生成一个可以直接运行的HTML文件。 【任务】 制作一张“杭州亚运会奖牌榜TOP10”可视化图表。具体要求如下: 1. 使用CDN引入ECharts 5,不要使用其他图表库。 2. 图表类型:柱状图,每个国家显示金牌、银牌、铜牌三根柱子。 3. 数据排序:严格按“金牌”数量从高到低排列,不要自行调整顺序。 4. X轴为国家名称,Y轴为奖牌数量。 5. 图例项为:金牌、银牌、铜牌,显示在图表顶部居中。 6. 标题居中显示“杭州亚运会奖牌榜TOP10”。 7. 柱状图颜色:金牌使用#F6C442,银牌使用#BEC4C9,铜牌使用#D98736。 8. 所有中文使用“Microsoft YaHei”字体,避免乱码。 9. 图表容器宽度自适应浏览器窗口变化,高度保持600px。 【数据】 国家,金牌,银牌,铜牌 中国,201,111,71 日本,52,43,23 韩国,42,59,68 印度,38,31,43 乌兹别克斯坦,25,18,23 泰国,14,11,13 伊朗,12,21,18 印度尼西亚,7,11,17 沙特阿拉伯,5,8,10 巴林,4,6,9 【输出要求】 只输出一个完整HTML文件的内容,不要输出任何解释、说明、注释。不要用Markdown代码块包裹内容。文件命名为 index.html。4.2 为什么每条指令都要写进Prompt?
这条Prompt看起来要求很多,但每条都是在实战中踩过坑才补上的。我逐个拆解一下。
- 角色设定:给AI一个“资深可视化工程师”的人设,能明显提高代码质量。AI在续写时会更倾向于生成符合专家身份的完整代码,而不是泛泛而谈。
- 任务细分:图表类型、标题、颜色、字体、排序这些要素,缺一个就可能让AI自由发挥。尤其“严格按金牌数量从高到低排列,不要自行调整顺序”这句话,能挡掉AI自作主张按字母排序的情况。
- 颜色指定:如果不指定颜色,AI大概率会使用默认配色,金色的柱子可能变成蓝色。这里给出具体十六进制色值,避免二次沟通。
- 自适应要求:加了第9条后,AI会主动使用
window.addEventListener('resize', ...)处理窗口变化。你不说,它就不写,页面一缩小图表就溢出。 - 输出要求:“不要Markdown代码块包裹”这句最重要。它能省掉你复制代码时的反引号清理工作。很多新手就是没强调这句话,结果把带反引号的文本直接存成HTML,打开全是乱码。
4.3 一个直接有效的微调手法
你再看完上面代码就会发现,完整Prompt和简版Prompt最大的差别,其实是把结果说是“按我的要求来”。AI生成代码后,如果你还想改样式,不需要重新发一遍完整Prompt。比如我追加一句:
把柱状图改成横向条形图,国家名称放Y轴,奖牌数放X轴,其他配置保持不变。它通常能基于刚才的上下文直接改代码。只要你不关闭对话,AI会一直记得刚才那段HTML代码。这也是为什么我建议用同一个对话窗口完成多轮调整,而不是反复发完整Prompt。
5. AI代码翻车后的排查方法
5.1 我自己遇到最多的三类问题
再厉害的AI也会翻车,关键是快速定位。我把常见问题总结成了一个表,方便你对照排查。
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 浏览器打开HTML后图表一片空白 | 容器div没有高度,或script代码在div渲染前执行 | 给#chart设置显式高度,把script放到body最后,或使用window.onload初始化 |
| 柱状图顺序和想象不一样 | AI忽略了排序指令,或数据中的中文排序逻辑改变 | 在数据里预先按金牌降序排好,Prompt里再次强调;也可以在AI返回的series.data里手动调整顺序 |
| 中文全部显示为方块或乱码 | 文件保存时用了非UTF-8编码,或未指定中文字体 | 记事本另存为时选择UTF-8,Prompt中要求字体为Microsoft YaHei |
5.2 把报错喂给AI的正确姿势
很多人遇到报错,就给AI发一句“图表不显示,帮我看看”。在AI眼里,这句话几乎没有信息量。我建议把能收集到的信息全部贴过去,标准模板是:
我用了你生成的HTML代码,保存为index.html后用浏览器打开,图表区域是空白的。浏览器控制台报错:Uncaught TypeError: Cannot read properties of undefined (reading 'setOption')。完整代码是这样的:……(粘贴你的完整HTML)这里的重点是:操作步骤、页面现象、控制台报错、完整代码四件套。AI看到了上下文,才能帮你做具体定位,而不是给你一套泛泛的检查清单。
5.3 用追加Prompt微调,不要重新开对话
AI生成的V1代码一般就能用,但如果你想要一些样式微调,最省力的方式是继续保持同一对话追加需求。比如:
现在把图表背景改成浅灰色,图例放到底部,金牌柱子上增加白色描边。它会在刚才的代码基础上改,不会重新发明一套。这样做的好处是,改完你可以直接复制完整最终代码,不用自己拼合。但要注意,如果AI在续写中代码越写越乱,你可以让它“把当前完整HTML重新输出一遍”,这时候AI会给你一份干净的最终版。
6. 更进一步:用Flask+ECharts把它变成一个小应用
6.1 为什么从静态HTML走向Flask
静态HTML适合一次性展示,但如果你希望数据来自数据库、接口或后台文件,静态页面就不够用了。Flask这种轻量级Python框架搭配ECharts是非常经典的组合,网上常看到“Flask+ECharts数据可视化”项目,农产品价格、网约车数据、校园大数据都爱用这套。原因很简单:Python处理数据方便,Flask能快速起一个Web服务,前端用ECharts展示,开发成本低。
6.2 最简Flask应用长什么样
假设我们要把刚才的图表变成一个动态数据应用,后端从内存变量读取数据,前端用模板渲染。项目结构大概是这样:
app.py templates/ index.htmlapp.py 代码:
from flask import Flask, render_template import json app = Flask(__name__) @app.route('/') def index(): # 这里可以改成从数据库或CSV读取数据 data = { 'categories': ['中国', '日本', '韩国', '印度'], 'gold': [201, 52, 42, 38], 'silver': [111, 43, 59, 31], 'bronze': [71, 23, 68, 43] } return render_template('index.html', data=json.dumps(data, ensure_ascii=False)) if __name__ == '__main__': app.run(debug=True)注意json.dumps(..., ensure_ascii=False)这一步很重要,如果省略,中文会变成\u4e2d\u56fd这样的转义字符串,前端拿到还要再处理。
templates/index.html 作为模板:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> </head> <body> <div id="chart" style="width:100%;height:600px;"></div> <script> var data = {{ data|safe }}; var chart = echarts.init(document.getElementById('chart')); chart.setOption({ title: { text: '亚运会奖牌榜TOP4', left: 'center' }, tooltip: { trigger: 'axis' }, legend: { data: ['金牌', '银牌', '铜牌'], top: '8%' }, xAxis: { type: 'category', data: data.categories }, yAxis: { type: 'value' }, series: [ { name: '金牌', type: 'bar', data: data.gold }, { name: '银牌', type: 'bar', data: data.silver }, { name: '铜牌', type: 'bar', data: data.bronze } ] }); window.addEventListener('resize', function() { chart.resize(); }); </script> </body> </html>6.3 用自然语言让AI完成“Flask化”改造
如果你不想手写上面这些Flask代码,也可以继续用AI。在刚才同一个对话里追加一句:
现在把刚才生成的index.html改造为一个Flask应用。要求:1. app.py中定义一个路由,返回渲染index.html;2. 把图表要用的categories、gold、silver、bronze数据放到app.py的变量中,通过render_template传给模板;3. 模板里的script中使用safe过滤器接收JSON数据;4. 保持图表样式不变。只输出app.py和templates/index.html两个文件的完整代码。这一步的本质是让AI在已有代码基础上做“项目结构改写”,比从零生成整个项目成功率高得多。改完之后你本地运行python app.py,打开 http://127.0.0.1:5000 就能看到动态页面。
再往后,你甚至可以让AI帮你把数据源换成数据库,或者增加一个根据国家筛选的交互功能。只要数据源是干净的,AI完成这些扩展都不算特别吃力。
回到开头那个问题:为什么说5分钟够用?因为现在AI把“代码翻译”这部分时间几乎压缩没了。我自己的体会是,真正决定可视化效率的,已经不是Prompt写得多漂亮,而是你手里的数据够不够干净、结构够不够清楚。数据一乱,AI怎么救都救不回来;数据清楚了,5分钟出一张专业图表真不是夸张。最后再分享一个小技巧:对话式AI每次重新开窗口后上下文会清零,如果你要在不同项目里复用这套Prompt,记得把数据和Prompt组合在一起保存成一个模板文件,下次直接改数据部分就好。