根据给定值的颜色 Cartopy 地图国家
Color Cartopy map countries according to given values
我正在和那些非常了解 Cartopy 的人交谈...因为我使用 Cartopy 制作地图,但我不太了解它是如何工作的。
首先,我绘制了一张欧洲地图(广义上,从大西洋到乌拉尔),如附图所示。
然后,我有一个单独的文件,比如dft0
,指示每个欧洲国家某种现象的出现时间(Time0
),以相对于某个事件的天数计算任意日期 D
并从 min
到 max
排序;作为第一行的示例:
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.1
到52.1
。
我的问题是:知道我做了一个合适的程序来绘制欧洲地图,我应该在程序中添加什么样的代码才能给地图上色呢?根据变量 Time0
的国家,例如从 red
(意大利)到 violet
(白俄罗斯),遵循可见光谱的颜色,其中 red = 800 nm
和violet = 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 之一,或者搜索有关感知均匀颜色图的信息。您作品的观众(尤其是那些有色觉障碍的观众)会感谢您。
我正在和那些非常了解 Cartopy 的人交谈...因为我使用 Cartopy 制作地图,但我不太了解它是如何工作的。
首先,我绘制了一张欧洲地图(广义上,从大西洋到乌拉尔),如附图所示。
然后,我有一个单独的文件,比如dft0
,指示每个欧洲国家某种现象的出现时间(Time0
),以相对于某个事件的天数计算任意日期 D
并从 min
到 max
排序;作为第一行的示例:
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.1
到52.1
。
我的问题是:知道我做了一个合适的程序来绘制欧洲地图,我应该在程序中添加什么样的代码才能给地图上色呢?根据变量 Time0
的国家,例如从 red
(意大利)到 violet
(白俄罗斯),遵循可见光谱的颜色,其中 red = 800 nm
和violet = 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 之一,或者搜索有关感知均匀颜色图的信息。您作品的观众(尤其是那些有色觉障碍的观众)会感谢您。