
简介一套面向数据分析师、开发者和可视化爱好者的PythonEcharts大屏案例合集收录10套可直接运行与二次改造的完整数据看板适用于多类业务数据的可视化展示与汇报解决从数据清洗、图表配置到界面发布的全流程问题。资源包共1242个文件压缩体积约21.22MB以JavaScript、HTML、CSS、Python及JSON为主要类型JS文件驱动Echarts交互与图表渲染HTML/CSS负责页面骨架与视觉样式Python脚本辅助数据预处理和自动化配置png、svg等图片素材与woff2、ttf字体文件则为图标、背景与排版提供支撑另含bat脚本便于快速打包或启动。目前已有3871人学习下载适合作为项目模板、课堂案例或毕业设计参考。每套案例均包含可运行页面、图表配置代码与基础数据文件按需替换数据即可生成专属大屏能够有效缩短可视化项目开发周期提升数据展示的专业度与交互体验。1. 数据可视化大屏10套PythonECharts案例能解决什么做数据可视化大屏的人都知道一个尴尬数据早就跑出来了但汇报时PPT放出去领导问一句“这个图能不能点开看看”现场直接冷场。PythonECharts的组合之所以在可视化大屏里流行不是因为ECharts比别的库漂亮多少而是因为它从图表配置到数据对接的链路最短——Python后端处理好数据ECharts前端渲染一套代码同时覆盖查数、画图、上屏三个环节。这套10套案例的资源就是把“数据→图表→大屏”这条链路按不同业务场景拆开做成可以直接改数据复用的模板适合正在做课设、公司内部驾驶舱或者想快速给客户出demo的前端和后端开发。2. 案例拆解大屏最常见的三种形态和它们的选型逻辑2.1 销售与经营看板类ECharts柱状图折线图组合这10套里占大头的是销售、运营类的经营看板。这类大屏的共性是顶部一排KPI指标卡中间是柱状图和折线图的组合底部放排名列表或饼图。为什么老用柱状图加折线图因为经营数据就只有两类关系——不同部门/不同月份的对比以及随时间变化的趋势。柱状图适合凸显对比差异折线图适合交代走势两者叠加在一张大屏上看的人不用切换页面就能完成“谁卖得好→为什么好→趋势怎么样”的阅读路径。这类案例的ECharts配置有个共同技巧柱状图不要用默认的矩形柱子改成圆角、带渐变色。渐变色在视觉上的作用不只是好看它能利用颜色深浅把数值差异放大比如柱子的渐变从浅蓝到深蓝越到顶部颜色越深观众不用看具体坐标轴数值也能直观感受大小。选项也顺手把柱子的最大宽度限制住比如barMaxWidth: 32否则大屏分辨率拉高以后柱子会变得又扁又宽毫无精致感。配置里绕不开的一个参数是grid。很多人只调left/right/top/bottom四个值资源里更细一点的做法是给grid加containLabel: true让坐标轴刻度标签不被挤到图表外面——在大屏布局中图表组件之间间距通常是固定像素标签溢出去就会压到相邻的卡片这在开发环境看不出问题一上大屏就翻车。2.2 地理分布与监控预警类ECharts地图和散点图的配合第二类常见案例是带地图的监控大屏比如全国销售分布、设备在线状态、物流轨迹。地图类大屏的选型关键不在图表配置而在数据格式——ECharts的地图必须绑定GeoJSON数据而GeoJSON默认包往往比较旧边界线和现在的行政区域对不上。案例里一般会内置一份全国各省的GeoJSON或者用registerMap动态注册外部地图数据这个细节比图表本身的样式重要得多。地图类大屏通常叠加两种图层散点图表达“点”的分布飞线图表达“点与点之间的流动”。散点图scatter的配置重点在scale和symbolSize用来区分数据量级飞线图lines则要设置effect系列里的trailLength来控制拖尾长度。这里的技巧是底图的视觉层级必须压下去比如把地图itemStyle的areaColor调暗让飞线和散点跳出来。绝大多数新人会把地图做得比数据层还醒目结果飞线全被背景色吞掉这是最典型的失败案例。地图案例里还会涉及一个Python侧的问题从数据库读出来的省市名称常常不规范——有人存“内蒙古”有人存“内蒙古自治区”如果直接拿去匹配GeoJSON的name属性地图上就会缺一块。地市级大屏做数据清洗时我一般会建一个省市名称映射字典在生成ECharts配置前先把名称标准化。2.3 实时数据流与轮播类大屏的“动”不是靠动画第三类案例是实时监控或数据轮播大屏比如网约车订单实时监控、污水处理厂在线监测这类项目。这类大屏的核心诉求是“新数据进来页面不用刷新就更新”以及“多条数据在有限屏幕空间里循环展示”。先说实时刷新。案例里最常见的实现不是WebSocket而是setInterval轮询——Python后端提供一个JSON接口前端每隔3到5秒请求一次拿到最新数据后调用chart.setOption()更新。为什么不用WebSocket因为大部分大屏项目部署在客户内网WebSocket需要单独维护长连接内网防火墙策略不配合时调试成本高轮询虽然有一两秒的延迟但对看板场景完全够用。再说轮播。表格、排行榜这类列表组件在大屏上空间有限10条数据放不下案例里的做法是做成透明轮播通过CSS动画让列表整体向上滚动到末尾后切回顶部配合ECharts图表的dataZoom组件可以让图表在自动轮播时按窗口滚动显示不同时间段的数据。这里有一个容易被忽略的配置——dataZoom的start和end如果是数值型只对图表生效一次案例里通常用dispatchAction来动态控制dataZoom的窗口位置才能做到图表和数据列表同步轮播。3. 图表参数落地把静态demo改成能上大屏的配置3.1 柱状图与饼图的渐变色、圆角与间距优化这10套案例里柱状图和饼图的代码模式高度一致我直接给出一个贴近案例实际风格的配置并说明每段参数的作用。option { color: [#2E96FF, #36D6B6, #FFB239], tooltip: { trigger: axis, backgroundColor: rgba(0,0,0,0.7), borderWidth: 0, textStyle: { color: #fff } }, grid: { left: 3%, right: 4%, bottom: 3%, top: 8%, containLabel: true }, xAxis: { type: category, data: [华东, 华南, 华北, 西南], axisLine: { lineStyle: { color: rgba(255,255,255,0.3) } }, axisLabel: { color: #B8C4D3 } }, yAxis: { type: value, splitLine: { lineStyle: { color: rgba(255,255,255,0.1) } } }, series: [{ name: 销售额, type: bar, barMaxWidth: 32, itemStyle: { borderRadius: [6, 6, 0, 0], color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: #2E96FF }, { offset: 1, color: rgba(46,150,255,0.25) } ]) }, data: [220, 182, 191, 234] }] };逻辑说明grid.containLabel: true保证了纵轴刻度和“销售额”字样不会被挤出图表区域barMaxWidth限制柱子最大像素宽度避免1920分辨率下柱子过宽borderRadius把柱子顶部做成圆角这是大屏视觉里常用的“卡片化”观感LinearGradient的四个参数分别代表渐变方向起点x、起点y、终点x、终点y(0,0,0,1)表示从上到下渐变offset:0对应柱子顶部颜色最亮offset:1对应柱子底部。饼图在这个案例里主要作为占比展示。大屏上的饼图最容易犯的错是把图例放在饼图右侧导致空间浪费。案例里比较稳妥的做法是legend放到底部、orient: horizontal同时给label加上formatter用{b}: {d}%显示“名称:百分比”。3.2 折线图平滑、面积渐变和x轴刻度处理折线图在大屏里的角色是趋势展示这里有一组热搜里很多人问的配置——x轴刻度怎么处理以及面积渐变areaStyle怎么设置。很多人折线图的x轴标签挤在一起黑压压一片问题通常出在没开axisLabel.interval或者没设dataZoom。option { xAxis: { type: category, data: [09:00, 10:00, 11:00, 12:00, 13:00, 14:00, 15:00], axisLabel: { color: #B8C4D3, interval: 1, // 每2个刻度显示1个数值0表示全部显示 rotate: 0 } }, yAxis: { type: value, axisLabel: { color: #B8C4D3 }, splitLine: { lineStyle: { color: rgba(255,255,255,0.08) } } }, series: [{ type: line, smooth: true, symbol: circle, symbolSize: 6, lineStyle: { width: 3, color: #36D6B6 }, areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: rgba(54,214,182,0.4) }, { offset: 1, color: rgba(54,214,182,0) } ]) }, data: [120, 200, 150, 280, 190, 300, 260] }] };这段配置里最值得说的是interval: 1。它的含义是“隔一个刻度显示一个标签”当x轴数据是整点时间且有几十个点时全显示会重叠不显示又看不懂interval设为1或2是实践里最常见的折中。smooth: true把折线变成平滑曲线大屏场景通常选平滑视觉上更柔和但需要注意业务方如果要求精确读数值平滑曲线会引入轻微偏移这种场景就用smooth: false。areaStyle就是热搜里说的“面积渐变”。它让折线下方形成一个从rgba(54,214,182,0.4)到完全透明的渐变区域。它带来的好处是让趋势区间在视觉上有“厚度”几组折线叠在一张图里时填充面积能帮助区分不同系列。3.3 地图与飞线registerMap的正确打开方式地图慢或者地图不显示九成问题出在registerMap的调用顺序和数据格式上。正确顺序是先注册GeoJSON再setOption。而且GeoJSON里的name字段必须和series.data里的name完全一致差一个空格都渲染不出来。// 1. 加载并注册地图数据 fetch(china.json) .then(res res.json()) .then(geoJson { echarts.registerMap(china, geoJson); initChart(); }); // 2. 在initChart里配置地图和飞线 function initChart() { const chart echarts.init(document.getElementById(mapChart)); chart.setOption({ geo: { map: china, roam: false, itemStyle: { areaColor: rgba(20,40,80,0.7), borderColor: rgba(100,180,255,0.6) }, emphasis: { itemStyle: { areaColor: rgba(30,80,140,0.9) } } }, series: [ { type: lines, coordinateSystem: geo, zlevel: 2, effect: { show: true, period: 4, trailLength: 0.4, symbol: arrow, symbolSize: 6 }, lineStyle: { color: #FFD666, width: 1.2, opacity: 0.8 }, data: [ { coords: [[116.405285, 39.904989], [121.473701, 31.230416]] }, { coords: [[121.473701, 31.230416], [113.264385, 23.129112]] } ] }, { type: scatter, coordinateSystem: geo, data: [ { name: 北京, value: [116.405285, 39.904989, 100] }, { name: 上海, value: [121.473701, 31.230416, 88] } ], symbolSize: function(val) { return val[2] / 10; } } ] }); }逻辑说明lines系列里的coords是一个二维数组第一个点是起点、第二个是终点ECharts会自动画一条弧线。effect.trailLength控制飞线拖尾长度数值0到1之间0.3~0.5看起来比较利落。symbolSize: function(val)把散点大小和数据值绑定数据越大点越大这就是地图大屏上常见的热力分布效果。地图能不能正常显示取决于geo.map的名称是否和注册名一致这里注册为china配置里也必须是china。4. 大屏页面骨架布局、自适应缩放和数据接口对接4.1 大屏布局flex还是grid按什么基准设计这套案例有一个共同点页面结构几乎都是“顶部标题栏中间图表区底部补充信息区”图表卡片之间用固定间距。布局层面推荐在CSS里用一个基准设计稿尺寸通常以1920×1080为基准。因为大多数大屏投放场景是16:9的屏。用rem或者vw/vh做适配时所有尺寸按基准宽度换算背后原理是等比缩放。html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #0A1428; font-family: Microsoft YaHei, sans-serif; } .screen-wrapper { width: 1920px; height: 1080px; transform-origin: left top; display: grid; grid-template-columns: 420px 1fr 420px; grid-template-rows: 80px 1fr 260px; gap: 16px; padding: 16px; box-sizing: border-box; } .card { background: rgba(16, 32, 60, 0.75); border: 1px solid rgba(70, 140, 255, 0.25); border-radius: 8px; padding: 12px; box-sizing: border-box; }逻辑说明这里最核心的是.screen-wrapper的transform-origin: left top配合后面要写的JS缩放逻辑使用。grid-template-columns: 420px 1fr 420px表示左侧和右侧各固定420px放指标卡和排行榜中间1fr自适应放主图表。固定像素布局配合整体缩放比全百分比布局更可控——百分比布局在小屏上会挤压图表比例而缩放方案始终保持设计稿的视觉比例只是整体缩小。4.2 自适应缩放为什么用scale而不用百分比大屏投放的屏幕分辨率千差万别从1080P到4K拼接屏都有。案例里普遍采用的方案是按照屏幕宽高比动态计算缩放比例用CSS transform的scale属性把整个页面等比缩放。只缩放到可以用的方法是先算window.innerWidth / 1920和window.innerHeight / 1080取两者中较小值作为缩放系数这样能保证整块大屏内容完整显示不被裁剪。function adaptScreen() { const designWidth 1920; const designHeight 1080; const wrapper document.querySelector(.screen-wrapper); function setScale() { const scaleX window.innerWidth / designWidth; const scaleY window.innerHeight / designHeight; const scale Math.min(scaleX, scaleY); wrapper.style.transform scale( scale ); } window.addEventListener(resize, setScale); setScale(); } adaptScreen();这套方案有个边界问题如果屏幕不是16:9比如超宽拼接屏Math.min取出的比例会导致页面上下或左右出现黑边。实践里的做法是先做背景填充把黑边区域用深色背景覆盖再让大屏内容居中视觉上就变成“内容区氛围背景”比强行拉伸比例让图表变形要好看得多。注意在scale之外还要配合transform-origin: left top否则缩放中心会是页面中心左上角就会多出一块空白。4.3 数据接口对接Flask返回JSON和前端setOption的衔接案例里的数据来源有两种一是直接写在JavaScript里的静态数据代码改动最小、适合演示demo二是通过Python后端从数据库或Excel读取后返回JSON适合真实业务。第二种方案里最稳的组合是Flaskpymysql/sqlite代码如下from flask import Flask, jsonify import pymysql app Flask(__name__) def fetch_sales_data(): conn pymysql.connect( hostlocalhost, userroot, passwordyour_password, databasesales_db, charsetutf8mb4 ) cursor conn.cursor() cursor.execute(SELECT region, SUM(amount) FROM sales GROUP BY region) rows cursor.fetchall() cursor.close() conn.close() return [{name: row[0], value: float(row[1])} for row in rows] app.route(/api/sales) def sales_api(): data fetch_sales_data() return jsonify({code: 0, data: data})前端接收并更新图表核心逻辑如下async function refreshChart() { try { const res await fetch(/api/sales); const json await res.json(); if (json.code 0) { myChart.setOption({ series: [{ data: json.data.map(item item.value) }] }); } } catch (e) { console.error(大屏数据加载失败, e); } }逻辑说明把pymysql.connect里的事务、连接关闭放在请求处理内虽然简单但对大屏展示足够。jsonify返回时默认会把中文转成Unicode编码浏览器解析后能正常显示但如果文件里是ensure_asciiTrue抓包看接口会是一堆\u5...排查问题时不直观可以加一句app.config[JSON_AS_ASCII] False把中文直接输出。前端fetch到的数据只需更新series.data不要整个setOption全量替换配置那样会丢失动画效果并造成渲染卡顿。5. 项目复现的避坑清单十个常见报错和配置翻车点5.1 图表缩放后文字模糊现象大屏页面套用了transform: scale()缩放图表里的数字和文字边缘发虚像被涂抹过一样。原因浏览器对scale缩放的渲染是位图重采样缩放系数不是整数倍时文字和线条的边缘会被插值处理产生模糊。解决文字和图表容器尺寸不要跟着scale一起缩改成先按1920×1080设计稿把页面渲染清晰再通过CSS的zoom属性或者ECharts自带的devicePixelRatio设置渲染分辨率。常见做法是给echarts.init传入{ devicePixelRatio: window.devicePixelRatio }让图表在4K屏上用更高分辨率渲染文字边缘会锐利很多。5.2 ECharts地图白屏或不显示边界现象页面其他图表正常只有地图区域一片空白控制台也不报错。原因registerMap的GeoJSON加载是异步的在数据还没返回时就执行了setOption或者GeoJSON的name和series数据里的name不完全一致。解决把setOption放进.then回调里同时打印一下geoJson.features[0].properties.name跟数据里的名称逐一比对。血泪经验数据库里的“广西”和GeoJSON里的“广西壮族自治区”匹配不上地图就会少一块排查半天才发现是名称映射问题。5.3 resize事件反复触发导致图表闪烁现象大屏页面开在那里不动图表每隔几秒自己闪一下像是被重新渲染。原因某个图表用了resize事件监听而页面里又多了一个自适应脚本两个监听互相触发导致ECharts不断重新计算尺寸并重绘。解决给resize事件做节流并且在window.addEventListener(resize, handler)里标记一个requestAnimationFrame同一帧内多次resize只执行一次图表chart.resize()。这也是为什么4.2节里的adaptScreen不直接调用ECharts的resize而是只负责计算页面缩放系数图表本身的resize由图表统一管理。5.4 折线图几万条数据直接卡死现象折线图数据点多于5000个之后鼠标划过或拖动时页面明显卡顿CPU占用飙高。原因ECharts默认对所有数据点做完整渲染数据量大时绘制开销成倍增长。解决开sampling参数首选sampling: lttb它会用Largest-Triangle-Three-Buckets算法做抽稀保留趋势特征同时大幅减少渲染点。还可以叠加dataZoom让图表只显示当前窗口内的数据。注意dataZoom的type: slider和type: inside在大屏上一般只留inside拖动才出现避免滑块占据屏幕边缘空间。5.5 中文乱码和JSON解析失败现象接口返回的数据在浏览器里显示正常但ECharts图表加载后中文全部变成问号或者JSON.parse直接报错。原因HTML页面没有声明UTF-8字符集或者Python端用Flask的jsonify返回时被改成了ASCII编码更常见的是后端返回的JSON字符串里直接拼接了未转义的引号。解决HTML头部加meta charsetUTF-8Python字典里所有字符串都交给jsonify序列化不要手动拼json.dumps后再当作字符串返回。前端解析时优先用res.json()而不是JSON.parse(await res.text())这样可以避免各种编码转换的坑。5.6 大屏在拼接屏上被拉伸变形现象客户用的是四块屏拼成的整屏分辨率是3840×2160页面放到整屏上后图表被左右拉宽圆形饼图变成了椭圆。原因只做了width/1920和height/1080的线性缩放没有保持宽高比。解决回到4.2节说到的方案取Math.min(scaleX, scaleY)做等比缩放黑边区域用背景图填充。如果客户坚持要铺满就得把整块屏当作一个超宽屏重新设计栅格布局而不是把标准16:9页面硬拉。大屏项目里等比缩放永远比铺满重要——变形的大屏在演示时一眼就能被看出来这是我做过的最多的返工原因。5.7 页面刚打开时图表高度为0现象大屏刷新后图表区域是空白等几秒后数据才出来图表的canvas高度是0。原因图表所在的DOM容器在页面缩放和布局完成前高度还没有被撑开此时echarts.init拿到的高度是0。解决把图表初始化放到页面布局计算之后比如window.onload回调里再init或者在初始化前加一个setTimeout等待布局完成。更稳妥的做法是用ResizeObserver监听容器尺寸变化容器尺寸稳定后再执行setOption。5.8 setInterval轮询叠加造成请求堆积现象大屏页面运行到第二天看网络面板发现有大量重复的接口请求进程内存占用持续上涨。原因页面被切到后台时setInterval依然在跑回到前台时又继续累积如果某次请求响应慢而半个后一次轮询又发出去请求队列就会越堆越多。解决定时器里做请求冲突处理——每次请求开始时先clearInterval暂停轮询请求完成且数据处理完后再重新启动代码如下async function startPolling() { clearInterval(timer); await refreshChart(); timer setInterval(refreshChart, 5000); }5.9 ECharts动画导致数据错位现象数据更新后柱状图数值变化的瞬间旧柱子和新柱子交替闪现像在“抖动”。原因setOption时没有指定动画策略ECharts默认对变化的数据做动画过渡数据顺序变化时新旧柱子匹配错位。解决更新数据时加notMerge参数即myChart.setOption(newOption, true)强制用新配置替换旧配置而不是合并。注意如果用了notMerge: true原来设置的media、backgroundColor这类属性也会被重置要一起带进新option里。5.10 开发环境正常、打包后接口404现象本地用npm run dev一切正常部署到服务器后用nginx托管大屏接口全部404页面只有空壳。原因前端页面和Python后端分别部署在不同端口或路径请求地址写死了http://localhost:5000/api/sales部署后指向了错误地址。解决把接口地址抽到一个配置文件里根据环境变量切换。Python端则要排查Flask的端口是否被防火墙拦着以及nginx的proxy_pass是否指向正确。大屏交付给客户时最省事的方式是让nginx直接把静态页面和Flask接口放在同一个域下通过反向代理把/api前缀的请求转发到Flask的5000端口避免跨域和路径问题。6. 让大屏在真实环境里长期稳定运行定时刷新、异常兜底与性能验证大屏交付后真正考验人的不是第一眼效果而是能不能在客户现场放一周不崩。前端页面的图表如果只是静态数据那和截图没区别但加上定时刷新后内存泄漏、请求堆积、图表渲染卡顿这些问题会在运行几天后集中爆发。我通常会给大屏加两套兜底机制第一是页面可见性监听页面切到后台时立刻暂停所有数据和动画回到前台再恢复第二是每次请求失败不静默吞掉而是在控制台输出一条结构化错误日志同时保留上一次成功返回的数据继续展示——让大屏显示旧数据总比白屏好这是现场演示时最实际的后悔药。document.addEventListener(visibilitychange, function () { if (document.hidden) { clearInterval(timer); } else { startPolling(); } });另一个容易忽略的验证点是长时间运行后的帧率。打开浏览器开发者工具的性能面板录制30秒运行过程重点看ECharts的Canvas重绘耗时和内存占用曲线。如果内存曲线持续上升不回落优先检查代码里是否反复创建echarts.init实例而没dispose如果重绘耗时高则优先检查sampling和notMerge有没有正确设置。上面这段代码的逻辑说明visibilitychange事件在页面切换到后台或回到前台时触发后台暂停轮询、前台立即拉一次最新数据并恢复定时器这样既省资源又保证回到大屏时数据是最新的。注意clearInterval(timer)之后要重新startPolling()因为原来的定时器ID已经失效了。如果大屏需要交互下钻比如点击“华东”柱子跳到该地区的明细大屏可以用ECharts的chart.on(click, params ...)事件拿到params.name后跳转路由或切换数据。这类交互一定要先验证图表事件在缩放状态下点击坐标是否偏移——我被这个问题坑过大屏套了scale(0.5)之后点击柱子的命中区域会错位只能通过chart.getZr().on(click)手动换算坐标从那以后我每做完一个大屏交互都会强制跑一遍“模拟点击坐标偏移测试”对照设计稿上的位置逐个点击验证确认无误才敢交付。最后一条习惯是现在项目交付的底线要求所有大屏代码上线前必须把关键数据接口加超时时间Python端用pymysql.connect时加上read_timeout10前端fetch挂一个AbortController超时中止。大屏不像后台管理系统没人会去点刷新按钮一旦请求挂起页面就永远卡在那里。这一套10个案例的模板里稳定运行的优先级永远高于视觉效果我一般拿到手会先跑通接口再改样式希望帮到你。本文还有配套的精品资源点击获取