使用Cartopy绘制国家标签。

huangapple go评论73阅读模式
英文:

Plotting country labels with cartopy

问题

I understand that you want assistance with a code snippet related to creating a map overview using Cartopy and labeling countries on the map. To clarify, you'd like guidance on how to resolve issues with country labels, particularly when trying to label Mozambique. Is that correct?

英文:

I am trying to create a map overview using cartopy, but for some reason cannot figure out how to plot the names of the countries shown on the map.

My function looks like this:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

def plot_southwest_indian_ocean():
    # Define the latitude and longitude ranges for the Southwest Indian Ocean basin
    lat_range = [-40, 0]
    lon_range = [-340, -260]

    # Create a figure and axis object with a desired projection
    fig, ax = plt.subplots(figsize=(8, 6), subplot_kw={'projection': ccrs.PlateCarree()})

    # Set the map boundaries
    ax.set_extent(lon_range + lat_range, crs=ccrs.PlateCarree())

    # Add land and ocean features
    ax.add_feature(cfeature.LAND, edgecolor='black')
    ax.add_feature(cfeature.OCEAN)

    # Add country borders
    ax.add_feature(cfeature.BORDERS, linestyle='-', alpha=0.5)

    # Add country labels
    countries = cfeature.NaturalEarthFeature(
        category='cultural',
        name='admin_0_countries',
        scale='50m',
        facecolor='none',
        edgecolor='gray'
    )
    ax.add_feature(countries, linewidth=0.5)

    country_name = 'Mozambique'
    country_boundaries = [country for country in countries.geometries() if country.properties['ADMIN'] == country_name]

    for boundary in country_boundaries:
        centroid = boundary.centroid
        ax.annotate(
            country_name,
            xy=(centroid.x, centroid.y),
            xytext=(5, 5),
            textcoords='offset points',
            ha='left',
            va='bottom',
            fontsize=8,
            color='black',
            bbox=dict(boxstyle='round,pad=0.2', fc='white', ec='gray', lw=0.5)
        )

    # Add gridlines
    gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, color='gray', alpha=0.5, linestyle='--')
    gl.ylabels_right = False
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    gl.xlabel_style = {'size': 12, 'color': 'gray'}
    gl.ylabel_style = {'size': 12, 'color': 'gray'}

    # Add a title to the plot
    ax.set_title("Southwest Indian Ocean Basin")

    # Show the plot
    plt.show()

I was trying to test it out with Mozambique, but continue to run into errors if I try to plot one country label or all of them. Ideally all within this map extent would be plotted. This is the map extent without any attempt at country labels:

def plot_southwest_indian_ocean():
    # Define the latitude and longitude ranges for the Southwest Indian Ocean basin
    lat_range = [-40, 0]
    lon_range = [-340, -260]

    # Create a figure and axis object with a desired projection
    fig, ax = plt.subplots(figsize=(8, 6), subplot_kw={'projection': ccrs.PlateCarree()})

    # Set the map boundaries
    ax.set_extent(lon_range + lat_range, crs=ccrs.PlateCarree())

    # Add land and ocean features
    ax.add_feature(cfeature.LAND, edgecolor='black')
    ax.add_feature(cfeature.OCEAN)

    # Add country borders
    ax.add_feature(cfeature.BORDERS, linestyle='-', alpha=0.5)


    # Add gridlines
    gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, color='gray', alpha=0.5, linestyle='--')
    gl.ylabels_right = False
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    gl.xlabel_style = {'size': 12, 'color': 'gray'}
    gl.ylabel_style = {'size': 12, 'color': 'gray'}

    # Add a title to the plot
    ax.set_title("Southwest Indian Ocean Basin")

    # Show the plot
    plt.show()

使用Cartopy绘制国家标签。

答案1

得分: 1

以下是您要翻译的内容:

"if country.properties['ADMIN'] == country_name"这一行返回错误,因为"country"没有"properties"属性。

从https://stackoverflow.com/questions/60147431/how-to-put-a-label-on-a-country-with-python-cartopy,我成功生成了应该实现您想要的功能的代码:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import cartopy.io.shapereader as shpreader

# 定义西南印度洋盆地的纬度和经度范围
lat_range = [-40, 0]
lon_range = [-340, -260]

# 创建一个带有所需投影的图和坐标轴对象
fig, ax = plt.subplots(figsize=(8, 6), subplot_kw={'projection': ccrs.PlateCarree()})

# 设置地图边界
ax.set_extent(lon_range + lat_range, crs=ccrs.PlateCarree())

# 添加陆地和海洋特征
ax.add_feature(cfeature.LAND, edgecolor='black')
ax.add_feature(cfeature.OCEAN)

# 添加国家边界
ax.add_feature(cfeature.BORDERS, linestyle='-', alpha=0.5)
shpfilename = shpreader.natural_earth(resolution='50m',
                                      category='cultural',
                                      name='admin_0_countries')
reader = shpreader.Reader(shpfilename)
countries = reader.records()
country_names = ['Mozambique', 'Madagascar']
for country in countries:
    ax.add_geometries(country.geometry, ccrs.PlateCarree(), edgecolor='#888888', facecolor='#EFEFDB')
    if country.attributes['NAME'] in country_names:
        x = country.geometry.centroid.x        
        y = country.geometry.centroid.y
        ax.annotate(country.attributes['NAME'], 
                    xy=(x, y), 
                    xytext=(5, 5),
                    textcoords='offset points',
                    ha='left', 
                    va='bottom', 
                    fontsize=8,
                    color='black',
                    bbox=dict(boxstyle='round,pad=0.2', fc='white', ec='gray', lw=0.5))

# 添加网格线
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, color='gray', alpha=0.5, linestyle='--')
gl.ylabels_right = False
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.xlabel_style = {'size': 12, 'color': 'gray'}
gl.ylabel_style = {'size': 12, 'color': 'gray'}

# 添加标题
ax.set_title("西南印度洋盆地")

# 显示图形
plt.show()

使用Cartopy绘制国家标签。

英文:

The line with if country.properties['ADMIN'] == country_name returns an error because country has no attribute properties.

From https://stackoverflow.com/questions/60147431/how-to-put-a-label-on-a-country-with-python-cartopy, I managed to produce this code that should do what you want:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import cartopy.io.shapereader as shpreader
# Define the latitude and longitude ranges for the Southwest Indian Ocean basin
lat_range = [-40, 0]
lon_range = [-340, -260]
# Create a figure and axis object with a desired projection
fig, ax = plt.subplots(figsize=(8, 6), subplot_kw={'projection': ccrs.PlateCarree()})
# Set the map boundaries
ax.set_extent(lon_range + lat_range, crs=ccrs.PlateCarree())
# Add land and ocean features
ax.add_feature(cfeature.LAND, edgecolor='black')
ax.add_feature(cfeature.OCEAN)
# Add country borders
ax.add_feature(cfeature.BORDERS, linestyle='-', alpha=0.5)
shpfilename = shpreader.natural_earth(resolution='50m',
category='cultural',
name='admin_0_countries')
reader = shpreader.Reader(shpfilename)
countries = reader.records()
country_names = ['Mozambique', 'Madagascar']
for country in countries:
ax.add_geometries(country.geometry, ccrs.PlateCarree(), edgecolor='#888888', facecolor='#EFEFDB')
if country.attributes['NAME'] in country_names:
x = country.geometry.centroid.x        
y = country.geometry.centroid.y
ax.annotate(country.attributes['NAME'], 
xy=(x, y), 
xytext=(5, 5),
textcoords='offset points',
ha='left', 
va='bottom', 
fontsize=8,
color='black',
bbox=dict(boxstyle='round,pad=0.2', fc='white', ec='gray', lw=0.5))
# Add gridlines
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, color='gray', alpha=0.5, linestyle='--')
gl.ylabels_right = False
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.xlabel_style = {'size': 12, 'color': 'gray'}
gl.ylabel_style = {'size': 12, 'color': 'gray'}
# Add a title to the plot
ax.set_title("Southwest Indian Ocean Basin")
# Show the plot
plt.show()

使用Cartopy绘制国家标签。

huangapple
  • 本文由 发表于 2023年5月10日 16:10:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76216234.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定