最近,本人在处理站点经纬度数据,想将站点数据绘制在地图上,但是总觉得matplotlib内自带的图标很普通,为了标新立异,一直试图将图标变得与众不同。比如:在处理雷达站点信息时,想将雷达的图标花在地图上。
终于,在费劲九牛二虎之力,终于将图像绘制成这样的:
那么这张图如何绘制呢,下面将详细记录绘制方法。
1. 找到自己心仪的图标
介绍一个超级方便的免费矢量图下载网址:
在这个图标库内,能下载到各种的svg图片。
举个栗子:在搜索雷达后,得到了下面这个界面
将鼠标移至心仪的图标上后,显示如下,点击最下方的下载按键后,再点击svg下载,得到了一个图标矢量文件(.svg)
2. 处理svg文件,将svg文件处理为path格式
利用svgpath2mpl模块对矢量图进行处理,将其转化为Path格式,为后续变成图标做基础
定义一个svg2path 函数:
import matplotlib.path as mpath
from svgpath2mpl import parse_path
import xml.etree.ElementTree as etree
from six import StringIO
import numpy as np
def rot(verts, az):
#顺时针旋转
rad = az / 180 * np.pi
verts = np.array(verts)
rotMat = np.array([[np.cos(rad), -np.sin(rad)], [np.sin(rad), np.cos(rad)]])
transVerts = verts.dot(rotMat)
return transVerts
def svg2path(svg_rda):
# svg_rda = "./rad_icon.svg"
tree = etree.parse(svg_rda)
root = tree.getroot()
path_elems = root.findall('.//{http://www.w3.org/2000/svg}path')
paths = [parse_path(elem.attrib['d']) for elem in path_elems]
verts = paths[0].vertices
codes = paths[0].codes
for i in range(1, len(paths)):
verts = np.concatenate([verts, paths[i].vertices])
codes = np.concatenate([codes, paths[i].codes])
verts = rot(verts, 270)
verts = np.fliplr(verts) # 水平翻转,镜像
icon = mpath.Path(vertices=verts, codes=codes)
return icon
这个函数中,svg_rda为矢量图文件,得到的icon为图片的path格式。
3.将矢量图作为图标在散点图上进行绘制
ax.scatter(new_lpar_lons, new_lpar_lats, s=100, c="#c875c4", marker='.',label=label5)
绘图语句中,marker='.'表示散点图中的图标为点图,即:
而将图标改为我们自设的图标,绘图语句为:
import svg2icon
rda_icon = svg2icon.svg2path('./rad_icon.svg')
ax.scatter(rda_SA_lons, rda_SA_lats, s=100, c="#8ffe09", marker=rda_icon)
这样就能看到,图标变成雷达矢量图的样式了。
4. 普通的散点图图标
在利用matplotlib绘制散点图时,其market都有着对应的代表,具体可以参考:
https://www.cnblogs.com/Big-Big-Watermelon/p/14052165.html
1. 这类普通marker,利用 market='^'就可以用了
2. 高级marker
这类高级marker使用 market = '$\circledR$'来调用(具体见链接)