根据给定值的颜色 Cartopy 地图国家

Color Cartopy map countries according to given values

我正在和那些非常了解 Cartopy 的人交谈...因为我使用 Cartopy 制作地图,但我不太了解它是如何工作的。

首先,我绘制了一张欧洲地图(广义上,从大西洋到乌拉尔),如附图所示。

然后,我有一个单独的文件,比如dft0,指示每个欧洲国家某种现象的出现时间(Time0),以相对于某个事件的天数计算任意日期 D 并从 minmax 排序;作为第一行的示例:

    Country     Time0
20  Italy    -16.063702
10  Denmark   -2.798684
39  Sweden    -2.711578
15  Germany    3.259436

所以,所谓的现象首先出现在意大利,16.1 days之前我的约会对象D,然后是丹麦,2.8 days 之前 D,然后在瑞典,2.7 days 之前 D,然后在德国,3.3 days after D等,去白俄罗斯,在那里出现52.1 days after D . 52.1.

文件dft0中有44个这样的值(从负到正),从-16.152.1

我的问题是:知道我做了一个合适的程序来绘制欧洲地图,我应该在程序中添加什么样的代码才能给地图上色呢?根据变量 Time0 的国家,例如从 red(意大利)到 violet(白俄罗斯),遵循可见光谱的颜色,其中 red = 800 nmviolet = 400 nm?

更准确地说,如果Time0 = x,我想用(大约)y = -5.9 x + 705.6 nm对应的颜色给相应的国家上色。

为了更容易理解,我插入了一个显示如何计算颜色的图表 y(在 nm 中);这是一个基本的线性插值。

真不知道能不能搞定,好像很复杂(可能是不必要的复杂)。所以,我对任何其他想法持开放态度。目的是区分我在这个文件 dft0 中的 44 个国家,使用有序的调色板,显示有规律的减少(或有规律的增长......)

感谢您的关心。

添加:我使用的Cartopy程序:

import matplotlib.pyplot as plt
import cartopy
import cartopy.io.shapereader as shpreader

plt.figure(figsize=(4, 4))

central_lon, central_lat = 0, 45
extent = [-10, 45, 35, 70]

ax = plt.axes(projection=cartopy.crs.Orthographic(central_lon, central_lat))
ax.set_extent(extent)
ax.gridlines()
ax.add_feature(cartopy.feature.BORDERS, linestyle=':', alpha=1)
ax.add_feature(cartopy.feature.OCEAN,facecolor=("lightblue"))
ax.add_feature(cartopy.feature.LAND)
ax.coastlines(resolution='10m')

plt.show()

此解决方案基于您发布的代码示例并大量借鉴了 this answer

import matplotlib.pyplot as plt
import matplotlib
import cartopy
from cartopy.io import shapereader
import cartopy.crs as ccrs
import geopandas
import numpy as np

# get natural earth data (http://www.naturalearthdata.com/)

# get country borders
resolution = '10m'
category = 'cultural'
name = 'admin_0_countries'
shpfilename = shapereader.natural_earth(resolution, category, name)

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


# Set up the canvas
fig = plt.figure(figsize=(8, 8))
central_lon, central_lat = 0, 45
extent = [-10, 45, 35, 70]
ax = plt.axes(projection=cartopy.crs.Orthographic(central_lon, central_lat))
ax.set_extent(extent)
ax.gridlines()

# Add natural earth features and borders
ax.add_feature(cartopy.feature.BORDERS, linestyle=':', alpha=1)
ax.add_feature(cartopy.feature.OCEAN, facecolor=("lightblue"))
ax.add_feature(cartopy.feature.LAND)
ax.coastlines(resolution='10m')

# Insert your lists of countries and lag times here
countries = ['Germany', 'France', 'Italy', 'Spain', 'Ukraine']
lags = [-20,-5, 15, 0, 2]

# Normalise the lag times to between 0 and 1 to extract the colour
lags_norm = (lags-np.nanmin(lags))/(np.nanmax(lags) - np.nanmin(lags))

# Choose your colourmap here
cmap = matplotlib.cm.get_cmap('viridis')


for country, lag_norm in zip(countries, lags_norm):
    # read the borders of the country in this loop
    poly = df.loc[df['ADMIN'] == country]['geometry'].values[0]
    # get the color for this country
    rgba = cmap(lag_norm)
    # plot the country on a map
    ax.add_geometries(poly, crs=ccrs.PlateCarree(), facecolor=rgba, edgecolor='none', zorder=1)

# Add a scatter plot of the original data so the colorbar has the correct numbers. Hacky but it works
dummy_scat = ax.scatter(lags, lags, c=lags, cmap=cmap, zorder=0)
fig.colorbar(mappable=dummy_scat, label='Time lag of phenomenon', orientation='horizontal', shrink=0.8)

结果:

Map of Europe with France, Germany and Italy coloured

至于可见光谱的着色,我强烈建议您不要这样做,除非您有充分的理由这样做。相反,我使用了 matplotlib 的 inbuilt perceptually uniform colourmaps. There are many other colormaps you can use if viridis doesn't suit your needs. These perceptually uniform colormaps are preferable as they do not distort your data. For more information check out this page or this more in depth discussion 之一,或者搜索有关感知均匀颜色图的信息。您作品的观众(尤其是那些有色觉障碍的观众)会感谢您。