23/04/16使用pyecharts绘制中国地图并显示城市

您所在的位置:网站首页 中国红包分布地图 23/04/16使用pyecharts绘制中国地图并显示城市

23/04/16使用pyecharts绘制中国地图并显示城市

2024-07-06 21:39| 来源: 网络整理| 查看: 265

需求

近日几个高中朋友都上岸研究生,某人提议做一个求学路线图,这种技术活儿当然就交给我了。

一共是两幅图,本科城市分布图和研究生城市分布图背景是中国地图在地图中标记大学所在城市在标记点上显示每个人的头像附录显示大学名称每个人本科和研究生之间添加一条线导出为图片 环境

python 3.11.2 pyecharts 2.0.3 selenium 4.8.3 pyecharts-snapshot 0.2.0

pyecharts

官方文档 是一个基于Echarts的python工具包,用于数据可视化,可以用来画日历图、饼图、雷达图、词云图、涟漪特效图、热力图、散点图、数图、地图、3D图等

安装pyecharts pip install pyecharts pyecharts-snapshot

将 pyecharts/echarts.js 的输出呈现为 png、jpeg、gif、eps、svg 图像、原始 base64 编码或 pdf 文件

安装pyecharts-snapshot pip install pyecharts-snapshot 使用

pyecharts-snapshot用来将地图渲染成图片。 要使用pyecharts-snapshot,确保电脑正确安装Phantomjs,否则会报错,Phantomjs官网下载链接,选择符合自己电脑的版本下载。 下载完成之后,将bin加入到系统变量中。

开始绘图

使用pyecharts的过程,会学到链式调用和万物皆可对象化!

一、初始化画布

第一步,我们要画中国地图,创建一个Geo对象(地理图标)

geo = Geo()

在Geo()中初始化地图,设置一些基本的参数 一般写法

geo = Geo( width="1000px", height="600px", theme=ThemeType.ESSOS, # 地图主题 )

但是在pyecharts中有一个重要的思想就是 在这里插入图片描述 标准的写法是

geo = Geo( init_opts=opts.InitOpts( width="1000px", # 画布宽度 height="600px", # 画布高度 theme=ThemeType.ESSOS, # 地图主题 ) )

在这里使用init_opts进行初始化,init_opts是一个options,值由opts.InitOpts实例化得到,而width="1000px"...等params则作为opts.InitOpts的参数。

个人认为万物皆options有以下几点好处:

统一化:所有的图标对象都可以使用同一个参数方便查阅文档:需要哪个options就在文档中查找哪个,很直观。

比如这个InitOpts,经查阅文档后共有这么多属性

class InitOpts( # 图表画布宽度,css 长度单位。 width: str = "900px", # 图表画布高度,css 长度单位。 height: str = "500px", # 图表 ID,图表唯一标识,用于在多图表时区分。 chart_id: Optional[str] = None, # 渲染风格,可选 "canvas", "svg" # # 参考 `全局变量` 章节 renderer: str = RenderType.CANVAS, # 网页标题 page_title: str = "Awesome-pyecharts", # 图表主题 theme: str = "white", # 图表背景颜色 bg_color: Optional[str] = None, # 远程 js host,如不设置默认为 https://assets.pyecharts.org/assets/" # 参考 `全局变量` 章节 js_host: str = "", # 画图动画初始化配置,参考 `global_options.AnimationOpts` animation_opts: Union[AnimationOpts, dict] = AnimationOpts(), )

再加上一些必要的参数,完整版初始化代码如下:

geo = Geo( init_opts=opts.InitOpts( width="1000px", # 画布宽度 height="600px", # 画布高度 theme=ThemeType.ESSOS, # 地图主题 ), is_ignore_nonexistent_coord=True ) 二、设置地图类型

调用.add_schema()方法设置Geo对象的地图类型、缩放、视角中心点等

.add_schema( maptype='china' # 设置地图类型为china zoom=1.5, # 缩放比例为1.5 center=[105.95, 34.27], # 设置视角中心点为[105.95, 34.27] )

其中zoom center都是为后面导出图像设置的,效果如下 zoom为1.5 zoom为1

zoom=1,center向左偏离

三、添加点

调用geo对象的.add方法,添加需要显示的点,并设置其样式

这里最坑的是,文档中没有给出点实例,导致调试data废了很大功夫 文档描述 以北京举例:应该是("北京“, [116.407526, 39.90403]),数据项为元组类型,第一个元素为坐标点名称,第二个元素为坐标点的经度纬度,如果多个点,则data_pair为列表形式

这里有个坑,名称和经纬度必须一一对应才能正确显示,如果把北京改成北京市区,就不行了,估摸着他应该内置了一个对应关系

.add( series_name='研究生', # 这一系列点的名称 symbol_size=18, # 标志(圆圈)的尺寸 data_pair=city_graduate, # 数据项 type_="scatter", # 数据类型 label_opts=opts.LabelOpts( #标签(就是文字) is_show=True, # 是否显示标签 formatter='{b}', # 标签显示的格式 font_size=20, # 标签的文字大小 font_style="normal", # 标签的样式 )) 四、渲染HTML

调用geo.render参数为渲染后的html文件路径

.render('html/graduate.html') 五、渲染图片

第一个参数为渲染引擎,这里选择phantomjs;第二个参数是html文件路径;第三个参数是渲染后的图片文件路径

from snapshot_phantomjs import snapshot from generate_coordinate import generate_coordinate make_snapshot(snapshot, 'html/graduate.html', 'image/graduate.png') 六、整合

这里不得不提python的链式调用,十分直观,简约

geo = ( Geo( init_opts=opts.InitOpts( width="1000px", # 画布宽度 height="600px", # 画布高度 theme=ThemeType.ESSOS, # 地图主题 ), is_ignore_nonexistent_coord=True ) .add_schema( maptype='china' # 设置地图类型为china zoom=1.5, # 缩放比例为1.5 center=[105.95, 34.27], # 设置视角中心点为[105.95, 34.27] ) .add( series_name='研究生', # 这一系列点的名称 symbol_size=18, # 标志(圆圈)的尺寸 data_pair=city_graduate, # 数据项 type_="scatter", # 数据类型 label_opts=opts.LabelOpts( #标签(就是文字) is_show=True, # 是否显示标签 formatter='{b}', # 标签显示的格式 font_size=20, # 标签的文字大小 font_style="normal", # 标签的样式 ) ) .render('html/graduate.html') )

把所有有关这个对象的操作链成一个链条执行,将每个操作的结果组合,返回给geo对象。

遇到的BUG 城市不能自己命名,否则会无法正常显示如果在渲染图片的时候遇到“ReferenceError: Can‘t find variable: echarts\n\n undefined:1\nnull\n“错误,考虑项目目录中是否有中文,将其移动到纯英文目录中,问题就解决了。

这还是我google来的,仔细思考一下,can't find variable问题出在找不到echarts变量,但是echarts变量是存在的,否则画图就会报错,这样变量存在却找不到的情况,多半是路径出现问题,考虑到中文路径,以后这类Bug都可以往这方面想。

完整项目代码

github链接

成品展示 研究生城市分布 本科城市分布

总结

至此,城市分布图地图画好了!!短短的几行代码花了我六小时琢磨,反思一下:

代码版本 确认用pyecharts之后,就在直接找线程的代码,以期用最短的事件完成这个任务,关键是完全没考虑到版本问题,代码粘贴下来就是一顿报错,按照我的习惯,遇上bug就找chatgpt,谁知道chatgpt给出的代码也是版本不一致,就这样带着一次成功的功利目的,花费了大量的时间内耗。这一次真切感受到了复制代码前先确定版本号的重要性。官方文档 这些用户比较少的工具,社区、博客往往不活跃,这时候文档就是救命的东西,文档永远是最新的,pip安装的也永远是最新的,所以这俩是永远适配的。一般文档都会配有快速上手,经验之谈,5分钟的快速上手可以帮助节省50分钟之多。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3