英文:
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()
答案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()
英文:
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()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论