【问题标题】:How to plot a scatter plot over a map separated by divisions?如何在由分区分隔的地图上绘制散点图?
【发布时间】:2021-07-06 01:34:23
【问题描述】:

我想在由分区分隔的地图上绘制散点图。到目前为止,我已经尝试了以下方法。

import os
import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd
import numpy as np

fPath = 'shape/bgd_adm_bbs_20201113_SHP/bgd_admbnda_adm2_bbs_20201113.shp'
bgd = gpd.read_file(fPath)
ax = bgd.plot(figsize=(15,15),column='ADM1_EN', legend=True)

bgd_admbnda_adm2_bbs_20201113.shp 已在 github 中找到。它产生这个figure

Here, there are 8 divisions 'Barishal', 'Chattogram', 'Dhaka', 'Khulna', 'Rajshahi', 'Rangpur', 'Sylhet', 'Mymensingh'. 对于每个分区,都有一些数值(不是纬度,经度值)。例如。 达卡师 [73.13 77.64 74.32 82.48 84.21 88.23 89.90]。为方便起见,我将文件附在github 中。 现在,我根据值范围拆分值。例如。 i) 70-80:[73.13 77.64 74.32],ii) 80-90:[82.48 84.21 88.23 89.90]。现在,我想用两种颜色(例如this image)在达卡分区的任何地方绘制两类值的散点图。我已附上另一张预期输出图像供您参考

提前致谢。

【问题讨论】:

    标签: pandas dataframe matplotlib geopandas


    【解决方案1】:

    这就像在同一轴上绘制数据一样简单

    • 拥有医疗机构的数据,然后获取这些机构的 GIS 数据
    • 获取地图 GEOJSON 并在轴上绘图
    • 在同一轴上散布数据,使用医疗机构类型作为颜色
    import requests, io
    import pandas as pd
    import geopandas as gpd
    import matplotlib.pyplot as plt
    
    # get some data of healthcare facilities
    searchendpoint = "https://directory.spineservices.nhs.uk/ORD/2-0-0/organisations"
    # get all healthcare facilities in Herefordshire
    dfhc = pd.concat([pd.json_normalize(requests
                                 .get(searchendpoint, params={"PostCode":f"HR{i}","Status":"Active"})
                                 .json()["Organisations"]) 
               for i in range(1,10)]).reset_index(drop=True)
    
    # get geo data for postcodes
    dfgeo = (pd.json_normalize(requests.post("http://api.postcodes.io/postcodes", 
                   json={"postcodes":dfhc.PostCode.unique().tolist()[0:100]}).json()["result"])
             .rename(columns={"result.postcode":"PostCode","result.longitude":"lng","result.latitude":"lat"})
             .loc[:,["PostCode","lat","lng"]]
            )
    
    dfdata = dfhc.merge(dfgeo, on="PostCode", how="inner")
    # going to use as color, so make if categorical so can get codes
    dfdata["PrimaryRoleId"] = pd.Categorical(dfdata["PrimaryRoleId"])
    
    fig, ax = plt.subplots(figsize=[14,6])
    
    # get map of regions
    df = gpd.read_file(io.StringIO(requests.get("https://martinjc.github.io/UK-GeoJSON/json/eng/msoa_by_lad/topo_E06000019.json").text))
    df.plot(ax=ax)
    # scatter data on top of region map
    ax.scatter(x=dfdata["lng"],y=dfdata["lat"], s=50, c=dfdata["PrimaryRoleId"].cat.codes)
    

    使用相同的数据集

    import numpy as np
    import geopandas as gpd
    import matplotlib.pyplot as plt
    import matplotlib
    
    df = gpd.read_file("bgd_admbnda_adm2_bbs_20201113.shp")
    fig, ax = plt.subplots(figsize=[8,8])
    df.plot(ax=ax, alpha=0.5, edgecolor='k')
    # some data that can be plotted on centroid
    df["val"] = np.random.randint(1,100,len(df))
    
    # use a discrete 
    cmap = plt.cm.get_cmap('jet', 5)
    # scatter data based on co-ords of centroid
    sc = ax.scatter(x=df.centroid.x, y=df.centroid.y, s=50, c=df["val"], cmap=cmap)
    plt.colorbar(sc)
    
    

    【讨论】:

    • 感谢您的回复。我想根据纬度、经度值的数值绘制散点图。你能帮我按预期进行绘图吗?如果您使用我的数据绘制它,对我将非常有帮助。
    • ax.scatter(x=dfdata["lng"],y=dfdata["lat"], 是基于经纬度的散射
    • 我已更新为使用您记下的数据集。同样的,分散在 geopandas 创建的基础之上
    • 非常感谢。很棒的答案。
    猜你喜欢
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多