专栏首页Small Code使用 plotly 绘制 Choropleth 地图

使用 plotly 绘制 Choropleth 地图

本文将通过绘制中国省级 Choropleth 地图来解释如何使用 plotly 绘制 Choropleth 地图,主要有两种方法:底层 API plotly.graph_objects.Choroplethmapbox 和高层 API plotly.express.choropleth_mapbox,数据是 COVID-19 在某一天的疫情数据。

什么是 Choropleth 地图

Choropleth map 即分级统计图。在整个制图区域的若干个小的区划单元内(行政区划或者其他区划单位),根据各分区资料的数量(相对)指标进行分级,并用相应色级或不同疏密的晕线,反映各区现象的集中程度或发展水平的分布差别。—— Choropleth_百度百科

简单来说,具体到本文,就是在地图上为每个省上色,根据什么来确定上哪个颜色呢?在本文中就是该省的确诊人数,人数越多,颜色越亮。这样得到的地图就是 Choropleth 地图。

依赖

主要依赖为:

均可以通过 pip 安装,然后导入:

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

数据准备

  • data.csv:某日 COVID-19 全国省级疫情数据,用于地图上色
  • china_province.geojson:中国省级地图 geojson 文件,用于绘制地图轮廓

然后导入数据:

with open("china_province.geojson") as f:
    provinces_map = json.load(f)
df = pd.read_csv('data.csv')

plotly 的绘图逻辑

使用 plotly 绘图,其实就是两点:data 和 layout,即数据和布局。其实所有绘图都是这样,只不过在 plotly 里体现得尤为明显,尤其是底层 API。

data 决定绘图所使用的数据,比如绘制股票折线图用的股票历史数据,绘制疫情地图用的疫情数据。layout 决定图的布局,比如一幅折线图的宽高,一幅地图的风格和中心点。plotly 里一幅图是一个 Figure 对象,这个对象就有 datalayout 两个参数。

方法 1:底层 API plotly.graph_objects.Choroplethmapbox

plotly.graph_objects.Choroplethmapbox(以下简称 go.Choroplethmapbox)是 plotly 的底层 API,其全部参数可参考其官方文档。不过这参数实在是太多了,下面我通过例子来介绍一下几个常用的。

先来看代码:

fig = go.Figure(
    go.Choroplethmapbox(
        geojson=provinces_map,
        featureidkey="properties.NL_NAME_1",
        locations=df.地区,
        z=df.确诊,
        zauto=True,
        colorscale='viridis',
        marker_opacity=0.8,
        marker_line_width=0.8,
        showscale=True,
    )
)
fig.update_layout(
    mapbox_style="carto-darkmatter",
    mapbox_zoom=3,
    mapbox_center={"lat": 37.110573, "lon": 106.493924},
)

先看下 go.Choroplethmapbox 的参数:

  • geojsondict 类型,这个就是刚才说的用于绘制地图轮廓的数据,一般从相应的 geojson 文件中用 json.load 加载进来。
  • featureidkeystr 类型,默认 为 id。函数会使用这个参数和 locations 匹配地图单元(比如省份)的名称,以此决定绘制哪些地图单元的轮廓。通常的形式为 properties.name,其中的 name 需要你自己根据 geojson 文件去指定,比如这里是 properties.NL_NAME_1,意思就是 NL_NAME_1 这一列是省份名称。这个很重要,设置不正确会导致地图轮廓显示不出来,一定要保证和 locations 中的所有名称保持一致
  • locations: 可以是以下类型:list,numpy array,数字、字符串或者 datetime 构成的 Pandas series。指定地图单元名称,决定绘制哪些地图单元的轮廓。同样需要注意featureidkey 保持一致
  • z:可以是以下类型:list,numpy array,数字、字符串或者 datetime 构成的 Pandas series。指定地图单元对应的数值,函数会将此值映射到 colorscale 中的某一颜色,然后将此颜色涂到相应的地图单元内。通常来说是一个 pandas dataframe 中的某一列,即一个 series。需要注意此参数中值的顺序需要和 locations 保持一致,一一对应,如河南在 locations 中的索引是 9,那么河南的确诊人数在 z 中的索引也必须是 9。
  • zautobool 类型,默认为 True。是否让颜色自动适应 z,即自动计算 zminzmax,然后据此来映射 colorscale。
  • colorscale:通常来说是 str 类型,也可以是 list 类型。指定所使用的 colorscale,可使用的值参见此处
  • marker_opacityfloat 类型,颜色透明度。
  • marker_line_widthfloat 类型,地图轮廓宽度。
  • showscalebool 类型。是否显示 colorbar,就是地图旁边的颜色条。

fig.update_layout 的参数同样有很多,主要用来定义布局:

  • mapbox_stylestr 类型,指定 mapbox 风格。可用的 mapbox 风格列表可参见这里。需要注意的是当你使用以下风格之一时,你就需要指定 mapbox_token(关于如何获取 token 详细可参见这里): ["basic", "streets", "outdoors", "light", "dark", "satellite", "satellite-streets"]
  • mapbox_zoomint 类型,指定地图的缩放级别。
  • mapbox_centerdict 类型,key 为 lat(经度)和 lon(纬度),指定初始时地图的中心点。

最终的效果如图:

方法 2:高层 API plotly.express.choropleth_mapbox

plotly.express.choropleth_mapbox(以下简称 px.choropleth_mapbox) 是 plotly 的高层 API,严格来说是 plotly_express 的接口,但是后来这个包被并入 plotly,可以直接用 plotly.express 来引入了,这个包主要就是简化了 plotly 的绘图方法。

详细参数可参考其官方文档。其实大部分参数是异曲同工的,下面我同样使用相同的数据来绘制地图,解释下。

老规矩,先来看代码:

fig = px.choropleth_mapbox(
    data_frame=df,
    geojson=provinces_map,
    color='确诊',
    locations="地区",
    featureidkey="properties.NL_NAME_1",
    mapbox_style="carto-darkmatter",
    color_continuous_scale='viridis',
    center={"lat": 37.110573, "lon": 106.493924},
    zoom=3,
)
  • data_frame:通常来说是 pd.DataFrame 格式。我们需要把绘图用到的数据都放到这个参数里面,后续很多参数都是基于此的,具体来说就是其中的列名。在 plot express 的各个绘图方法中,DataFrame 其实是最为方便的格式,也是官方推荐的格式,官方的大部分示例都是使用的这个格式。
  • geojson:和 go.Choroplethmapbox 的同名参数对应。
  • color:通常为 str 类型,data_frame 的列名。和 go.Choroplethmapbox 中的 z 对应。
  • locations:通常为 str 类型,data_frame 的列名。和 go.Choroplethmapbox 中的同名参数对应。
  • featureidkey:和 go.Choroplethmapbox 的同名参数对应。
  • mapbox_style:和 update_layout 的同名参数对应。
  • color_continuous_scale:和 go.Choroplethmapbox 中的 colorscale 对应。
  • center:和 update_layout 中的 mapbox_center 对应。
  • zoom:和 update_layout 中的 mapbox_zoom 对应。

最终的效果如图:

完整代码

完整代码放在 GitHub 上。

一些没说到的

为了阅读体验,本文没有解释更多的参数,但我相信这已经能让你绘制一幅不错的 choropleth 地图了。有时间我会继续写一写如何在 dash 中融入这些地图,并实时更新。

其实本文所讲的是地图是一种 tile map,和这种地图对应的是一种轮廓地图,没有 mapbox 这种底图,只绘制 geojson 文件中定义的轮廓,如下面这幅图:

plotly 也可以绘制这种地图,只需要去掉本文所讲的函数中 mapbox 即可:go.Choroplethpx.choropleth,感兴趣可以参考这里的示例。

有任何问题欢迎在 GitHub 上提 issue 或者在评论区留言。

Reference

END

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【TensorFlow】TensorFlow 的 Logistic Regression

    前面提到了使用 TensorFlow 进行线性回归以及学习率、迭代次数和初始化方式对准确率的影响,这次来谈一下如何使用 TensorFlow 进行 Logist...

    Alan Lee
  • 【TensorFlow】DNNRegressor 的简单使用

    tf.contrib.learn.DNNRegressor 是 TensoFlow 中实现的一个神经网络回归器。一般神经网络用于分类问题的比较多,但是同样可以用...

    Alan Lee
  • 【Python】numpy 中的 copy 问题详解

    这篇文章本是我在 segmentfault 上的一个回答,但是越来越觉得有必要单独拿出来,毕竟这个问题挺常见的。具体可参看 numpy 官方文档 。 正文 nu...

    Alan Lee
  • 给未来程序员的15个顶级职业建议

    好吧,我觉得10条不够,应该有15条职业建议。不过首先,我想解释一下出色的职业生涯是什么样的。

    哲洛不闹
  • 防止flash被反编译

    通常我们制作的flash,一般都可以通过SWFDecompiler这些反编译工具获取到里面的素材,如果想防止被轻易的破解掉。可以加上url的判断

    meteoric
  • 编程小白 | 每日一练(10)

    这道理放在编程上也一并受用。在编程方面有着天赋异禀的人毕竟是少数,我们大多数人想要从编程小白进阶到高手,需要经历的是日积月累的学习,那么如何学习呢?当然是每天都...

    闫小林
  • Django: "No module named urls" error for /admin/

    用户1258909
  • 鱼眼相机相关概念

    omnidirectional camera 可以在同一时间看到相机四周所有方向的物体 360度 视野

    用户1148525
  • MongoDB快速入门

        从我第一次听到Nosql这个概念到如今已经走过4个年头了,但仍然没有具体的去做过相应的实践。最近获得一段学习休息时间,购买了Nosql技术实践一书,正在...

    用户1216676
  • MySQL学习笔记(二)

    二、SQL基本知识 SQL 是一种典型的非过程化程序设计语言,这种语言的特点是:只指定哪些数据被操纵,至于对这些数据要执行哪些操作,以及这些操作是如何执行的,则...

    mukekeheart

扫码关注云+社区

领取腾讯云代金券