• 【matplotlib基础】--结合地图


    如果分析的数据与地域相关,那么,把分析结果结合地图一起展示的话,会让可视化的效果得到极大的提升。

    比如,分析各省GDP数据,人口数据,用柱状图,饼图之类的虽然都可以展示分析结果,
    不过,如果能在全国的地图上展示各省的分析结果的话,会让人留下更加深刻的印象。

    将数据的分析结果展示在地图上,难点在于:

    1. 如何绘制地图,地图是展示数据的基础,如何绘制出需要的地图区域是第一步
    2. 数据和地图关联,数据最终要显示在地图上,数据如何与地理坐标关联也是重要的一步
    3. 地图上展示数据,也就是要在地图上绘制不同的颜色或者几何形状来表达不同的数据

    解决了上面3个难题,就能够结合地图做一些基本的数据展示了。
    本篇通过一个基于南京各个区地理信息的分析示例,来演示如何一步步通过地图来展示分析结果。

    1. 绘制地图

    第一步是绘制地图,其实地图就是一块块不规则的多边形拼接起来的。
    在本篇的示例中,各个多边形就是南京的各个区

    绘制多边形不难,难的是如何得到各个多边形的顶点坐标。
    好在现在有很多的开放地理信息平台,可以让我们获取到想要的地理信息。

    1.1. 获取地理信息

    比如,通过阿里的DataV数据可视化平台,可以获取南京各个区的地理范围信息。
    image.png
    在这个平台上,左边选择区域,右边会生成对应范围的地理信息的数据。
    地理信息数据是json格式。

    1.2. 展示地理信息

    为了读取地理信息数据并展示,需要用到一个 GeoPandas 的库。
    pip 安装很简单:

    $ pip install geopandas
    

    geopandas可以直接读取DataV数据可视化平台生成的JSON数据并展示。

    import geopandas as gpd
    
    df_geo = gpd.read_file(
        "https://geo.datav.aliyun.com/areas_v3/bound/320100_full.json"
    )
    df_geo
    
    

    image.png
    json文件的HTTP地址DataV数据可视化平台就是在上生成的。
    这个文件中的关键字段就是 geometry,其中的内容就是各个区的多边形形状的各个顶点的经纬度坐标。

    展示数据:

    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots()
    fig.set_size_inches(8, 8)
    
    # df_geo就是上面通过geopandas读取的数据
    df_geo.plot(
        ax=ax,
        column="name",
        cmap="plasma",
        edgecolor="k",
        legend=True,
        legend_kwds={"loc": "lower left"}
    )
    plt.show()
    

    image.png
    其中主要参数的含义:

    1. axmatplotlib生成的子图,这里就是数据要绘制的位置
    2. column:作为不同区域的名称,这里就是南京各个区的名称
    3. cmap:一组颜色,分别对应不同的区
    4. edgecolor:每个多边形边缘的颜色,这里设置的是黑色
    5. legend:是否显示图例
    6. legend_kwds:设置图例的配置信息,这里只设置了图例的位置

    2. 地图和数据关联

    首先生成一些测试数据:

    # 删除 df_geo 中一些不必要的列
    df_geo = df_geo.drop(columns=["childrenNum", "level", "parent", "subFeatureIndex"])
    
    # 南京各个区的名称
    area_names = df_geo.loc[:, "name"]
    
    # df_val为测试数据,其中name列是各个区的名称
    # value 列是一些随机数,模拟各个区的人口,GDP等数据
    df_val = pd.DataFrame({
        "name": area_names.tolist(),
        "value": np.random.randint(10, 10000, len(area_names))
    })
    
    

    测试数据 df_val 模拟其他途径得到的业务数据,
    下面要将 df_val 中的指展示到地图上,就要先把 df_valdf_geo 结合起来。

    # 以 name 列作为结合两个数据集的依据
    df = pd.merge(df_geo, df_val, on="name", how="left")
    df
    

    image.png
    这样,我们就得到了同时包含地理信息(geometry)业务数据(value)的数据集了。

    3. 地图上展示数据

    接下来就是展示数据了,下面演示两种在地图上展示数据的方式。

    3.1. 热力图方式

    根据 value 值的不同,用渐变色来显示不同区的颜色。

    fig, ax = plt.subplots()
    fig.set_size_inches(8, 8)
    ax.axis("off")
    
    df.plot(
        ax=ax,
        column="value",
        cmap="plasma",
        edgecolor="k",
        legend=True,
        legend_kwds={'label': "value", 'shrink':0.5},
    )
    
    for index in df.index:
        x = df.iloc[index].geometry.centroid.x
        y = df.iloc[index].geometry.centroid.y
        name = df.iloc[index]["name"]
        if name in ["建邺区", "鼓楼区", "玄武区", "秦淮区"]:
            ax.text(x, y, name, ha="center", va="center", fontsize=8)
        else:
            ax.text(x, y, name, ha="center", va="center")
    
    plt.show()
    

    image.png
    其中,"建邺区", "鼓楼区", "玄武区", "秦淮区" 四个区的面积比较小,
    所以字体稍微调小了一些。

    3.2. 分类展示

    value值分为3类,每类用不同的形式来表示。

    • value < 3000
    • 3000 <= value < 5000
    • value >= 5000
    import matplotlib.patches as mpatches
    
    fig, ax = plt.subplots()
    fig.set_size_inches(5, 10)
    ax.axis("off")
    legend_list = []
    
    df[df["value"] < 3000].plot(
        ax=ax,
        color="lightblue",
        edgecolor="k",
        hatch="\\\\",
        legend=False,
    )
    legend_list.append(
        mpatches.Patch(
            facecolor="lightblue",
            edgecolor="black", hatch="\\\\", label="value<3000"
        )
    )
    
    
    df[(df["value"] >= 3000) & (df["value"] < 5000)].plot(
        ax=ax,
        color="lightgreen",
        edgecolor="k",
        hatch="o",
        legend=False,
    )
    legend_list.append(
        mpatches.Patch(
            facecolor="lightgreen",
            edgecolor="black", hatch="o", label="3000<=value<5000")
    )
    
    df[df["value"] >= 5000].plot(
        ax=ax,
        color="r",
        edgecolor="k",
        hatch="*",
        legend=False,
    )
    legend_list.append(mpatches.Patch(
        facecolor="r",
        edgecolor="black", hatch="*", label="value>=5000"))
    
    ax.legend(handles = legend_list, 
              loc=(1, 0.5), 
              title="value 等级", 
              fontsize=12)
    
    plt.show()
    

    image.png

    4. 总结

    结合地理信息展示数据,让数据更加的生动,特别是很多数据分析场景本身就和地理信息密切相关。
    除了基于地域的各种经济或者人口等等的相关数据,
    还有各类气象数据,如能和地理信息结合展示的话,会让人对整体情况一目了然。

    文中用到的主要资源:


  • 相关阅读:
    「GPT虚拟直播」实战篇|GPT接入虚拟人实现直播间弹幕回复
    高级深入--day35
    WCF Demo
    Java项目:SSM律师事务所律师管理系统
    【网页设计】期末大作业:化妆品主题——绿色大气的html5响应式化妆品护肤品肌肤网页设计(11页)
    神经网络(十五)在VS Code下搭建PyTorch环境
    【数值分析】0 - 数值分析绪论
    .Net RabbitMQ(消息队列)
    【CSDN 每日一练 ★☆☆】【蛮力/双指针】删除排序链表中的重复元素
    Cookie和Session
  • 原文地址:https://www.cnblogs.com/wang_yb/p/17727254.html