查看原文
其他

用 Plotly 画出中国疫情地图(附源码)

Mort Python中文社区 2022-12-04

作者简介:Mort,数据分析爱好者,擅长数据可视化,比较关注机器学习领域,希望能和业内朋友多学习交流。

前两天笔者曾写了一篇名为用 matplotlib 画出中国疫情地图(附源码)的文章,当时笔者在文中就说到要写一篇关于Plotly作图的文章,今天就把该文章分享给大家。

首先对Plotly做一个简单的介绍,Plotly是一款基于D3.js框架的Python库,其功能相当强大,主要用于做交互式的数据可视化(matplotlib其实也可以做交互式,有兴趣的读者可以自行研究一下),除了Python以外,Plotly还支持R和MATLAB语言,所以其应用非常广泛,近几年发展势头相当不错。Plotly能生成的图片类型非常多,地图只是其中一种,今天主要介绍一下其绘制地图的用法。安装Plotly和其他库的方法都差不多,用pip或conda都可以(笔者用的anaconda,所以用conda安装),这里就不多介绍了。下面我们就直接上代码。

首先导入需要的包和准备数据。

import json
import pandas as pd
import plotly.express as px


file_yq = r'C:\plotly\yq-data.xlsx'
file_gs = r'C:\plotly\china_geo.json' #这个数据中要把id那一项修改了,放在properties前面,这个是已经修改好的

gs_data = open(file_gs, encoding='utf8').read()
gs_data = json.loads(gs_data)
df = pd.read_excel(file_yq, index_col=0)

这里主要用到两个数据文件,一个是疫情数据,名为yq-data.xlsx,是一个Excel文件,一个是中国地图数据,名为china_geo.json,是一个json文件。疫情数据非常简单,大家自己做就OK了,直接到各大网站上复制粘贴,so easy,中国地图数据则稍微麻烦点,因为Plotly目前仅支持json格式数据(笔者目前还没发现其他的数据格式),所以我们只能用json格式的数据,有能力的读者可以自己制作,不想自己动手的网上也有一大堆可以下载,笔者建议直接去GitHub上下载,直接在上面搜索“China geojson”就可以了。这里有一个问题要注意了,就是json数据中有一个省份的编号,即类似’id’: 14这样的一段代码,在很多中国地图数据中这段代码是放在一个类似"properties": {"name": "甘肃","cp": [100.735, 38.7393]}这样的一个dictionary中,我们要把它拿出来放在properties前面,也就是让两者成为并列关系,而不是包含关系,这个编号有多个,所以我们要把他们全部处理好。因为Plotly要通过这个id来识别省份,如果放在properties当中,Plotly读取不到,最终生成的图片是一片空白,别看就这样一个小问题,网上一直找不到答案,我花了n个小时才发现并解决了,忽然发现这发际线又上移了……当然这两个文件我都准备好了,文件获取方式请见文章下方,下面放上两张这俩文件的截图。

图1. 疫情数据部分内容截图

图2. 中国地图数据部分内容截图

接下来就是绘图了。

fig = px.choropleth_mapbox(df, geojson=gs_data, locations='code', color='confirmed',
        range_color=(0, 30000),
        color_continuous_scale=[             
        [0, 'lightcoral'], #这个必须要写,否则会出错
        [1./3000, 'indianred'],
        [1./300, 'brown'],   
        [1./30, 'firebrick'],     
        [1/3, 'maroon'], 
        [1., 'darkred']],
        zoom=3, center = {"lat": 37.4189, "lon": 116.4219},
        mapbox_style='carto-positron')

fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()

这里面有几点要注意的,一是locations='code'color='confirmed'这俩参数,他们的值是df也就是那个Excel文件中省份代码和确诊人数两列的列名,这个可以自己命名。二是range_color=(0, 30000)这个,为什么取30000这个范围,因为我们的疫情数据中最大的值为29631(这是几天前的数据,最新数据可以自己去网上查找),我们只要设置一个比29631大的数即可,最好是整数,所以设定30000。最后一点是color_continuous_scale=[[0, 'lightcoral'], [1./3000, 'indianred'], [1./300, 'brown'], [1./30, 'firebrick'], [1/3, 'maroon'], 1., 'darkred']]这项,这是设置图片颜色的参数,我们看到这个参数可以按照比例来设定颜色,这也是Plotly强大的地方,其中[0, 'lightcoral']这个必须有,如果没有而直接从[1./3000, 'indianred']开始,那么这个参数无效,图片的颜色将是系统默认的颜色,而这个问题网上也木有答案,我又花了n个小时才解决,这发际线……所有参数设置好后,生成的图片如下,再放一个百度的原图对比一下。

图3. Plotly绘制的疫情地图

图4. 百度网站的疫情地图

Plotly作图确实很方便,而且功能灰常强大,但个人赶脚其也有一个缺点,就是速度略慢,至少比matplotlib慢一些,这可能是d3.js的缘故,毕竟JavaScript的性能很不受一些用户的待见(估计有人要反对),当然实际应用中我们可以根据自己的需要选择适合自己的方法。以后笔者还会写一些其他的数据可视化方法,希望大家继续关注。

赞 赏 作 者



Python中文社区作为一个去中心化的全球技术社区,以成为全球20万Python中文开发者的精神部落为愿景,目前覆盖各大主流媒体和协作平台,与阿里、腾讯、百度、微软、亚马逊、开源中国、CSDN等业界知名公司和技术社区建立了广泛的联系,拥有来自十多个国家和地区数万名登记会员,会员来自以工信部、清华大学、北京大学、北京邮电大学、中国人民银行、中科院、中金、华为、BAT、谷歌、微软等为代表的政府机关、科研单位、金融机构以及海内外知名公司,全平台近20万开发者关注。


扫码关注下方公众号后回复“疫情”即可获取源码数据


▼ 点击成为社区注册会员      喜欢文章,点个在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存