python - 如何使用 Python 的 matplotlib 绘制 map 以便也包括小岛国?

标签 python matplotlib geopandas cartopy

我有一个使用 Python 在非洲 map 上绘制数据的基本设置 matplotlib .不幸的是geopandas自然地球数据库不包括小岛屿国家,这些国家也必须包括在内。
我的基本设置是这样的:

import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
africa = world.query('continent == "Africa"')

africa.plot(column="pop_est")
plt.show()
我得到的数字是这样的:
enter image description here
相反,我想要一个类似这样的图形,其中小岛国由可见的点整齐地呈现:
enter image description here
(图源为:https://en.wikipedia.org/wiki/African_Continental_Free_Trade_Area#/media/File:AfricanContinentalFreeTradeArea.svg)
我有两个问题:1)geopandas自然地球数据不包括岛国,以及 2)我不知道如何将原本不可见的岛国绘制为可见的点。
我在 SO for R 中看到了一些相关的问题,但它特别是我所追求的 Python 解决方案。

最佳答案

这是一个有趣的挑战。以下是具有输出映射的可运行代码,应满足问题中所述的要求。由于我在代码中添加了很多注释,所以我应该在这里写一个简短的介绍。

# Module imports
import matplotlib.pyplot as plt
import matplotlib
import cartopy
from cartopy.io import shapereader
import cartopy.crs as ccrs
import geopandas as gpd
import numpy as np
import pandas as pd

# get natural earth data from http://www.naturalearthdata.com/
# for country borders
use_res = '50m'  # medium resolution of (10m, 50m, 110m)
category = 'cultural'
name = 'admin_0_countries'
shpfilename = shapereader.natural_earth(use_res, category, name)

# read the shapefile using geopandas
df = gpd.read_file(shpfilename)

# select countries in Africa
africa = df[df['CONTINENT'] == "Africa"]

# It is possible to select the small island states by other methods without using their names
# .. but using names is presented here

# Select only countries in a list (small island states)
islnd_cts = ['Cabo Verde', 'Mauritius', 'Comoros', 'São Tomé and Principe', 'Seychelles']
islnds = df[df['NAME'].isin(islnd_cts)]

# collect name and centroid of countries in `islnds` dataframe
names, points, popest, iso_a3 = [], [], [], []
# this part can be improved
# 
for i, col_dict in islnds[['NAME', 'POP_EST', 'ISO_A3', 'geometry']].iterrows():
    #df1.loc[i, 'Result1'] = col_dict['NAME'] + col_dict['POP_EST']
    #print(col_dict['NAME'], col_dict['POP_EST'])
    names.append(col_dict['NAME'])
    points.append(col_dict['geometry'].centroid)
    popest.append(col_dict['POP_EST'])
    iso_a3.append(col_dict['ISO_A3'])

# prep a dict useful to build a dataframe
# population_estimate is intentionally omitted
ilsdict = {'NAME': names, 'ISO_A3': iso_a3, 'CENTROID': points}

# make it a dataframe
df6c = pd.DataFrame(ilsdict)

# create geodataframe of the island states
gdf6c = gpd.GeoDataFrame(df6c, crs={'init': 'epsg:4326'}, geometry='CENTROID')

# can do plot check with: 
#gdf6c.plot()

# Setup canvas for plotting multi-layered data (need cartopy here)
fig = plt.figure(figsize=(10, 10))
# set extent to cover Africa
extent =[-28,60,  -32, 40]  #lonmin, lonmax, latmin, latmax
ax = plt.axes(projection=cartopy.crs.PlateCarree())
ax.set_extent(extent)

# This do in batch, not possible to filter/check individual rows of data
africa.plot(ax=ax, edgecolor="black", facecolor='lightgray', lw=0.25)  #returns axes

# This layer of plot: island states, as colored dots
gdf6c.plot(ax=ax, facecolor='salmon', markersize=90)

# Annotate: iso-a3 abbrev-name of island states
for i, geo in gdf6c.centroid.iteritems():
    #print(str(i), ak['admin'][i], geo.x, geo.y)
    ax.annotate(s=gdf6c['ISO_A3'][i], xy=[geo.x, geo.y], color="blue")

# Draw other map features
ax.coastlines(resolution = use_res, lw=0.4)

ax.gridlines(draw_labels=True)
plt.title("African Island States", pad=20)
plt.show()
africa_island_states

关于python - 如何使用 Python 的 matplotlib 绘制 map 以便也包括小岛国?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65749316/

相关文章:

python - 如何在 CountVectorizer 中对句子应用权重(对每个句子标记进行多次计数)

python - Keras CNN 训练准确率很好但测试准确率很低

python - 稀疏矩阵上的点积

python - 如何将y轴比例因子移动到y轴标签旁边的位置?

python - 从地理数据帧导入图形时图形连接丢失

python - 将几何点从 GeoJSON 转换为纬度和经度

python - Geopandas read_file

python - 如何在 tkinter GUI 中删除外部 Matplot 框架

python - 在 AudioLazy 库中从 python 中的 zfilter 对象中提取数值

python - 按下绘图按钮后 cx_Freeze 转换的 GUI 应用程序 (tkinter) 崩溃