记一次骚操作
起来再写吧嘻嘻嘻——2019.4.2 00:55
好了我已经起来了嘻嘻嘻——2019.4.2 13:22
事情是这样子的,就我要做毕设嘛,搞什么数据可视化,就是爬到数据然后画个图出来?然后我想用python,因为我编程白痴好上手,不是有那个pyecharts的库嘛,想着把高铁火车的班次用线画到中国地图上,就大概像下面那样:
哇桂格即食燕麦片的吸水能力真的是爆炸,碗里吃的变成了糊糊。。。我百度看别人的代码要import库里面的Style和GeoLines两个类嘛,然后我死活import不了,好像是库里面没有emmmm,弄了大半天不行,就更新了一下,它更新到了0.5.11版本,然后安装个pyecharts_snapshot就可以导入那两个类了:
python3 -m pip install --upgrade pyecharts
python3 -m pip install pyecharts_snapshot
pyecharts里面有一些城市的经纬度数据,但是火车站点的几乎没有,我就百度申请了一个ak,把我要用到的站点经纬度爬下来编好格式,插入到它存放经纬度数据的地方,下面是爬取经纬度数据的脚本(看我连类都不会写就知道我是白痴了):
import requests, json
if __name__ == '__main__':
ak = '百度申请的ak号,是免费的,注册一个账号就有了'
# placelist.txt是整理好的车站名文本
with open('placelist.txt', 'r', encoding='utf-8') as f:
place = f.readline()
place = place[:-1] # 去掉换行符\n
while place:
# place = '深圳站'
url = 'http://api.map.baidu.com/geocoder/v2/?address=' \
+ place + '火车站' \ # 加一个“火车站”搜得更准确一点
+ '&output=json&ak='
+ ak
req = requests.get(url)
req.encoding = req.apparent_encoding
# print(req.text)
data = json.loads(req.content)
# print('\"' + place + '\":' + str(data['result']['location']) + ',\n')
with open('text.txt', 'a', encoding='utf-8') as wf:
wf.write('\"' + place + '\":' + str(data['result']['location']) + ',\n')
place = f.readline()
place = place[:-1]
(诶我牙膏掉桌子上了)其实在旧版本的pyecharts我也做过这样的事情,那时候是要画一个散点图,也是要加经纬度数据,用的是Geo类,其实在add()函数(也就是加数据的函数)里面有一个geo_cities_coords参数,可以加自定义的经纬度数据,我不知道怎么的觉得直接在库里加上去比较好用就跑去改了????那时候是在一个base.py文件里加上去的,更新了之后变成了在一个datasets文件夹里专门有一个city_coordinates.json文件,要在那里面加。
geo.add("", name, testData, visual_range=[0, 3000], maptype='china',
visual_text_color="#fff", symbol_size=10, is_visualmap=True, geo_cities_coords=posData)
然后就是魔改重头戏了23333 我找到了pyecharts在GitHub上的文档嘛,就照着它慢慢地加数据上去还有改效果,然后我发现线上面有箭头,还有车站的点太大了,一坨的不好看,就想改一下,然后PyCharm是不是没有函数参数的自动补全啊?就我在括号里打参数名的时候它也不说对还是错,也没有提示,我都不知道有没有调整这些效果的参数,就弄不了。。哦哦哦原来是有的,我那时候是想看函数全部有的参数,现在知道可以按住Ctrl点进去慢慢找就有了,呜呜呜我怎么那么菜啊
然后!我就想不如去看一下源代码吧,说不定可以找一下!然后我就去看库里有一个echarts文件夹,点开里面的geolines.py看,哇写得贼整齐,还有中文注释惊了,然后我看到了这个:
我寻思着它写着一个“lines”,应该是对应线条的参数,里面有一个“symbol”,默认是none和arrow,那不就是单项的箭头吗?!我就到程序里style.add()里加上一个symbol='none',居然成功了!当时我就觉得哇我真是个天才23333
可是那个点还是很大啊,因为在Geo类里面这个点是可以调大小的,我就想也找一下看能不能改,结果它规定死了是10,我就自己加一个新变量,在开头那里加上去,结果真的可以!我当时就觉得好神奇啊,还可以这样子????关键我在程序里加了个scatter_size=5还真能用了,点变小了????????????????2333
关于这个中文注释的事啊,我后来弄明白了,原来有一个叫echarts的js库,是百度搞出来的,用来做数据可视化的,然后这个pyecharts就是使得能在python里用这个echarts,不用写js,也是国人的大佬搞的,所以是有中文注释的
echarts网站:https://echarts.baidu.com/index.html
pyecharts GitHub文档:http://pyecharts.org/#/
最后贴一个代码吧,做了一个高铁火车班次的图,不同颜色表示一天之内班次的多少,还是比较简陋,要慢慢改
from pyecharts import GeoLines, Style
import json, re
if __name__ == '__main__':
ODPairList = []
ODPairDict = {}
ODPairPattern = re.compile(r'([\u4e00-\u9fa5]+)-([\u4e00-\u9fa5]+)')
with open('Data/train_list_181206.json', 'r', encoding='utf-8') as trainListFile:
jsonData = json.loads(trainListFile.read())
for trainType in ['G', 'D', 'C', 'Z', 'T', 'K', 'O']:
for train in jsonData['2018-12-06'][trainType]:
ODStr = re.search(ODPairPattern, train['station_train_code']).group()
ODPair = ODStr.split('-')
if ODPair not in ODPairList:
ODPairList.append(ODPair)
ODPairDict[ODStr] = 1
else:
ODPairDict[ODStr] += 1
# print(ODPairList)
# print(ODPairDict)
style = Style(
title_top="#fff",
title_pos="center",
width=1600,
height=900,
background_color="#505050" # echart background color
)
style_geo = style.add(
# line_curve=0.2,
# line_opacity=0.6,
legend_text_color="#eee",
legend_pos="right",
border_color="#303030", # map border color
# geo_effect_symbol="plane",
# geo_effect_symbolsize=15,
symbol='none',
scatter_size=5,
geo_normal_color="#505050", # map normal color
geo_emphasis_color="#BDBDBD", # map highlight color
label_color=['#9C27B0', # purple
'#AD1457', # pink
'#e53935', # red
'#FF5722', # deep orange
'#FF9800', # orange
'#FFC107', # amber
'#FFEB3B', # yellow
'#CDDC39', # lime
'#8BC34A', # light green
'#4CAF50', # green
'#009688', # teal
'#00BCD4', # cyan
'#03A9F4', # light blue
'#2196F3' # blue
],
is_label_show=False,
# label_pos="right",
# label_formatter="{b}",
# label_text_color="#37474F", # map text color
# legend_selectedmode="single", # 指定单例模式
is_geo_effect_show=False
)
lineList = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
]
for pair in ODPairList:
pairStr = pair[0] + '-' + pair[1]
lineList[ODPairDict[pairStr] // 10].append([pair[0], pair[1], ODPairDict[pairStr]])
print(lineList)
g = GeoLines("title", **style.init_style)
for i in range(len(lineList) - 1, -1, -1):
g.add(str(i), lineList[i], **style_geo)
g.render(r'C:\Users\Administrator\Desktop\test.html')
最最后总结一下吧, 首先这样对python里的库魔改好像不太好,以后一更新或者项目换个地方什么的就崩掉了,我也有点理解PyCharm建项目的时候搞一个venv而不是直接用电脑里的python的意义了。然后,虽然说这是一次骚操作,但回想起来都比较普通,就是往库的源代码里加点东西而已,主要是我以前没有做过这样的事情,也对阅读源代码一窍不通,才会觉得很特别,所以说还是任重道远啊,加油吧